MCP stdio transport: client kills stdin 2-5s after receiving successful tool response (chrome-devtools-mcp)
Summary
Claude Code's MCP client drops the stdio transport connection during Claude's response generation, seconds after the MCP server returns a successful tool result. The MCP server is healthy throughout — it never crashes or errors internally. The disconnect manifests as a -32000 Connection closed error on the next tool call in the sequence.
Environment
- Claude Code version: latest (as of 2026-04-13)
- Platform: macOS (darwin 25.4.0)
- MCP server:
chrome-devtools-mcpv0.21.0, registered as a User MCP in~/.claude.json - Server transport: stdio (
node ... chrome-devtools-mcp.js --autoConnect)
Reproduction
- Register
chrome-devtools-mcpas a User MCP in~/.claude.jsonwith--autoConnect - In a Claude Code session, call any sequence of 3-5 chrome-devtools MCP tools (e.g.
list_pages,select_page,navigate_page,take_snapshot,get_network_request) - After 3-5 successful tool calls, the next tool call returns:
MCP error -32000: Connection closed - The MCP server logs:
Parent death detected (stdin end). Sending shutdown event...
Log evidence
The server log (--logFile /tmp/chrome-devtools-mcp.log) shows a consistent pattern: the last recorded telemetry entry has "success": true, then 2-5 seconds later the parent death is detected. The server never records an error or crash.
"tool_name": "list_pages", "success": true, "latency_ms": 5000
2026-04-13T10:27:17Z Parent death detected (stdin end). Sending shutdown event...
"tool_name": "select_page", "success": true, "latency_ms": 5000
2026-04-13T10:27:44Z Parent death detected (stdin end). Sending shutdown event...
"tool_name": "evaluate_script","success": true, "latency_ms": 2500
2026-04-13T10:29:46Z Parent death detected (stdin end). Sending shutdown event...
"tool_name": "list_network_requests","success": true,"latency_ms": 500
2026-04-13T10:52:42Z Parent death detected (stdin end). Sending shutdown event...
"tool_name": "get_network_request","success": true,"latency_ms": 2500
2026-04-13T12:04:35Z Parent death detected (stdin end). Sending shutdown event...
"tool_name": "wait_for", "success": true, "latency_ms": 10000
2026-04-13T12:17:47Z Parent death detected (stdin end). Sending shutdown event...
"tool_name": "get_network_request","success": true,"latency_ms": 2500
2026-04-13T12:22:23Z Parent death detected (stdin end). Sending shutdown event...
This pattern repeated 18 times during a single debugging session (18 separate Parent death detected events recorded in the log). In every case, the preceding tool call recorded "success": true.
Key observations
- The MCP server never crashes. Every tool call that completes records
"success": trueor"success": false(graceful error). There are no unhandled exceptions, no process exits before the parent death event.
- The disconnect happens during Claude's response generation, not during tool execution. The server records the successful tool result, then the parent death arrives 2-5 seconds later — while Claude Code is presumably generating its text response using that result.
- The tool that gets the
Connection closederror is always the NEXT call after the disconnect. The tool that triggered the disconnect always succeeds from the server's perspective.
- Timing is variable (0.3s to 27.9s after tool completion), ruling out a simple fixed timeout. It correlates with tool response size — tools that return larger payloads (
wait_forat 10s latency,get_network_request) are followed by disconnects more reliably.
- Workaround that reduces frequency: saving tool outputs to files (e.g.
responseFilePath=/tmp/cdp-res.json) and reading them with theReadtool keeps MCP response payloads small and reduces (but does not eliminate) the disconnect rate.
Hypothesis
Claude Code's MCP stdio transport has a condition where the client closes stdin while processing a large tool response or during response generation. This could be:
- A response size threshold that triggers an early transport teardown
- A race condition between response streaming and stdio buffer management
- A timeout on the client side that fires during LLM inference when the MCP response was large
Impact
This makes it impossible to use any MCP server that requires multiple sequential tool calls in a single Claude Code session — any workflow requiring 4+ tool calls to the same MCP server will hit the disconnect.
Workaround (partial)
Keep MCP tool response payloads small:
- Write large outputs to temp files and read them separately with the
Readtool - Batch multiple reads into a single
evaluate_scriptcall instead of chaining tool calls - Interleave non-MCP work (file reads, grep) between sequential MCP calls
These reduce frequency but do not eliminate the problem.
This issue has 8 comments on GitHub. Read the full discussion on GitHub ↗