Flatten MCP namespace tools for non-OpenAI Responses API providers (Ollama, LM Studio, OpenRouter)
When Codex runs against a non-OpenAI Responses API endpoint such as a local server (Ollama, LM Studio), a gateway (OpenRouter), or AWS Bedrock Mantle, tools provided by MCP servers are never callable by the model. Codex serializes each MCP server's tools inside a proprietary {"type": "namespace", "name": "mcp__<server>", "tools": [...]} wrapper, which is not part of the standard OpenAI Responses API. OpenAI and Azure expand the wrapper and reach the nested tools, but other Responses API backends pass it through unchanged or reject any tool whose type is not function, so the model only ever sees a single non-callable mcp__<server> tool and the MCP tools are unusable.
I have a fix implemented and tested on this branch: https://github.com/LucaCappelletti94/codex/tree/flatten-mcp-tools-for-non-namespace-providers
The fix gives providers a namespace_tools capability. An explicit namespace_tools in [model_providers.<id>] config wins, otherwise it defaults to requires_openai_auth, so OpenAI and Azure keep namespaces while other Responses API providers get flattened tools. When the capability is off, each namespace is flattened into plain function tools named mcp__<server>__<tool> instead of being dropped, and the tool registry resolves a flat call name back to its namespaced runtime so the call dispatches correctly. The resolution side also covers tool names that a proxy flattens on its own. Bedrock keeps namespaces on by default but can opt out for Mantle with namespace_tools = false.
Unit tests cover the capability resolution (auto and explicit override), namespace flattening into canonical function specs rather than dropping them, and flat-name resolution to the namespaced runtime. I also verified the change end to end against Ollama with both gpt-oss:20b and gpt-oss:120b plus a real MCP server: the request now carries the MCP tool as a flat function named mcp__<server>__<tool> with no namespace wrapper, the model calls it, and the tool executes.
Related to #23186, #19871, #20652, and #25034 (Mantle can opt out with namespace_tools = false).
34 Comments
+1 for this PR!
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
No, that is not a related solution (and it does not work as commented by some other person). Also, this is primarily related to open models. My solution works with any open model with tooling supporting the Responses API.
+1 for this PR
+1 for this PR
+1 for this PR
This seems worth framing as more than a Bedrock-specific fix. The pattern I would want maintainers to preserve is: provider capability should decide the wire shape, while Codex's internal registry should keep a stable canonical tool identity.
A few acceptance checks that would make this safer:
functiontools unless they explicitly opt into namespace support.mcp__<server>__<tool>and still dispatch back to the original server/tool pair.That last point matters because #25034 shows one provider-specific failure mode, while this issue covers the broader compatibility problem for OpenRouter/Ollama/LM Studio-style Responses API backends. A provider-level
namespace_toolscapability plus registry-level flat-name resolution seems like the right boundary if the team wants to support those without making the OpenAI path regress.+1
+1 - this is happening with my vLLM-hosted Qwen 3.6, spent yesterday trying to diagnose what was happening trying to use an MCP tool and this matches it exactly.
@madarkadonk feel free to use my fork in the meantime and do let me know whether any issue come out of it. So far it seems to work on my end.
@madarkadonk also please promote this issue / PR! We feel like this really would improve codex
+1
+1
Thanks Luca, yes I've been using your branch for a couple days now and it definitely solves the direct problem. It seems like there are more secondary features that break. Example being, when codex prompts to allow something, if you select 'always allow', it'll add that to my config file - but then next time I launch codex it'll be unable to parse that entry. I didn't dig very deep into why, but probably related to the name rewriting. It could definitely be unrelated though, since this is my first attempt to use this specific MCP server.
+1 for this PR
Yes there are many more issues on using open models with codex. In my fork I have a branch called "open codex" where I am gradually merging my fixes, which I am keeping separated in different branches in the hope that the openAI people decide that they actually want to support open models. I think that it is a very big stretch for them to currently claim they support open models.
Hi Luca,
Thanks for reporting this and for sharing a proposed fix.
I’m working on a fix for this issue and have attached a small manual repro script for reference.
repro_codex_issue_26234.py
I had the same issue +1 for this PR
+1
+1 Do we have an ETA on when this fix might be available?
I just switch to using https://github.com/can1357/oh-my-pi for my open model needs and specifically I am very happy with https://unsloth.ai/docs/models/qwen3.6 for the time being.
+1
Also experiencing this with the Xunfei (讯飞) custom provider via --profile xunfei.
Setup:
When using --profile xunfei:
Workaround attempted: using mcp-remote as a stdio proxy — this fails for Figma because Figma's MCP server rejects non-whitelisted
OAuth clients (403 Forbidden). It works for Tavily since Tavily accepts API keys in the URL.
Current workaround: switch back to default OpenAI model when Figma access is needed, then back to xunfei for regular coding. Not
ideal.
This is the same root cause as #19871 and #19363. Has been open since April — any updates on a fix?
I messaged OpenRouter and asked them if they could create a plugin to fix these request issues. They already have a "JSON Response Healer" plugin, and it sounds like it should be possible to have a "Codex Request Healer" plugin that rewrites the Codex request JSON to match the Responses API spec.
openai preferred PR 28271, then closed that one in favor of 29602, then closed 29602 with no explanation. Seems like supporting third party models isn't their priority, which I guess isn't too surprising, though disappointing.
@madarkadonk yes, exactly... this is what I've just seen right now. A bit disappointed honestly...
+1
I am also trying to use Codex (0.146.0) with a local model, and I cannot make MCP tool calls because of this issue either.
It seems like one of the related PRs fixes this, but it was closed before it was merged in? Is there any explicit reason for this?
https://github.com/openai/codex/pull/29602
Still waiting for a response to this
I’m the author of Swobu, a local compatibility gateway.
I reproduced this namespace failure and shipped an intermediary workaround in Swobu v1.0.0-rc.4. Swobu projects namespaced MCP tools into backend-compatible function names, keeps an attempt-scoped reverse mapping, and restores the original
{namespace, name}identity before returning the tool call to Codex.I verified the complete path on August 2, 2026 using:
openai/gpt-4.1-miniCodex successfully executed
microsoft_docs/microsoft_docs_searchand returned a grounded Microsoft Learn URL.Install Swobu:
Then point a Codex profile at the configured Swobu workspace:
The Codex-facing client key can be a placeholder; backend credentials remain configured in Swobu.
Additional sanitized reproduction data:
Expected behavior: third-party Responses providers should be able to declare supported tool kinds, or Codex should filter/flatten unsupported tool definitions before sending the request.
I reproduced this on the current stable CLI with a GLM custom Responses provider. The failure is not specific to Streamable HTTP or to a private MCP server.
Environment
0.146.0wire_api = "responses"codegraph, configured as an enabled STDIO serverControlled reproduction
To avoid sending private repository data to the provider, I created a temporary synthetic Git repository containing only a marker string,
CODEGRAPH_SYNTHETIC_OK.I then ran
codex --profile <glm-profile> execwith:codegraphenabled and approved for read-only tool useBefore the model run,
codex --profile <glm-profile> mcp get codegraphreported the server as enabled withtransport: stdioand the expected command/arguments.Observed model-facing state:
mcp__codegraph__*toolstool_searchlist_mcp_resources/read_mcp_resourcehelpersmcp_tool_callevent was emittedThe relevant feature state in
0.146.0is:This makes the registered STDIO MCP tools unreachable to this custom provider: they are not exposed directly, and the session has no discovery tool with which to load them.
Transport comparison and control
I observed the same missing-tool behavior with a healthy Streamable HTTP MCP server whose
initializeandtools/listcalls succeed, so the failure is not specific to STDIO versus Streamable HTTP.As a compatibility control, I ran Codex
0.136.0with the same GLM provider through a localhost adapter that only:namespacetools into ordinary functions namedmcp__<server>__<tool>, andThat control produced a real MCP tool call and a successful tool result. This is consistent with the
namespace_tools = false/ flattened-dispatch direction proposed in this issue.Expected behavior
For a custom Responses provider, Codex should either:
tool_searchpath for deferred MCP tools, orThe synthetic repository was deleted after the test. No private repository content, internal endpoint, or credential is included in this report.
A workaround for this issue is to use a proxy to flatten the request and unflatten the response: https://gist.github.com/mdunphy/6c2cf14aefddeb0d627d79c8e5d366cd
(The rewrite_roles() part is not needed for fixing MCP, that was to fix something else)
Additional Codex Desktop reproduction through CLIProxyAPI:
list_threads,read_thread, browser tools, and workspace tools.tool_searchpath.This appears to be the same compatibility boundary addressed by closed PR #29602, whose scope explicitly included flattened namespace tools, deferred
tool_searchresults, standalone extension tools, collision handling, and reverse dispatch. It also manifests in Codex Desktop as described in #30523.Is there a replacement for #29602, or can its provider-capability approach be revived? Custom Responses providers need either:
namespace_tools/ client-tool-search capability, orWithout this, custom providers are nominally supported but cannot use the complete Codex Desktop tool surface.
I'd like to note you can branch the Codex CLI and fix the problem. It
didn't play well with the Windows GUI frontend, especially while keeping my
legit OpenAI Codex stuff intact and up to date, so I also built my own GUI,
only about halfway done but functioning for basic tasks, memory, etc.
including MCP servers. With external models of the users choice - confirmed
to work with Gemma 4 e2b and e4b.
On Sun, Aug 9, 2026 at 12:12 AM Soham Dasgupta @.***>
wrote:
--
---------------------------------------------
Charles Niswander II
Allegan, MI
@. @.>*
*https://charlesniswanderinnovations.com/
<https://charlesniswanderinnovations.com/>*