Namespaced MCP tool calls fail after deferred tool discovery because replayed function_call drops namespace
What version of Codex CLI is running?
0.132.0
What subscription do you have?
self hosted
Which model were you using?
gpt-5.5
What platform is your computer?
Linux 5.14.21-150400.24.147-default x86_64 x86_64
What terminal emulator and version are you using (if applicable)?
tmux
Codex doctor report
Not relevant
What issue are you seeing?
When multiple MCP servers are enabled, Codex sometimes uses deferred tool discovery (tool_search / tool_search_output) before invoking an MCP tool.
In that path, the model emits a correctly namespaced function_call, the MCP tool executes successfully, but the next outbound request fails because the
replayed function_call is missing its namespace.
This appears to be a client/gateway serialization bug during history replay, not an MCP server bug.
#### Observed behavior
Failure sequence:
- Codex performs deferred tool discovery
tool_search_outputreturns a namespaced tool- model emits a
function_callwith a validnamespace - MCP tool executes successfully
- follow-up request to the model backend fails with missing namespace
Backend error:
```json
{
"error": {
"code": "EXTERNAL_API_ERROR",
"message": "Azure stream failed to open - Body: {\n \"error\": {\n \"message\": \"Missing namespace for function_call '<tool_name>'. It does not exist
in the default namespace. Round-trip the model's function_call item with its namespace field included.\",\n \"type\": \"invalid_request_error\",\n
\"param\": \"input[7].namespace\",\n \"code\": null\n }\n}"
}
}
### What steps can reproduce the bug?
This is not tied to one specific MCP server.
What matters is:
- multiple MCP servers enabled
- deferred tool discovery path is used
- the chosen tool is namespaced
- the next request replays prior function_call history
A smaller config with only a couple of MCP servers may avoid the problem because the model can directly emit the tool call without going through deferred tool
discovery.
#### Control case
With only two small MCP servers enabled, the same namespaced tool call succeeds end-to-end.
In that passing case:
- no tool_search_output appears
- the model directly emits the namespaced function_call
- tool executes
- follow-up turn succeeds
This suggests the bug is specific to:
tool_search_output -> function_call -> function_call_output -> replay
rather than to namespaced MCP tools in general.
#### Likely root cause
A client or gateway layer is dropping namespace from prior function_call items when rebuilding the outbound request history.
Most likely locations:
1. conversation history normalization
2. tool-call replay serialization
3. provider bridge / gateway request transformation before Azure
The backend appears to be correctly rejecting malformed input rather than generating the problem.
### What is the expected behavior?
If a prior function_call item includes namespace, that field should be preserved exactly when conversation history is replayed into the next outbound model
request.
#### What makes this notable
The local rollout JSONL shows the original function_call item is correct.
Sanitized example:
{
"type": "function_call",
"name": "lookup_term",
"namespace": "mcp__server_a__",
"arguments": "{\"term\":\"ABC\"}",
"call_id": "call_123"
}
Then the tool runs successfully and produces function_call_output.
The failure only occurs on the next outbound request, which strongly suggests the namespace is being dropped during request reconstruction / serialization.This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗