AI NewsletterSubscribe →
Resource HubAdvanced

MCP Server Troubleshooting Diagnostic Workflow

A step-by-step workflow for diagnosing MCP server problems — server doesn't appear, tools fail when called, schema validation errors, transport-specific failures, and the inspector tool that isolates the server from Claude Code.

Larry Maguire

Larry Maguire

GenAI Skills Academy

MCP servers fail in a small number of predictable ways. The diagnostic workflow below is built around isolating the failure to one of three layers — registration, transport, or the server itself — and fixing it from there. Most problems are resolved in the first two layers; the inspector tool handles the rest.

The three layers

  1. Registration — Claude Code knows the server exists. Run /mcp; the server is in the list. If not, the problem is in your config file
  2. Transport — Claude Code can connect to the server. The server appears as connected in /mcp, not error or disconnected. If it errors, the problem is in how the server is launched or in network/auth configuration
  3. Server — the server runs and responds correctly. Tools appear in /mcp, calls return results, no schema errors. If tools fail when called, the problem is in the server's code

Diagnose in order. Don't dig into server code if the server isn't even being registered; don't suspect a tool implementation if the transport is broken.

Layer 1 — server doesn't appear

Symptom: you registered the server, but /mcp doesn't list it.

Check the config file. User-scope servers are in ~/.claude.json under the mcpServers key. Workspace-scope servers are in ./.mcp.json at the workspace root. Open the file and verify your server is there with the expected name. Common mistakes: edited the wrong file, JSON syntax error elsewhere in the file invalidating the whole document, server registered under user scope but you're checking from a workspace where the user scope hasn't loaded.

Validate JSON. A trailing comma anywhere in ~/.claude.json or .mcp.json breaks the entire file. cat ~/.claude.json | jq . — if jq complains, fix the syntax error before doing anything else. The Claude Code CLI doesn't always report this clearly; the symptom is "no MCP servers" rather than "your config is broken".

Restart Claude Code. MCP server lists are loaded at session start. Edits to ~/.claude.json or .mcp.json while Claude Code is running don't take effect until you start a new session.

Workspace approval (project scope). Servers in .mcp.json require one-time per-workspace approval the first time you run Claude Code there. If you dismissed the approval prompt, the server stays registered but unapproved. Run /mcp, find the server, and approve it.

Layer 2 — server appears but errors

Symptom: /mcp shows the server but with a red error indicator, or it shows zero tools.

Use the debug flag. Restart Claude Code with claude --debug mcp. Stderr from your MCP server is then surfaced in the Claude Code logs. For stdio servers, this is the most useful single command — most server-side errors print to stderr on startup, but you only see them with --debug.

Check the command path. If the registered command is node dist/index.js (relative), it resolves against Claude Code's launch directory, not against the directory where you ran claude mcp add. Use absolute paths in MCP server commands; relative paths work in interactive testing and break in real use.

Check the executable exists. A Node version mismatch (server compiled against Node 20, system has Node 16) causes the server to crash on startup. Try running the exact command from your config in a plain terminal:

node /absolute/path/to/dist/index.js

It should sit silently waiting for stdin. If it crashes, the error tells you what's wrong.

Stdio-specific issues

  • Server logs to stdout — any console.log in the server's code sends invalid bytes into the JSON-RPC stream and Claude Code disconnects with a parse error. Search the server source for console.log; replace with console.error (stderr is safe)
  • Server crashes silently on startup — usually an unhandled promise rejection in async setup. The server starts, fails, exits; Claude Code sees a closed stream and reports "disconnected". Run with --debug mcp to see the stack trace
  • Environment variables not passed — env vars set via --env at registration are written to ~/.claude.json; if you registered the server without them, the server won't see them. Re-register with the correct flags

HTTP-specific issues

  • Authorization header format — Bearer tokens need the literal "Bearer " prefix; some servers expect just the token, some expect the full Authorization: Bearer xxx string. Read the server's docs and verify the header registration matches
  • CORS on local development servers — if you're testing against a server running on localhost, CORS configuration in the server can block Claude Code's requests. Server-side fix: allow the appropriate origin
  • Connection timeouts — slow servers or geographic distance can exceed the default connection timeout. Configure timeout in the registration if Claude Code's CLI exposes it; otherwise, host the server closer or speed up its cold-start

Layer 3 — tool calls fail

Symptom: server connects, tools appear in /mcp, but when Claude actually calls a tool, it fails.

Read the error. Tool call failures surface in Claude Code's chat — usually with a message like "Tool error: …" followed by the underlying issue. Read the literal text first; it often tells you exactly what's wrong (missing parameter, type mismatch, server-side exception).

Common error signatures and meanings:

  • "Method not found" — the tool name in the call doesn't match what the server registered. Usually a typo in the server's tool name, or a stale tool definition cached client-side. Reconnect the server
  • "Invalid params" — Claude passed arguments the server's input schema rejected. Either the schema is wrong (overly strict), or Claude is genuinely passing wrong types. Check the schema definition in the server source
  • "Internal error" — generic server-side exception. Run --debug mcp to see the actual stack trace from the server
  • JSON parse errors — the server returned invalid JSON. Almost always means stdout pollution (logging in stdio servers) or a bug in the response-shaping code
  • Schema validation failures — the response shape doesn't match what MCP expects. Check that your tool handler returns { content: [{ type: "text", text: "..." }] }, not just a string

The MCP Inspector

For stubborn problems that don't reveal themselves through Claude Code, the MCP Inspector tool isolates the server from the client. It's a separate process you run against your server directly, with a UI that lets you list tools, call them with chosen arguments, and see the raw protocol traffic.

npx @modelcontextprotocol/inspector node /path/to/your/server.js

The Inspector connects to your server using the same protocol Claude Code uses, but with a debugger UI on top. If your tool works in the Inspector and fails in Claude Code, the bug is in how Claude is calling it (probably a schema mismatch). If it fails in both, the bug is in your server.

When you're stuck

If diagnostics aren't progressing:

  • Reconnect the server from the /mcp menu — picks up server-side changes without restarting Claude Code
  • Restart Claude Code — picks up config changes
  • Roll back to a known-good version of the server — bisect to find what change broke it
  • Run the Inspector against the server in isolation — eliminates Claude Code as a variable
  • Check the server's GitHub issues — popular community servers have many of these problems documented

The general principle: don't add complexity (more tools, more env vars, more transports) until what you have is working. MCP problems compound — a slightly-broken server with one tool is much easier to fix than a slightly-broken server with twelve.

GenAI Skills Academy

Achieve Productivity Gains With AI Today

Send me your details and let’s book a 15 min no-obligation call to discuss your needs and concerns around AI.