Flatten MCP namespace tools for non-OpenAI Responses API providers (Ollama, LM Studio, OpenRouter)

Open 💬 26 comments Opened Jun 3, 2026 by LucaCappelletti94
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

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).

View original on GitHub ↗

26 Comments

justaddcoffee · 1 month ago

+1 for this PR!

github-actions[bot] contributor · 1 month ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #25034

Powered by Codex Action

LucaCappelletti94 · 1 month ago
Potential duplicates detected. Please review them and close your issue if it is a duplicate. * amazon-bedrock provider: namespace_tools capability breaks Bedrock Mantle (validation_error) #25034 _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.

MathieuBo · 1 month ago

+1 for this PR

AO33 · 1 month ago

+1 for this PR

GGBondBlueWhale · 1 month ago

+1 for this PR

SylvainWinning · 1 month ago

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:

  • OpenAI/Azure providers that support namespace tools continue to send grouped namespace tools.
  • Custom Responses-compatible providers default to plain function tools unless they explicitly opt into namespace support.
  • Flattened MCP tools use deterministic names such as mcp__<server>__<tool> and still dispatch back to the original server/tool pair.
  • Collision handling is explicit if a real tool name already matches a flattened MCP name.
  • The model-provider capability is visible through app-server capability reads, so Desktop/other surfaces can reason about the same behavior.

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_tools capability plus registry-level flat-name resolution seems like the right boundary if the team wants to support those without making the OpenAI path regress.

blakelai · 1 month ago

+1

madarkadonk · 1 month ago

+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.

LucaCappelletti94 · 1 month ago

@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.

justaddcoffee · 1 month ago

@madarkadonk also please promote this issue / PR! We feel like this really would improve codex

kaleighfilisa · 1 month ago

+1

jam8924 · 1 month ago

+1

madarkadonk · 1 month ago
@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.

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.

sfragrance · 1 month ago

+1 for this PR

LucaCappelletti94 · 1 month ago
> @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. 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.

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.

kotakem-openai contributor · 1 month ago

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

drakonkat · 1 month ago

I had the same issue +1 for this PR

flakz · 1 month ago

+1

fuzziebrain · 1 month ago

+1 Do we have an ETA on when this fix might be available?

LucaCappelletti94 · 1 month ago

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.

SZCjoker · 24 days ago

+1

xyun1996 · 19 days ago

Also experiencing this with the Xunfei (讯飞) custom provider via --profile xunfei.
Setup:

  • codex-cli 0.142.5 on Windows
  • model_provider = "xunfei" with wire_api = "responses" (OpenAI-compatible endpoint)
  • Figma MCP configured as HTTP with OAuth (works perfectly with default OpenAI model)
  • Tavily MCP same issue

When using --profile xunfei:

  • All MCP tools return unsupported call
  • codex mcp list shows servers as enabled with correct OAuth status
  • list_mcp_resources and read_mcp_resource still work (resources are accessible)
  • Only tool invocation is broken

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?

philippgille · 9 days ago

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.

madarkadonk · 8 days ago

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.

oddm643 · 6 days ago

@madarkadonk yes, exactly... this is what I've just seen right now. A bit disappointed honestly...