Inference APIs
Reference/Errors/Codex CLI

Codex CLI: MCP tools return "unsupported call" or are never used with a custom model provider

You point Codex at DeepSeek, GLM, Qwen or another open model through a custom provider. The shell tool works, the MCP servers show as connected in codex mcp list, and yet the model never uses them, or every MCP call comes back as unsupported call. Nothing is wrong with your MCP server. The tools are lost between Codex and the model.

Last verified September 17, 2026 against openai/codex issue #26234, Community proxy workaround · 6 min read

ToolOpenAI Codex CLI and Codex Desktop, with wire_api = "responses" and a provider other than OpenAI or Azure
SymptomMCP tool calls fail with unsupported call, or the model never calls an MCP tool and works around it with shell commands
Not affectedBuilt-in tools (shell, apply_patch) and MCP resources. The same MCP servers work on OpenAI models
CauseCodex sends each MCP server as one {"type":"namespace"} tool. That wrapper is an OpenAI extension; other backends drop it or pass it through as a tool that cannot be called
When it happensAny MCP server, stdio or HTTP, as soon as the model provider is not OpenAI or Azure
Can you wait it out?No. It fails the same way on every request until the request format or the provider changes
Short answer
  • Cause: Codex groups each MCP server's tools in a namespace wrapper that only OpenAI's and Azure's backends expand.
  • Fixes: run a patched Codex, run a local proxy that flattens the request and restores the namespace on the way back, or use a provider that does this on its side.
  • Codex's own sub-agent tools are wrapped the same way, so they are lost too.

What happens on the wire

We captured the requests Codex 0.154.0 sends. Built-in tools are ordinary function tools. Each MCP server, and Codex's own sub-agent tool set, arrives as a single tool of type namespace with the real tools nested inside:

What Codex sends for an MCP server (shortened)
{
  "tools": [
    { "type": "function", "name": "exec_command", "parameters": { "...": "..." } },
    {
      "type": "namespace",
      "name": "mcp__orders",
      "tools": [
        { "type": "function", "name": "lookup_order", "parameters": { "...": "..." } },
        { "type": "function", "name": "add_note", "parameters": { "...": "..." } }
      ]
    }
  ]
}

The Responses API specification has no namespace tool type. A backend that follows the specification does one of three things: rejects the request, drops the entry, or hands the model one uncallable tool named mcp__orders. In the first two cases the model never learns the tools exist. In the third it guesses a flat name such as mcp__orders__lookup_order, and Codex's router answers unsupported call, because it routes MCP calls by a separate namespace field:

What Codex needs back to run the tool
{
  "type": "function_call",
  "namespace": "mcp__orders",
  "name": "lookup_order",
  "call_id": "call_abc",
  "arguments": "{\"order_id\":\"A-1042\"}"
}

How to confirm this is your problem

  • The same MCP server works when you switch Codex back to an OpenAI model.
  • list_mcp_resources and read_mcp_resource still work. They are plain function tools, so they survive.
  • The model reaches for the shell to do what the MCP tool would have done. In our first capture the model found the MCP server's script on disk and piped JSON into it by hand. The answer was right and the MCP server logged zero calls.

Fix 1: a patched Codex

The issue's author maintains a branch that adds a namespace_tools provider setting and flattens the tools when it is off. It works, and it means building Codex from source and rebasing on every release. As of September 17, 2026, the fix is not in a Codex release.

Fix 2: a local proxy

A commenter published a small Python proxy that sits between Codex and your provider. It rewrites each namespace into flat functions named namespace__tool, rewrites the calls Codex replays in the conversation history the same way, and splits the name back into namespace and name in the response. It is linked at the top of this page. It buffers the whole response before passing it on, so you lose streaming, and it is one more process to keep running.

Fix 3: a provider that does it on its side

The translation can live in the provider's Responses endpoint, which is where we put it. Nothing changes in your Codex config beyond the provider block:

~/.codex/config.toml
model = "zai-org/GLM-5.3"
model_provider = "inferenceapis"

[model_providers.inferenceapis]
name = "Inference APIs"
base_url = "https://api.inferenceapis.com/v1"
env_key = "INFERENCE_API_KEY"
wire_api = "responses"

# your MCP servers stay exactly as they are
[mcp_servers.orders]
command = "python3"
args = ["/path/to/your_mcp_server.py"]

What the endpoint does with a Codex request:

  • Expands every namespace into flat function tools. Names longer than the 64-character limit are shortened and mapped back.
  • Rewrites namespaced calls in the replayed history, so a multi-step session stays consistent.
  • Returns each call with namespace and name restored, in streamed events as well as in the final response.
  • Accepts a call the model made by the bare tool name when only one namespace has a tool of that name.
  • Reports what it did in a response header:
Confirm the server saw and flattened your MCP tools
curl -s -D - -o /dev/null https://api.inferenceapis.com/v1/responses \
  -H "Authorization: Bearer $INFERENCE_API_KEY" -H "Content-Type: application/json" \
  -d '{"model":"deepseek-ai/DeepSeek-V4-Flash","input":"hi",
       "tools":[{"type":"namespace","name":"mcp__demo","tools":[
         {"type":"function","name":"ping","parameters":{"type":"object","properties":{}}}]}]}' | grep -i x-namespace
# X-Namespace-Tools: 1 flattened

What we tested

ModelMCP toolsSub-agentsSub-agents, Multi-Agent V2Note
deepseek-ai/DeepSeek-V4-FlashPassPassPass
deepseek-ai/DeepSeek-V4.1-FlashPassPassPass
deepseek-ai/DeepSeek-V4-ProPassPassPass
zai-org/GLM-5.3PassPassPass
zai-org/GLM-5.3-FlashPassPassPass
MiniMaxAI/MiniMax-M3PassPassPass
moonshotai/Kimi-K2.7-CodePassPassPassIn one V1 run the parent delegated and also computed the answer itself.
openai/gpt-oss-120bPassPassUnreliableV2: passed 1 of 3 runs. GPT-OSS writes tool names in its own style (collaboration.spawn_agent) and sometimes calls sub-agent tools from inside the sub-agent, where they are not offered; the endpoint normalises the names, the second problem is the model.
Qwen/Qwen3-VL-235B-A22B-InstructPassPassPass
meta-llama/Llama-3.3-70B-Instruct-TurboFailNot runNot runCalled the MCP tool, then announced the second step without doing it. Not suited to multi-step agent work.

Run with codex-cli 0.154.0 on September 17, 2026. MCP test: a local MCP server holds order data the model cannot know; pass means the server logged both tool calls and the final answer contained the release code. Sub-agent test: the parent must delegate a SHA-256 of a random string; pass means the parent ran no shell command itself, a sub-agent was spawned, and the correct digest came back.

Llama 3.3 70B is listed for completeness. Its MCP call went through, and then it announced the second step without doing it. That is the model, not the wire format; use a larger model for agent work.

Frequently asked questions

Does this affect HTTP MCP servers with OAuth, such as Figma?

Yes. The wrapper is applied to every MCP server regardless of transport. Because the fix is in how tools are presented to the model, it works for them as well; Codex still makes the MCP connection itself, with your credentials, on your machine.

Does the provider see my MCP server or its data?

The provider sees the tool definitions and whatever tool results Codex puts in the conversation, as any model provider does. It never connects to your MCP server. Here, none of it is stored after the response is returned; see the trust page.

Will this break when Codex ships its own fix?

No. If Codex starts sending flat function tools to non-OpenAI providers, there is nothing to expand and the request passes through as it is.

Is the OpenAI web search tool covered?

No. That tool runs on OpenAI's servers and is dropped here, with an X-Tools-Dropped header saying so. Use a search MCP server instead; that works.

Where Inference APIs fits

Fix 3 above is what we built: the Responses endpoint here expands Codex's namespace tools and puts the namespace back on every call, so MCP servers and sub-agents work on open models with no proxy and no patched Codex. Billing is per token from a prepaid balance.

Something changed or wrong? Tell us and we will re-verify the entry.