DEV Community

Cover image for Debugging MCP Connection Timeouts and Tool Calling Failures in Claude, Cursor, and SadaSend
Woda Toki
Woda Toki

Posted on

Debugging MCP Connection Timeouts and Tool Calling Failures in Claude, Cursor, and SadaSend

When your MCP server fails with “Connection closed” or tools silently fail to execute in Claude Desktop, use this systematic diagnostic guide to fix the underlying issue.

The top 4 reasons MCP servers fail in Claude Desktop

  1. Stdio Pollution (Console Logging): In stdio transport, stdout is reserved strictly for JSON-RPC messages. If your code calls console.log("Starting server..."), the text corrupts the JSON-RPC stream, causing Claude to terminate the connection instantly. Always use console.error() for debug logs.

  2. Missing Environment Variables: Claude Desktop does not inherit your full terminal shell profile (.zshrc / .bashrc). Explicitly define environment variables inside claude_desktop_config.json.

  3. Schema Type Mismatches: If a tool parameter is marked as number in Zod but the LLM supplies "50" as a string without coercion, the server will reject the call with code -32602.

  4. Path Resolution Failures: Using relative paths (e.g. ./server.js) fails because Claude spawns processes from the application root. Always use absolute paths or npx.

# Test raw MCP handshake over stdio
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2026-07-28","capabilities":{},"clientInfo":{"name":"test-client","version":"1.0.0"}}}' | npx tsx server.ts

Verifying with the Official MCP Inspector
Run npx @modelcontextprotocol/inspector tsx server.ts to open a local web UI where you can inspect every JSON-RPC frame, inspect error codes, and benchmark tool latencies.

Read more about MCP Server Debugging: https://sadasend.com/blog/debugging-mcp-connection-timeouts-tool-failures

EmailAPI #DeveloperTools #ModelContextProtocol #MCP #Debugging #Claude

Top comments (1)

Collapse
 
rulestack profile image
Rulestack

One more failure mode worth adding for people on Claude Code rather than Desktop: a server can be configured and still be invisible. claude mcp list reports a status per server, and a server that failed its handshake shows as failed there while the config file looks fine. The stdout-pollution case you describe shows up exactly this way: the process starts, prints a banner, and the client drops it before the first tool call. The raw initialize echo you show is what I reach for first because it takes ten seconds; the Inspector is the second step when the frames need reading.