Skip to content
Writing
MCPDebuggingClaudeCursor

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

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.

Why MCP Connection Failures Are So Difficult to Diagnose

Debugging Model Context Protocol (MCP) integrations can feel uniquely frustrating. Unlike standard HTTP REST APIs that return descriptive 4xx or 5xx status codes in browser developer tools, local stdio and remote SSE MCP connections frequently fail silently: Claude Desktop or Cursor displays a generic error message ("Tool execution failed" or "MCP server disconnected") with zero stack traces.

Under the hood, MCP relies on strict JSON-RPC 2.0 framing. The smallest corruption in stdout or an uncaught asynchronous exception will break the framing parser and crash the connection pipe. This systematic troubleshooting guide breaks down the four most common failure modes and provides verified remediation scripts.

1. Stdio Pollution: The #1 Silent Killer of Local MCP Servers

In stdio transport mode, POSIX standard output (stdout) is strictly reserved for JSON-RPC messages delimited by newlines. If your server code—or any imported npm package—executes a console.log("Server initialized") statement, that plain text string is injected directly into the JSON-RPC stream.

The host application (Claude or Cursor) attempts to parse "Server initialized" as a JSON-RPC 2.0 packet, throws a JSON syntax error, and immediately terminates the subprocess. To fix this, always redirect debugging output to stderr (console.error), which Claude routes directly into application diagnostic log files without contaminating the protocol stream.

TYPESCRIPT
// INCORRECT: Contaminates stdout and crashes Claude Desktop
console.log('[DEBUG] Tool invoked with args:', args);

// CORRECT: Emits to stderr for safe logging in Claude logs
console.error('[DEBUG] Tool invoked with args:', args);

2. Environment Variable Inheritance & Path Resolution

On macOS and Linux, GUI applications launched from the desktop (like Claude Desktop or Cursor) do NOT inherit your interactive shell environment (.zshrc, .bashrc). If your MCP configuration relies on process.env.PATH or ambient API keys, the subprocess will fail with ENOENT or Configuration Error: SADASEND_API_KEY missing.

Always supply absolute executable paths and declare explicit environment variables inside claude_desktop_config.json:

JSON
{
  "mcpServers": {
    "sadasend": {
      "command": "/usr/local/bin/node",
      "args": ["/Users/developer/projects/mcp-email/dist/index.js"],
      "env": {
        "SADASEND_API_KEY": "sada_live_sk_your_key_here",
        "NODE_ENV": "production"
      }
    }
  }
}

3. Common MCP Error Codes & Remediation Matrix

JSON-RPC Error CodeMeaningUnderlying CauseEngineering Fix
-32700 Parse ErrorInvalid JSON payload receivedStdout polluted with console.log or crash traceSwitch all logging statements to console.error
-32601 Method Not FoundRequested tool/prompt missingTool name spelling mismatch in server.tool()Run tools/list inspection script to verify tool registration
-32602 Invalid ParamsInput schema validation failedLLM supplied string instead of integer/booleanAdd z.coerce.number() in Zod input schema definition
-32603 Internal ErrorUncaught exception during executionUnhandled network fetch rejection or bad API keyWrap handler logic in try/catch block with isError: true

4. Verifying with the Official MCP Inspector

Never debug MCP servers directly inside Claude Desktop. Use the interactive @modelcontextprotocol/inspector web interface to step through tool handshakes and inspect raw JSON-RPC traffic:

BASH
# Launch interactive MCP diagnostic inspector
npx @modelcontextprotocol/inspector npx tsx src/server.ts
Free plan

Building AI agents that send email?

Scoped API keys, per-key recipient allowlists, approval mode and a hosted MCP server with ten tools — on the free plan, without a card.