Room 42, home

Fix an MCP server that will not connect

A debugging checklist for a dead MCP connection covering the command path, args, env, logs, and how to test the server on its own.

MCPadvanced9 min readUpdated 13 Jun 2026

In short

  1. 01A dead MCP connection is debugged in order: confirm the command, check the args and env, read the logs, then test the server on its own.
  2. 02Start with claude mcp get to read the stored config, since most failures are a typo, a relative path, or a missing key you can spot there.
  3. 03Use absolute paths everywhere and pass required keys explicitly, because a stdio server inherits only a limited environment.
  4. 04Watch for stdout pollution that silently corrupts the handshake, and use the MCP Inspector to prove whether the bug is the server or the wiring.
Contents · 10 sections
  1. 1How do I check an MCP server's status?
  2. 2Step 1 · The command path
  3. 3Step 2 · Working directory and absolute paths
  4. 4Step 3 · The args
  5. 5Step 4 · The environment
  6. 6Step 5 · Where are the MCP server logs?
  7. 7Step 6 · How do I test an MCP server on its own?
  8. 8Why won't my remote MCP server connect?
  9. 9Let Claude work the checklist with you
  10. 10A fast triage order

When an MCP server will not connect, work the chain in order: confirm Claude Code can find and run the command, check the args and env it passes, read the server logs, then run the server on its own to prove the fault is in the wiring and not the server itself. This guide is that checklist, top to bottom.

If you have not configured a server yet, read MCP fundamentals and MCP configuration first. This guide assumes you added a server and it shows up broken.

How do I check an MCP server's status?

Inside a Claude Code session, run the status panel:

/mcp

The /mcp panel lists every server and its state. A healthy stdioA local MCP server: Claude Code launches it as a child process and talks to it over standard input and output, with no network involved. server shows as connected with a tool count next to it. A broken one shows as failed, or as pending while Claude Code retries a remote connection.

To see the same picture from your shell without opening a session:

claude mcp list
claude mcp get my-server

claude mcp list prints every configured server and whether it connected. claude mcp get <name> prints one server's full configuration: the command, the args, the env, the transport, and the scope. Read this first. Most connection failures are a typo you can see in this output before you touch anything else.

Step 1 · The command path

A stdio server is a program Claude Code launches as a child process. If it cannot find or run that program, nothing else matters. You configure it like this:

claude mcp add my-server -- npx -y @scope/my-mcp-server

The -- separator splits Claude Code's own options from the command it runs. Everything after -- is the command and its args, passed through untouched.Common gotchaWith npx -y @scope/server, npx can launch a stale cached copy, so a fix you published never loads and the old bug appears to live forever.Pin the version (@scope/server@1.4.0) or clear the cache with npx clear-npx-cache to force the real one.

Check three things about the command:

  • Is the binary on the PATH Claude Code sees? Claude Code launches the process with a limited environment. A tool that works in your interactive shell may not be on the PATH the child process inherits. When in doubt, use an absolute path to the binary, for example /usr/local/bin/node instead of node.
  • Does the file exist where you pointed? A server you run with a script path, such as python /srv/mcp/server.py, breaks the moment that file moves. Confirm the path resolves.
  • Is it executable? A script without execute permission, or a Node entry point that was never built, fails at launch with a permission or "module not found" error.

PATHThe list of directories the shell searches for a command. A child process inherits a copy, which can differ from your interactive shell. mismatches are the most common reason a server that "works on my machine" fails inside Claude Code. The fix is an absolute path.

Step 2 · Working directory and absolute paths

When Claude Code launches a stdio server, the working directory may be undefined or the filesystem root, not the folder you started Claude from. A server that reads ./config.json or writes to ./data looks in the wrong place and fails.

Use absolute paths everywhere: in the command, in the args, and inside any .env file the server reads.

claude mcp add files -- npx -y @scope/server-filesystem /home/me/projects/notes

Pass the data directory as an absolute path in the args, never ./notes. The same rule applies to a database file, a credentials file, or a log path the server opens on startup.

Step 3 · The args

Args are the tokens after the command. One wrong flag and the process exits before the connection opens. Read the args back with claude mcp get and check them against the server's own documentation.

Common mistakes:

  • A flag the server does not accept. The process prints a usage error to its output and exits. You see a failed server with no tools.
  • A missing required arg, such as the directory a filesystem server needs or the connection string a database server needs.
  • Quoting that the shell ate. A value with spaces or a $ can be mangled when you type the claude mcp add command. Confirm the stored args with claude mcp get, because the stored copy is what runs.
SymptomLikely causeFix
Server fails instantlyWrong command or missing binaryUse absolute path, confirm it runs
Fails with a usage errorBad or missing argCompare args to server docs
Connects but exposes no toolsServer started but errored after initRead the logs
Remote server stuck pendingAuth not completedRun /mcp and authenticate

Step 4 · The environment

MCP servers launched over stdio inherit only a limited subset of environment variables, and the exact set is platform-dependent. A server that needs an API key or a connection string will not see a variable just because it is exported in your shell. You pass it explicitly:

claude mcp add --env API_KEY=your_key --transport stdio my-server -- node /srv/mcp/index.js

--env accepts multiple KEY=value pairs. Place at least one other option between --env and the server name, as shown above with --transport. If the name comes right after --env, the CLI reads the name as another pair and rejects it.Common gotchaA trap here is wrapping the value in quotes inside the pair, like --env API_KEY="abc". Your shell strips the outer quotes before the CLI sees them on a bare value, but when the value has spaces the quotes get stored literally and the server reads "abc" with the quote marks included, so every call 401s for no visible reason.Pass the raw value with no surrounding quotes and confirm the stored copy with claude mcp get.

For a project-scoped server, the values live in the project .mcp.json file, and you can reference machine-specific values with environment-variable expansion:

{
  "mcpServers": {
    "my-server": {
      "command": "node",
      "args": ["/srv/mcp/index.js"],
      "env": {
        "API_KEY": "${MY_APP_API_KEY}",
        "DATA_DIR": "${DATA_DIR:-/home/me/projects/notes}"
      }
    }
  }
}

The ${VAR:-default} form supplies a fallback when the variable is unset, which keeps the config working for every teammate. A server that connects but every tool call fails with "unauthorized" almost always has a missing or stale key here. Confirm the value with claude mcp get, then test the key against the service directly.

Step 5 · Where are the MCP server logs?

A stdio server writes its diagnostic output to stderrStandard error: the separate text stream a program uses for logs and errors, kept apart from the data it sends to the host., and the host captures it. This is where the real error message lives.

If you run Claude Desktop alongside Claude Code, its MCP logs are written to disk and you can tail them:

tail -n 20 -F ~/Library/Logs/Claude/mcp*.log

On Windows the same logs live under %APPDATA%\Claude\logs. The log captures the connection events, configuration problems, runtime errors, and the message exchange. Read the last failure before the disconnect. It usually names the exact problem: a module that would not load, a port already in use, a file it could not open.

Why does my MCP handshake never complete?

There is one failure that produces no clear error and confuses every beginner: a stdio server must never write to stdoutStandard out: the stream a stdio MCP server uses only for protocol messages. Anything else printed there corrupts the connection.. The protocol uses stdout for its JSON-RPC messages. A stray print or console.log in the server, or a startup banner from a dependency, injects junk into that stream and corrupts the connection.

If the server starts but the handshake never completes, suspect stdout pollution. Logs go to stderr; data goes to stdout; nothing else goes to stdout. If you wrote the server, move every log line to stderr. If you did not write it, an upstream dependency printing a banner is the usual culprit, and the project's issue tracker is the place to look.

Step 6 · How do I test an MCP server on its own?

Once the config looks right, prove the fault is in the wiring by running the server outside Claude Code. Two ways:

Run the exact command by hand. Take the command and args from claude mcp get and run them in your shell. If the process exits immediately or prints an error, the problem is the server or its environment, not Claude Code. Fix it here, where the feedback loop is tight, then add it back.

Use the MCP Inspector. The Inspector is the interactive testing tool from the MCP project. It connects to a stdio or HTTP server, lists the tools, prompts, and resources, and lets you invoke them while you watch the message stream. It is the recommended first stop for any server you are debugging:

npx @modelcontextprotocol/inspector node /srv/mcp/index.js

Pass the same command and args you would give Claude Code. If the Inspector connects and the tools work, your server is healthy and the bug is in how Claude Code launches it: revisit the path, args, and env. If the Inspector cannot connect either, the bug is in the server.

Why won't my remote MCP server connect?

The steps above target stdio servers, which are local processes. A remote server over HTTP fails for different reasons:

  • Authentication. When a remote server returns 401 or 403, Claude Code flags it in /mcp so you can complete the OAuthA standard way to grant an app limited access to your account without sharing your password. flow. Run /mcp and authenticate. A server stuck pending is usually waiting on this.
  • Reconnection. If an HTTP server drops mid-session, Claude Code reconnects automatically with exponential backoff, up to five attempts starting at one second and doubling each time. After five failures it is marked failed and you retry from /mcp. Stdio servers are local processes and are not reconnected automatically; restart the session.
  • The URL and transport. You add a remote server with the transport set explicitly, for example claude mcp add --transport http my-api https://api.example.com/mcp. A wrong path or scheme produces a connection error you can confirm with standard HTTP tooling like curl.

Let Claude work the checklist with you

You do not have to run every step by hand. Hand Claude Code the symptom and the config and let it reason through the chain:

Try this prompt
My MCP server "my-server" shows as failed in /mcp. Run `claude mcp get my-server` and read back the command, args, env, and transport. Then work this checklist with me: (1) confirm the command resolves to a real executable and is on the PATH; (2) check that every path in the args and env is absolute; (3) check that required env vars are present; (4) tell me where the logs for this server are and what to look for; (5) give me the exact command to run the server standalone and to launch it under the MCP Inspector. For each step, tell me what you found and what to fix. Do not change the config until I confirm.

A fast triage order

When you are in a hurry, run the chain in this order and stop at the first thing that is wrong:

  1. claude mcp get <name> · read the stored config; catch typos here.
  2. Command · does the binary resolve, and is it executable? Use an absolute path.
  3. Paths · is every path in args and env absolute, not relative?
  4. Env · are required keys passed with --env or in .mcp.json?
  5. Logs · what is the last error on stderr before the disconnect?
  6. Standalone · does the Inspector connect? If yes, the bug is the wiring; if no, the bug is the server.

Most dead connections are a relative path, a missing key, or a stray write to stdout. Work the list in order and the failure names itself.