Codex CLI
Codex CLI talks to custom providers through the OpenAI Responses shape. MUSCLE Flex by Adhibita serves that shape at /v1/responses. Codex keeps running its sandbox, commands and approvals locally; Flex routes the model requests.
Before you start
You need:
- an accepted MUSCLE Flex invitation and a funded service balance;
- a Flex API key, created on the API keys page of the portal;
- the Flex base URL from your invitation. This page writes it as
<FLEX_BASE_URL>: the scheme and host only, without a trailing/v1.
The key check below reads both values from your shell:
bash
export FLEX_BASE_URL="<FLEX_BASE_URL>"
export MUSCLE_FLEX_API_KEY="<FLEX_API_KEY>"Configure muscle/auto as the model id; auto is accepted as a short form of it. Flex chooses the route for each request, so the model field does not select a model. The model names that compatible clients send on their own are routed the same way. See The model id.
Check that Codex is installed with codex --version.
Configure
Codex reads the key from the environment variable named in env_key. Export MUSCLE_FLEX_API_KEY, as shown under Before you start, in the shell that launches Codex.
Merge these settings into ~/.codex/config.toml:
toml
model = "muscle/auto"
model_provider = "muscle-flex"
web_search = "disabled"
[model_providers.muscle-flex]
name = "MUSCLE Flex"
base_url = "<FLEX_BASE_URL>/v1"
env_key = "MUSCLE_FLEX_API_KEY"
wire_api = "responses"- The three top-level keys must sit above the first
[table]in the file. Below a table header, TOML would read them as part of that table. base_urlends in/v1. Codex appends/responsesto it, and Flex serves Responses only under/v1.wire_api = "responses"is required. Current Codex releases speak only the Responses shape to custom providers.web_search = "disabled"turns off Codex's hosted web search, which Flex does not offer. Left on, requests fail with400 unsupported_field.
Keep your current default
To leave your existing default provider alone, put the top-level keys in a profile instead:
toml
[profiles.muscle-flex]
model = "muscle/auto"
model_provider = "muscle-flex"
web_search = "disabled"Then start Codex with codex --profile muscle-flex.
What Codex features map to
- Function tools, and tool results replayed with the full conversation, go through Flex.
- Stored responses, background responses and response chaining by id are not offered in the beta. Codex's default stateless requests do not need them.
Verify
1. Check the key
This read-only call confirms the base URL and the key before you change the agent:
bash
curl -i "$FLEX_BASE_URL/v1/account" \
-H "Authorization: Bearer $MUSCLE_FLEX_API_KEY"A 200 response returns your account summary, including available credits. A 401 means the key is missing, mistyped or revoked.
Every Flex response carries an X-Request-Id header. Keep it when you contact support: it is how a single request is found.
2. Run one tool call
From a small project:
bash
codex exec "List the files in this folder, then read the README and summarize it in one sentence."Codex should run a command to read the files and print a one-sentence summary.
Troubleshooting
401or a missing-key error.env_keymust name the variable you exported, in the same shell that starts Codex.404.base_urlmust end in/v1.400 unsupported_fieldthat mentions web search. Setweb_search = "disabled"and start a new session.- A warning that model metadata is unavailable. Codex's model-list request expects Codex-specific fields. Codex falls back to its built-in metadata and can continue.
Responses you may see
| Status | Meaning | What to do |
|---|---|---|
401 | The key is missing, mistyped or revoked. | Check where the agent reads the key from. Create a new key in the portal if needed. |
402 | Your balance or spend cap does not cover the request. | Add credits, then retry. |
403 | The account is suspended, or the request is not allowed. | Contact support with the X-Request-Id. |
404 model_not_found | The agent sent a model id that Flex does not accept. | Set the agent's model to muscle/auto. Retrying unchanged fails again. |
429 | A rate limit was reached. | Wait for the number of seconds in Retry-After (a few seconds when it is absent), then retry. |
400 unsupported_field | The agent sent a field or tool that Flex does not offer yet. | Find the field in the compatibility matrix and turn that option off. |
400 unsupported_content | The conversation carries an image or audio part, which Flex does not support yet. | Start a new conversation without the image, and turn off the agent's image input. |
502, 503 or 504 | No eligible route could serve the request at that moment, or it timed out. | Retry later. If it persists, contact support with the X-Request-Id. |
503 feature_unavailable | No route offers what the request needs, or the conversation is too long for every route. | Start a new conversation or lower the agent's output limit. Retrying unchanged fails again. |
The API reference describes each error code and what to do about it.
Agents rarely show response headers. When a request fails inside an agent, note the time, the agent version and the error text for support.