[BUG] Stdio MCP tool calls default to 1-second timeout in v2.1.148 — long-running tools fail before server can respond
Observed
In Claude Code v2.1.148, every tool call to a stdio MCP server aborts at ~1001ms with:
MCP server "<name>" tool "<name>" timed out after 1s
This happens even when no MCP_TOOL_TIMEOUT env var is set and the server config in ~/.claude.json has no timeout field. The server's correct response arrives a few seconds later but is discarded by the host:
Connection error: Received a response for an unknown message ID: { ... }
HTTP MCP transports are unaffected — the same session can call HTTP MCP tools that take 5+ seconds and they return normally.
Expected
Either:
- The default stdio MCP tool timeout matches what's documented for other transports (much higher than 1s — see "Hypothesis" below), or
- The host waits for the server's response and surfaces it normally.
Repro
Any stdio MCP server with a tool that takes >1s to respond reproduces this. The shortest off-the-shelf example uses @openai/codex, which is publicly available via npm:
# Install codex CLI (the MCP server)
npm install -g @openai/codex
# Register it as a stdio MCP server
claude mcp add --scope user --transport stdio \
--env=OPENAI_API_KEY=<your-openai-key> \
codex -- codex mcp-server
Then in a CC v2.1.148 session, ask the assistant to call the codex MCP tool with any prompt. The tool call fails at ~1001ms.
For anyone without an OpenAI key handy: any stdio MCP server with a tool that sleeps >1s before returning will reproduce it. A ~30-line Python/Node stdio JSON-RPC server is sufficient.
Logs
CC writes per-call logs at ~/Library/Caches/claude-cli-nodejs/<encoded-cwd>/mcp-logs-<server>/<timestamp>.jsonl. Trimmed sample from one failed call:
17:52:50.878 Calling MCP tool: codex
17:52:51.879 Tool 'codex' failed after 1s: MCP server "codex" tool "codex" timed out after 1s
17:52:56.463 Connection error: Received a response for an unknown message ID:
{"jsonrpc":"2.0","id":5,"result":{"content":[{"type":"text","text":"hello"}], ...}}
Connect was healthy (~65ms). The server returned a valid response 5.5s after the request. CC had already cancelled request id 5 at the 1.001s mark.
Config baseline
mcpServers.codex in ~/.claude.json when the bug fires — no timeout anywhere:
{
"mcpServers": {
"codex": {
"type": "stdio",
"command": "codex",
"args": ["mcp-server"],
"env": {"OPENAI_API_KEY": "..."}
}
}
}
Env: no MCP_TOOL_TIMEOUT, no MCP_TIMEOUT set in the shell that launched CC.
Workarounds (both confirmed)
Both require a CC restart — the running process caches config at startup.
1. Per-server timeout in ~/.claude.json:
"codex": {
"type": "stdio",
"command": "codex",
"args": ["mcp-server"],
"env": {"OPENAI_API_KEY": "..."},
"timeout": 300000
}
2. Env var:
export MCP_TOOL_TIMEOUT=300000 # in ~/.zshrc, then restart CC
That both work suggests the timeout machinery itself is healthy. The bug appears to be just in the default value for stdio servers.
Hypothesis (optional reading — feel free to skip)
Looking at the CC 2.1.148 binary, the function that returns the per-call timeout looks like:
function gD3(H) {
let _ = parseInt(process.env.MCP_TOOL_TIMEOUT || "", 10),
q = H?.timeout ?? (_ > 0 ? _ : void 0) ?? FD3;
return Math.min(Math.max(q, 1000), j5K)
}
// FD3 = 1e8 ms (~28h); j5K = 2147483647
With nothing configured, q should fall through to FD3 and the result should be ~1e8. In practice the runtime returns 1000, which would happen if something is feeding H.timeout a sub-1s value (e.g. 0) so the ?? chain doesn't short-circuit and the Math.max(q, 1000) floor kicks in.
This is just behavioral inference from the binary — I couldn't pin down the exact code that sets H.timeout to a small value for stdio servers, and you'd see the truth instantly from source.
Possibly related
- #58687 — long-running MCP tool calls cancelled before server responds; response arrives intact after cancel and is discarded. Same end-state behavior, different transport (stdio→HTTP bridge) and version (2.1.58).
- #61669 — feature request from v2.1.145: "No MCP-layer timeout exists. A hung MCP tool call blocks an agent indefinitely." If a timeout mechanism was added between 2.1.145 and 2.1.148 in response, the stdio default in this report may be the regression.
- #16837 —
MCP_TIMEOUTnot respected above 60s.
Environment
- Claude Code: 2.1.148
- codex CLI (used as the repro MCP server): 0.130.0
- OS: macOS (Darwin arm64)
- Shell: zsh
Asks
- Confirm the intended default tool-call timeout for stdio MCP servers — is it meant to be ~
FD3(~28h), or something else? - Identify and fix whatever sets
H.timeoutto a sub-1s value for stdio configs. - (Stretch) Per #58687's suggestion: treat
MCP_TOOL_TIMEOUTas an idle-between-progress timeout rather than a hard wall-clock cap. The 1s default is the immediately-breaking bug, but a hard wall-clock cap also limits useful long-running tools.
Thanks!
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗