You launch Claude Desktop or Claude Code, see your MCP server appear in the tools list, and a minute or two later it greys out as “disconnected.” You reconnect, it works briefly, then drops again. This is the classic Claude MCP (Model Context Protocol) integration failure, and as of June 2026 the root cause is almost always one of: the local server process crashed, the startup blew past Claude’s ~60-second init window, an OAuth token expired, or the config points at the wrong path or Node binary.
Fastest fix (90% of cases): open the logs, find the line right after the disconnect, and match it to the table below. If you see exited with code 1 it’s a server crash; ENOENT / EACCES is a path/permission bug; Server transport closed ~60s after launch is a startup timeout; a 401 on tool calls is an expired token. Read once, fix once.
One thing worth knowing before you start: MCP is not an HTTP long-poll. For a local (stdio) server, Claude spawns a subprocess and talks to it over stdin/stdout. Stdio servers are not auto-reconnected — if the subprocess dies, the tool stays dead until you relaunch or reconnect. HTTP and SSE servers do auto-reconnect (Claude Code retries with exponential backoff, up to five attempts), so a stdio failure and a remote failure look the same in the UI but need different fixes.
Which bucket are you in?
Find the log line that appears right after the disconnect and jump to the matching fix.
| Log / symptom | Most likely cause | Go to |
|---|---|---|
exited with code 1, killed, or a stack trace | Server process crashed / OOM-killed | Step 2 + Step 3 |
Server transport closed ~60s after launch, no error | Startup exceeded the ~60s init window | Step 4 |
ENOENT: no such file or directory | Wrong / relative path in config | Step 2 |
EACCES: permission denied | Claude can’t read the file or dir | Step 2 |
Tool calls return 401 / unauthorized | OAuth token expired, no auto-refresh | Step 5 |
| Drops on a regular 30s / 60s clock, remote only | Corporate proxy cuts long-lived connections | Step 6 |
Cannot find module / Unexpected token | Node/Python version mismatch | Step 7 |
Every server fails right after initialize | Claude Desktop / OS-level bug | See FAQ |
Common causes, by hit rate
1. Local stdio server crashes or gets OOM-killed
Stdio MCP servers are Node or Python subprocesses Claude spawns. They get OOM-killed, throw on an uncaught exception, or fail to start under the wrong runtime version. Because stdio servers don’t auto-reconnect, one crash means the tool is gone for the rest of the session.
How to spot it: in the logs, exited with code 1, killed, or a stack trace.
2. Startup exceeds the ~60-second init window
This is the most under-diagnosed cause. Claude waits roughly 60 seconds for a stdio server to finish initializing. Servers that download heavy dependencies on first run blow past it — a Puppeteer server pulling Chromium (~180 MB), a Python server resolving packages, or any npx-launched server doing a cold npm install. The log shows Server transport closed about 60s in with no actual error.
How to spot it: the disconnect lands ~60s after launch, the first run is slow but later runs are fine (or vice versa if a cache got cleared), and the server is npx- or container-launched.
3. Wrong path or permissions in the config
The most common local gotcha. The args use a relative path, point at a file that doesn’t exist, or live in a directory Claude can’t read.
How to spot it: ENOENT: no such file or directory or EACCES: permission denied in the logs.
4. OAuth token expired and the server didn’t refresh
Remote MCPs (the official Notion, Sentry, GitHub, Asana servers) authenticate with OAuth or a bearer token. When the token expires and the implementation doesn’t auto-refresh, the connection looks live but every tool call returns 401.
How to spot it: tool calls return unauthorized / 401; re-running the OAuth flow fixes it.
5. Node / Python version mismatch
MCP servers generally need Node 18+ (Node 22 LTS recommended as of 2026) or Python 3.10+, but the first node on your PATH is older — for example a stock system Node. Claude inherits PATH, so the subprocess fails to start.
How to spot it: Cannot find module, Unexpected token, or a syntax error on a modern-JS feature. Confirm with which node && node -v.
6. Corporate network cuts the connection
Remote MCP over HTTP/SSE rides on a long-lived connection. Enterprise proxies and firewalls drop idle long-lived connections on a fixed interval.
How to spot it: the drop interval is suspiciously regular (every 30s or 60s) and only remote servers are affected.
7. macOS firewall blocked the server’s first launch
The first time a new local server tries to open a socket, macOS prompts “allow incoming connections.” If you hit Deny by reflex, it silently fails from then on.
How to spot it: System Settings → Network → Firewall → Options shows Claude or the server explicitly blocked.
Shortest path to fix
Step 1: Read the logs first
Don’t guess — the disconnect line tells you which fix to run.
Claude Desktop:
macOS: ~/Library/Logs/Claude/mcp*.log
Windows: %APPDATA%\Claude\logs\
To tail the macOS logs live while you reproduce the drop:
tail -n 50 -f ~/Library/Logs/Claude/mcp*.log
Claude Code:
claude --debug # verbose MCP startup output
/mcp # in-session: shows each server's status (connected / pending / failed)
/doctor # environment + config sanity check
Find the MCP entry nearest the most recent disconnect timestamp and match it to the bucket table above.
Step 2: Use absolute paths in the config
In Claude Desktop, open the config via Settings → Developer → Edit Config (this opens claude_desktop_config.json — macOS: ~/Library/Application Support/Claude/claude_desktop_config.json, Windows: %APPDATA%\Claude\claude_desktop_config.json). For Claude Code, project config lives in .mcp.json at the project root; local/user-scoped servers live in ~/.claude.json.
A correct stdio entry:
{
"mcpServers": {
"filesystem": {
"command": "/Users/you/.nvm/versions/node/v22.14.0/bin/node",
"args": [
"/Users/you/code/mcp-filesystem/dist/index.js",
"/Users/you/Documents"
]
}
}
}
Rules that prevent most disconnects:
commandis the absolute path fromwhich node, never bare"node".- Every path in
argsis absolute — never~or./. - Quote or escape any path that contains a space.
- The JSON must be valid. A single trailing comma or missing brace anywhere in the file silently kills all servers, not just the one you edited. Paste the file into a JSON validator if
/mcp(or the Desktop tool list) shows everything failing at once.
In Claude Code you can sidestep hand-editing entirely:
# stdio server (everything after -- runs the server untouched)
claude mcp add filesystem -- npx -y @modelcontextprotocol/server-filesystem /Users/you/Documents
claude mcp list # status of every configured server
claude mcp get filesystem
claude mcp remove filesystem
Step 3: Run the server by hand to confirm it starts
Copy the exact command + args from the config into a terminal:
/Users/you/.nvm/versions/node/v22.14.0/bin/node \
/Users/you/code/mcp-filesystem/dist/index.js \
/Users/you/Documents
If it crashes in your terminal, Claude can’t run it either. Fix the runtime version or install dependencies first. To prove the protocol handshake itself works (rules out the “Claude closes the pipe” class of bug), pipe an initialize request in:
echo '{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"test","version":"1"}}}' \
| /Users/you/.nvm/versions/node/v22.14.0/bin/node /Users/you/code/mcp-filesystem/dist/index.js /Users/you/Documents
A healthy server replies with a JSON result containing protocolVersion and capabilities. No reply means the server itself is broken; a clean reply means the problem is in how Claude launches it (path, env, or timeout).
Step 4: Fix the ~60s startup timeout
If the log shows Server transport closed about 60 seconds in with no real error, the server didn’t finish initializing in time.
- Pre-install dependencies so launch isn’t a cold install. For an
npxserver, install it globally or pin it inpackage.jsonfirst; for a Puppeteer/Playwright server, download the browser binary ahead of time so it isn’t fetched at startup. - In Claude Code, raise the startup timeout with the
MCP_TIMEOUTenvironment variable (milliseconds):
MCP_TIMEOUT=30000 claude # give servers 30s to start instead of the default
- For per-tool-call timeouts (a tool call that runs long, not startup), add a
timeoutfield in milliseconds to that server’s.mcp.jsonentry, e.g."timeout": 600000for ten minutes. See Claude Code MCP call timeout for that case specifically.
Step 5: Re-authenticate remote MCPs
When tool calls return 401:
- Claude Code: run
/mcp, select the server, and complete the OAuth flow again. - Claude Desktop: Settings → Connectors (or the server’s entry) → Disconnect → Connect, then re-authorize.
After authorizing, the tool should be usable immediately. If it still fails, check whether the upstream platform (Slack/Linear/GitHub/etc.) admin revoked the app authorization, or whether your bearer token (in a --header "Authorization: Bearer …" config) was rotated.
Step 6: Network and firewall
If the drop is on a regular clock and only hits remote servers, a proxy is cutting the connection. Ask IT to allowlist anthropic.com and your MCP’s specific domain (for example mcp.notion.com, mcp.sentry.dev), and to stop closing idle long-lived connections to those hosts. Note that the SSE transport is deprecated as of 2026 — if you control the server, prefer the HTTP (streamable-http) transport, which is more proxy-friendly.
For a blocked local server on macOS:
# is Claude blocked by the application firewall?
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --listapps | grep -i claude
# reset, then relaunch Claude and click Allow when prompted
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --remove /Applications/Claude.app
Step 7: Align runtime versions
node -v # need >= 18; Node 22 LTS recommended
python3 -V # need >= 3.10
which node # confirm which binary Claude will inherit
If you have multiple versions installed, hardcode the absolute path in command, or pin PATH in the server’s env:
{
"command": "node",
"args": ["/Users/you/code/mcp-filesystem/dist/index.js"],
"env": {
"PATH": "/Users/you/.nvm/versions/node/v22.14.0/bin:/usr/bin:/bin"
}
}
How to confirm it’s fixed
- Fully quit and relaunch Claude Desktop (Cmd+Q, not just close the window), or restart your Claude Code session — config and PATH are read at launch.
- In Claude Code run
/mcp(orclaude mcp list) and confirm the server readsconnected, notpendingorfailed. In Desktop, confirm the tool shows in the tools list. - Actually call a tool from the server and watch it return a result.
- Leave the session idle for 3-5 minutes, then call the tool again. If it survives the idle window, the disconnect is genuinely fixed rather than masked by a fresh reconnect.
Prevention
- Always absolute paths in the config — never
~or./. - Pin your Node version (nvm +
.nvmrc) so an OS or Homebrew update doesn’t swap the binary out from under Claude. - Pre-install MCP dependencies instead of relying on a cold
npxinstall at launch, so you stay inside the startup window. - After any config change, validate the JSON before relaunching — one bad comma takes down every server.
- Track
.mcp.json/claude_desktop_config.jsonin git so you can roll back a bad edit instantly. - For remote MCPs, note the token’s expiry somewhere and re-auth before it lapses.
FAQ
Every MCP server fails the instant it connects — even official ones. What’s wrong?
When all servers fail right after initialize (logs show Server transport closed then Server disconnected. For troubleshooting guidance, please visit our debugging documentation within tens of milliseconds), it’s almost never your server. The usual triggers are malformed JSON in the config (one syntax error disables everything) or a Claude Desktop / OS-level launch bug — a regression like this was reported on the macOS 26.2 Tahoe beta, where Desktop closed the pipe ~33ms after initialize. Validate the JSON first; if that’s clean, update Claude Desktop to the latest version and check the anthropics/claude-code issues for your OS.
Why does my remote MCP reconnect on its own but my local one doesn’t? By design. HTTP and SSE servers auto-reconnect with exponential backoff (Claude Code retries up to five times). Stdio (local subprocess) servers are not auto-reconnected, so a local crash is permanent until you relaunch or reconnect. If you need resilience, prefer a remote HTTP server where one exists.
The server connects but a tool call hangs forever, then errors out.
That’s a per-call timeout, not a connection drop. Add a timeout field (in milliseconds) to that server’s .mcp.json entry, or set MCP_TOOL_TIMEOUT. See Claude Code MCP call timeout.
Where exactly are the config and log files?
Desktop config: macOS ~/Library/Application Support/Claude/claude_desktop_config.json, Windows %APPDATA%\Claude\claude_desktop_config.json (open it via Settings → Developer → Edit Config). Desktop logs: ~/Library/Logs/Claude/mcp*.log. Claude Code: project config in .mcp.json, local/user servers in ~/.claude.json.
Should I use the HTTP or SSE transport for a remote server?
HTTP (the spec calls it streamable-http). SSE is deprecated as of 2026 — it still works but supports neither OAuth nor the claude mcp add --transport flag the same way, and proxies cut it more aggressively.
Related
- Claude Code MCP call timeout
- Claude tool unavailable
- Claude Connector no permission
- Claude GitHub connection failed
Tags: #Claude #Troubleshooting