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 lets Claude Code work with external tools and data. When a connection fails, the log may also show the single line MCP error -32000: Connection closed. Combining three things, the status, the connection method, and the error details, narrows down the cause. This article works through local startup, remote communication and authentication, and then configuration and approval.
The essentials: (1) Read the status and details with /mcp and claude mcp get <name>. (2) failed can occur with both local and remote servers. For stdio, look at the command and environment variables; for HTTP, the URL, network, server response, and authentication. (3) If the cause is unclear, capture connection logs with claude --debug=mcp. Fix only what the actual error points to, then reconnect to confirm the result.
Find the cause from status and details
— narrow down failed by connection method and error details
✗ failed = connection failed, △ needs auth = authentication required, ⏸ pending approval = waiting for approval.
Narrow down the cause of failed by the connection method and the Issue: details.
1. What this error is telling you
When the connection closes, the log shows the following line.
MCP error -32000: Connection closed
MCP error -32000: Connection closed indicates that the MCP connection closed. The MCP TypeScript SDK assigns -32000 to ConnectionClosed and emits this message when a connection closes (see the SDK connection-close handling). The line tells you only that the connection closed; the reason is in the log entries just before it. That is where you tell apart a server process that exited before initialization from a connection that dropped afterward.
A connection can close even when the configuration is correct. Issue #20713 is a user report of the connection closing during initialization with Claude Code 2.1.19 on macOS. The “race condition” cause is the reporter’s own theory, and the issue was closed as not planned in April 2026. If you report an issue yourself, include your OS, version, connection method, and logs with secrets removed.
MCP servers commonly use two 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.
With local (stdio) servers, the failures are a missing command, missing variables, a server that exits right away, or logs mixed into stdout. With remote (HTTP) servers, the causes are an incorrect URL, network problems, 5xx responses, timeouts, and authentication. Mistakes in the configuration file’s location, syntax, or scope can happen with either type.
First, note the status and error details, and see whether the connection uses stdio or HTTP. Changing several settings at once makes it hard to tell which change helped. Use the following table as a starting point, then investigate one relevant cause at a time.
2. Read the status with /mcp first
Run /mcp in a session (or claude mcp list / claude mcp get <name> from the shell) to see each server's state. The main statuses and their meanings are as follows.
| Status | Meaning | Where to look first |
|---|---|---|
| ✓ connected | Connected. Tool count shown beside it | If tools are expected but the count is 0, investigate exposed capabilities, permissions, and logs |
| ✗ failed | Connection to a local or remote server failed | The Issue: details and connection method. For HTTP, also look at communication, server responses, and fixed authentication headers |
| △ needs authentication | Sign-in or additional permissions needed | For OAuth, authenticate through /mcp. For headersHelper, look at the credential source; for Anthropic-hosted connectors, the connector settings in claude.ai |
| ⏸ pending approval | A project .mcp.json server waiting for approval. claude mcp list / get show it as ⏸ Pending approval | Start claude interactively and approve it. If wrongly declined: claude mcp reset-project-choices |
| ✗ rejected | A .mcp.json server listed in disabledMcpjsonServers in any settings file. Only claude mcp get <name> shows ✘ Rejected (see disabledMcpjsonServers in settings) (it does not appear in /mcp or claude mcp list) | Declining in the approval dialog writes this entry to .claude/settings.local.json. To undo your choice, use reset-project-choices; if the entry is in another settings file, remove it there |
failed appears for both local startup failures and remote communication failures. The details tell them apart: claude mcp list appends them to the end of the ✘ Failed to connect line, and claude mcp get <name> and the details view in /mcp show them on an Issue: line, giving the HTTP status or error code plus any error text the server returned. A fixed Authorization header rejected with 401/403 during connection also produces failed.
When a remote server drops mid-session, Claude Code tries to reconnect automatically, and /mcp shows it as pending in the meantime (a different meaning from waiting for approval). If all five attempts fail and it becomes failed, you see the notification MCP server "<name>" disconnected · open /mcp to reconnect (if it needs re-authorizing, it becomes needs authentication instead). Stdio servers are not reconnected automatically, so reconnect them manually from /mcp. /mcp also flags servers that declare the tools capability but expose no tools. A server that only provides resources or prompts is working normally even with zero tools. See the official server-status details.
3. Main causes of failure and fixes
These are the items to inspect for connection failures and configuration mismatches. Go through the items relevant to your connection method first.
What to inspect by connection method
spawn ... ENOENT.env. The env in settings.json also applies to the session and child processes, so those values take effect too.MCP_TIMEOUT (ms). In Bash: MCP_TIMEOUT=10000 claude. In PowerShell, set $env:MCP_TIMEOUT='10000', then launch claude..mcp.json goes at the project root (not under .claude/ or in settings.json). An undefined ${VAR} without a default raises a warning and remains as literal text./mcp. Note that a rejected fixed authentication header is reported as failed.Isolate the command, environment variables, and logs for local servers,
and the URL, communication, server response, and authentication for remote servers, following the actual error.
You can share a project .mcp.json, but do not commit secret values directly. For example, reference ${API_KEY} and set the required value in each environment. Some protected variable names, including Claude Code’s own credentials, resolve to empty strings in remote URLs and headers (official expansion rules). Interactive sessions request approval for project servers, but claude -p and the SDK load them without that prompt. Put any server you still do not want loaded in disabledMcpjsonServers (official project scope documentation). Related: MCP basics, A2A.
4. Check npx startup on Windows
If Windows reports spawn npx ENOENT, first look at the executable and PATH with where.exe npx. Next, test whether Node/npm works and whether the specified package can start on its own. According to the official Node documentation, .cmd files on Windows cannot run on their own and must be started through a shell or cmd.exe.
If the launch method is the cause: try cmd.exe /c
If the problem is how the .cmd file starts, try this form. Replace the package name with the one in the server’s official instructions:
{
"command": "cmd.exe",
"args": ["/c", "npx", "-y", "@scope/your-mcp-server"]
}
If you run it in WSL, set up Node, packages, and environment variables on the Linux side.
5. The diagnostic workflow
When the cause is unclear, work through the steps from the top. The trick is to confirm the server runs standalone before suspecting Claude Code.
Isolate it top-down
/mcp and claude mcp list / get to see the status, and read Issue: and the connection method too.claude --debug=mcp to capture MCP initialization and connection logs. For stdio servers, read the stderr output too.npx @modelcontextprotocol/inspector) — try fetching its tool list and invoking tools in a UI.A successful standalone launch is different from a successful MCP connection and operation.
Protocol compatibility, permissions, tool discovery, and client bugs can still cause problems after startup.
Note: by default, Claude Code loads tool definitions only when needed via tool search, so adding servers has only a small effect on the context. However, servers with alwaysLoad and setups where tool search is off load definitions from the start, so it is safer to disable servers you do not use with /mcp disable <name>. Overloading the context leads to Prompt is too long.
6. Prevention checklist
Habits that keep you from getting stuck on MCP connections.
(1) Write stdio executables and scripts with their actual paths. (2) Distinguish stdio variables from HTTP authentication headers, and keep secrets out of shared files. (3) On Windows, look at where.exe npx and Node/npm; try cmd.exe /c only when the launch method is the problem. (4) Put .mcp.json at the project root and inspect JSON syntax, variables, and approval. (5) Send stdio logs to stderr, not stdout. (6) Make one change at a time, then reconnect and confirm the result with the operation you need.
Summary
Investigate Claude Code MCP connection errors using the status, connection method, and error details together. failed is not limited to local startup failures: HTTP communication failures and rejected fixed authentication headers can also produce it. needs authentication is your entry point for revisiting authentication, and pending approval for revisiting approval of a project server.
Work through these steps: read the status and Issue: → read logs appropriate to the connection method → test standalone operation or communication → reconnect and try the operation. Select the debug category with claude --debug=mcp. Add --debug-file ./claude-mcp-debug.log to save the logs. Remove secrets before sharing them. Related: What is MCP, Monetizing MCP servers, Claude Code error roundup.
When the Codex app still shows the history but only sending fails, the problem is conversation state, not MCP. It is covered in Codex “thread not found”: troubleshooting and a recovery case.
FAQ
Q. /mcp shows failed. Where do I start?
A. Look at the connection method and Issue:. For stdio, the candidates are the command, path, environment variables, and stderr; for HTTP, the URL, network, server response, and authentication. A fixed Authorization header rejected with 401/403 during connection also produces failed, and Issue: then shows the HTTP status.
Q. It says "needs authentication" and the tools do not work.
A. The fix depends on the authentication method. For an OAuth server, authenticate through /mcp. With a custom headersHelper, this state appears when a tool call returns 401/403 and the retry with refreshed credentials also fails. If the helper supplies an Authorization header, Claude Code does not switch to OAuth: fix the credential source and the value it returns, then reconnect. Anthropic-hosted connectors such as Microsoft 365, Gmail, and Google Calendar do not support local OAuth from Claude Code. If you add one with claude mcp add or .mcp.json and sign in from /mcp, you see is Anthropic-hosted and doesn't support local OAuth; remove that entry and connect it in claude.ai's connector settings. See the official custom-authentication documentation.
Q. My npx server will not connect on Windows.
A. Look at where.exe npx and Node/npm, and try starting the same package with the same arguments. If the problem is how the .cmd file launches, you can start it with cmd.exe /c npx .... If you run it in WSL, set up Node and the packages on the Linux side.
Q. It is connected but shows 0 tools.
A. First, see whether that server is designed to provide tools. A server that only provides resources or prompts is working normally with zero tools. If it declares the tools capability but shows zero tools, /mcp flags that server; inspect exposed capabilities, permissions, server settings, and logs, then reconnect. Send stdio diagnostic logs to stderr, not to the stdout stream used for the protocol.
Q. I configured a server but cannot use it.
A. Check that the shared project .mcp.json is at the project root, then review syntax, scope, and approval status. An undefined ${VAR} without a default raises a warning and is loaded as literal text, which leads to startup or authentication failures. Write type in HTTP configurations too. If claude mcp get <name> returns ✘ Rejected, the server is listed in disabledMcpjsonServers in one of your settings files, so remove that entry rather than just redoing approval.
Configuration and command references: env settings, CLI reference, MCP connection reference.