Table of Contents
You set up an MCP (Model Context Protocol) server, but opening /mcp shows it stuck in a state like this — sound familiar?
/mcp
filesystem ✓ connected (12 tools)
github ✗ failed
notion △ needs authentication
my-server ⏸ pending approval
MCP gives Claude Code "hands" — external tools (file operations, GitHub, databases, various APIs) — but its connections trip up more often than you would expect. The causes split into three families: "local subprocess launch failure," "remote authentication," and "config file mistakes," and the /mcp status tells you which one. This article lays out how to read the status, cause-by-cause fixes, the top Windows trap, and the diagnostic workflow — based on official information.
Key points up front. (1) Look at the status with /mcp (and claude mcp list) first — failed (launch failure), needs authentication (auth), and pending approval (waiting for approval) all need completely different fixes. (2) For local (stdio) the usual culprits are paths and environment variables, plus the Windows npx problem. (3) For remote (HTTP) the usual culprit is OAuth. (4) When stuck, run claude --debug mcp to see the server's error output (stderr). Behaviors and defaults change by version, so confirm against the latest official docs.
The status tells you the fix
— failed / needs auth / pending each have a different cure
✗ failed = a local launch problem, △ needs auth = remote authentication, ⏸ pending = waiting for approval.
Do not lump "it won't connect" together — classify by status first; it is the shortest route.
1. What this error is telling you
MCP servers come in two broad connection types. (1) stdio (local) — Claude Code launches the server's command as a subprocess on your machine and talks over standard I/O. (2) HTTP (remote) — it connects to a cloud server by URL (the older SSE is deprecated). What "won't connect" means depends heavily on the type.
A local (stdio) failure is almost always "the command itself failed to launch" — wrong path, npx not resolving (especially on Windows), or the server crashing immediately because a required environment variable is missing. A remote (HTTP) failure is usually "OAuth has not been completed" — the server returns 401/403 and shows needs authentication. And when it is neither, yet the config has no effect, suspect the config file location, a JSON typo, or project approval.
So the first move is to "open /mcp, read the status, and identify which of the three families it is." Treating every error as a generic "won't connect" and poking at random is the long way around. The next section covers how to read the status.
2. Read the status with /mcp first
Run /mcp in session (or claude mcp list / claude mcp get <name> from the shell) to see each server's state. The main statuses and meanings:
| Status | Meaning | Where to look first |
|---|---|---|
| ✓ connected | Connected. Tool count shown beside it | If the tool count is 0: "connected but no tools" → reconnect / debug |
| ✗ failed | Failed to launch, or exhausted retries | Local launch = command, path, npx, env vars (§3, §4) |
| △ needs authentication | Remote returned 401/403. OAuth not done | Run authentication from /mcp (approve in browser) |
| ⏸ pending approval | Waiting for approval of a project .mcp.json server | Approve in /mcp. If wrongly declined: claude mcp reset-project-choices |
| ✗ rejected | A project server you previously declined | Same (reset-project-choices to re-approve) |
The point: "failed = a launch problem, needs authentication = auth, pending = approval" — the status uniquely determines your move. A commonly missed case is "connected but 0 tools" — the server started but is not returning a tool list; go to a reconnect or check logs with claude --debug mcp.
3. Main causes of failure and fixes
Here are the representative causes of failed (local launch failure) and config problems, paired with fixes.
Main drivers of failed / config issues
spawn ... ENOENT.env (in .mcp.json or --env). settings.json env does NOT reach MCP.MCP_TIMEOUT (ms) at launch, e.g. MCP_TIMEOUT=10000 claude..mcp.json goes at the repo root (not under .claude/, not in settings.json). An undefined ${VAR} makes config parsing fail.needs authentication. OAuth from /mcp. Note: a rejected static auth header is reported as failed.
For local, check in order: 1) path → 2) env vars → 4) config location.
For remote, 6) auth is nearly everything. The Windows trap in the next section is also very common.
A project .mcp.json can be shared via git and prompts for approval the first time. If you dismiss that prompt by accident, the server stays disabled (pending/rejected). Run claude mcp reset-project-choices to redo the approval. Pair this with MCP basics and agent-to-agent A2A for the full picture of connectivity.
4. When it fails on Windows (the top trap)
On native Windows, npx-based MCP servers failing to connect with spawn npx ENOENT / Failed to connect is extremely common. The cause: Windows npx is actually a batch shim (npx.cmd), and Node's process spawn cannot resolve a .cmd directly.
Fix: wrap it in cmd /c
Make command be cmd instead of npx directly, and pass /c npx ... as args:
{
"command": "cmd",
"args": ["/c", "npx", "-y", "@scope/your-mcp-server"]
}
Or run it under WSL, which is reliable. If where npx shows a path yet it still fails, suspect this .cmd problem first. Some version-specific occurrences may be fixed in later releases, so also try updating to the latest version.
5. The diagnostic workflow
When the cause is unclear, work top-down. The trick is to confirm the server runs standalone before blaming Claude Code.
Isolate it top-down
/mcp and claude mcp list / get to check the status (failed vs auth vs pending).claude --debug mcp to read the server's stderr (error output). The crash reason is usually right here.npx ... run in the same shell?). If not, it is a problem before Claude Code.npx @modelcontextprotocol/inspector) — inspect its tool list and invoke tools in a UI.mcp*.log. /doctor also checks.
The rule: confirm "does the server run standalone?" first.
Once that is settled, the rest narrows to config (path, env, location) or auth.
Note: adding too many MCP servers makes tool definitions eat the context (especially with always-load setups). Claude Code defers tool definitions via tool search by default, so the impact is small, but it is still wise to disable servers you do not use. Overloading the context can even trigger Prompt is too long.
6. Prevention checklist
Habits to avoid getting stuck on MCP connections.
(1) Specify local scripts with absolute paths. (2) Put server keys in the per-server env (not settings.json). (3) On Windows, wrap with cmd /c npx ... (or use WSL). (4) Keep .mcp.json at the repo root; watch JSON syntax and undefined ${VAR}. (5) Servers must not log to stdout (use stderr). (6) After config changes, reload (fully restart Desktop; re-approve project servers). (7) When stuck, isolate with claude --debug mcp and a standalone server launch, and update to the latest version if needed.
Summary
For Claude Code's MCP server connection errors, the shortest route is to classify by the /mcp status into three families. ✗ failed is a local launch problem (path, env vars, timeout, config location — and on Windows, wrap npx with cmd /c), △ needs authentication is remote OAuth (authenticate from /mcp), and ⏸ pending approval is a project server awaiting approval (approve in /mcp; a wrong decline is fixed with claude mcp reset-project-choices).
Diagnose in order: (1) status with /mcp -> (2) stderr with claude --debug mcp -> (3) standalone launch -> (4) MCP Inspector -> (5) fully restart Desktop. Confirm the server runs standalone before blaming Claude Code, and the rest narrows to config or auth. Just three habits — env vars in the per-server env, .mcp.json at the repo root, logs to stderr — drastically cut down on incidents. Related: What is MCP, Monetizing MCP servers, Claude Code error roundup.
FAQ
Q. /mcp shows "failed." Where do I start?
A. failed is mostly a local (stdio) server launch failure. Check in order: (1) the command/script path (use absolute paths), (2) required environment variables (put them in the per-server env), and (3) on Windows, wrap with cmd /c npx .... If the cause is still unclear, read the server's stderr with claude --debug mcp, and first test whether the server launches standalone in the same shell.
Q. It says "needs authentication" and the tools do not work.
A. This is a remote (HTTP) server requesting authentication (401/403). Open /mcp and run authentication for that server; it proceeds to OAuth approval in the browser. Once done, tokens are stored securely and auto-refreshed. Note that some services (Microsoft 365, Gmail, Google Calendar) do not support local auth from Claude Code and must be connected via Settings → Connectors on claude.ai instead.
Q. On Windows my npx server just will not connect.
A. Windows npx is actually a batch shim (npx.cmd), which often fails to launch with spawn npx ENOENT. Change command to cmd and args to ["/c","npx","-y","package-name"] to wrap it. Running under WSL is also reliable. If where npx shows a path yet it still fails, it is almost certainly this .cmd problem. It may be fixed in newer versions, so try updating too.
Q. It is "connected" but shows 0 tools.
A. The server launched successfully but is not returning a tool list. A common cause is a stdio server writing logs to stdout and corrupting the protocol — always send logs to stderr. First reconnect from /mcp; if that does not fix it, check the server's output with claude --debug mcp.
Q. I configured a server but it does not appear in /mcp.
A. The config file location is the likely issue. A shared project server goes in .mcp.json at the repo root (it is not read under .claude/ or inside settings.json). An undefined ${VAR} also makes config parsing fail. Project servers need a first-time approval; if you dismiss the prompt it stays pending — redo it with claude mcp reset-project-choices.