Fix: MCP Server Disconnected Error
The Error
Your MCP server tool call completes successfully, but Claude Code immediately tears down the stdio transport and respawns the server:
Closing transport (stdio transport error: Error)
From the MCP logs (found at ~/Library/Caches/claude-cli-nodejs/-Users-{username}/mcp-logs-{server-name}/):
{"debug":"Calling MCP tool: my_tool_name","timestamp":"2026-04-14T05:41:34.761Z"}
{"debug":"STDIO connection dropped after 139s uptime","timestamp":"2026-04-14T05:41:34.880Z"}
{"debug":"Connection error: Received a progress notification for an unknown token: {\"method\":\"notifications/progress\",\"params\":{\"progress\":1,\"total\":1,\"message\":\"Completed\",\"progressToken\":5}}","timestamp":"2026-04-14T05:41:34.880Z"}
{"debug":"Closing transport (stdio transport error: Error)"}
{"debug":"Tool 'my_tool_name' completed successfully in 119ms"}
{"debug":"Starting connection with timeout of 30000ms"}
The tool call succeeded, but the transport was torn down anyway. If another tool call was in-flight, it fails with “MCP server disconnected.”
Quick Fix
If you control the MCP server: stop emitting terminal progress notifications after dispatching the tool response.
# BEFORE (causes the bug):
1. Process the request
2. Send the tool response
3. Send progress notification (progress=1, total=1) <-- races the response
# AFTER (fix):
1. Process the request
2. Send the tool response
3. Do NOT send terminal progress after response
What Causes This
The MCP protocol allows servers to emit notifications/progress messages during long-running operations. These notifications include a progressToken that matches the client’s in-flight request.
Here is the race condition:
- Claude Code sends a tool call request with a
_meta.progressToken - The MCP server processes the request and sends back the result
- Claude Code receives the result and removes the
progressTokenfrom its in-flight request map - The MCP server sends a terminal progress notification (
progress == total) for the same token - The notification arrives after the token has been removed from the map
- Claude Code treats the unknown-token notification as a fatal stdio transport error
- The entire transport is torn down and the server process is respawned
The MCP spec’s progress notifications section does not specify what a client should do when receiving a progress notification for an unknown token. Most MCP SDK implementations drop it with a debug log. Claude Code’s implementation treats it as transport corruption.
Full Solution
For MCP Server Authors
Remove terminal progress notifications that fire after the response. Only send progress notifications before the tool response:
// Send progress BEFORE the result, not after
async function handleToolCall(request: any) {
const progressToken = request._meta?.progressToken;
// Progress notification during work (before response)
if (progressToken) {
await sendProgress(progressToken, 0.5, 1.0);
}
const result = await doExpensiveWork(request.params);
// Return the result - do NOT send progress=1/total=1 after this
return { type: "text", text: JSON.stringify(result) };
}
For MCP Server Users (Cannot Modify Server)
Option 1: Wrap the server with a stdio proxy that filters progress
#!/bin/bash
# mcp-progress-filter.sh
# Sits between Claude Code and the MCP server, filtering late progress
REAL_SERVER="$@"
$REAL_SERVER | while IFS= read -r line; do
# Pass through everything except progress notifications
if echo "$line" | grep -q '"notifications/progress"'; then
echo "$line" >> /tmp/mcp-filtered-progress.log
else
echo "$line"
fi
done
Configure Claude Code to use the wrapper:
{
"mcpServers": {
"my-server": {
"command": "/path/to/mcp-progress-filter.sh",
"args": ["python", "-m", "my_mcp_server"]
}
}
}
Option 2: Accept the reconnection delay
If the server reconnects automatically (Claude Code does respawn it), the main impact is latency. The 30-second reconnection timeout may be acceptable for non-critical use cases.
Check Your MCP Logs
The logs that confirm this issue are at:
# macOS
ls ~/Library/Caches/claude-cli-nodejs/-Users-$(whoami)/mcp-logs-*/
Look for entries matching:
"Connection error: Received a progress notification for an unknown token"
Prevention
- When authoring MCP servers, only send progress notifications before the tool response, never after
- If your server must send a terminal progress notification, send it before the JSON-RPC response in the same write batch
- Test your MCP server with Claude Code specifically, not just generic MCP clients, since Claude Code has stricter transport error handling