Claude MCP server disconnected: causes and fixes

Published 2026-08-07

You set up an MCP server, it worked, and now Claude says "Server disconnected". Or it never connected at all, and the only clue is a Connectors menu with nothing in it. If you have searched for this error, you have probably found a pile of GitHub issues, a couple of 2025 blog posts that each cover exactly one cause, and nothing that explains the whole picture.

This article is that picture. It covers Claude Desktop, claude.ai custom connectors, and Claude Code, because "disconnected" means something different in each. Every error string quoted below was either reproduced on my own machine on August 6, 2026, or fetched verbatim from vendor documentation the same day. I run a live remote MCP server for Calmara, so some of the server-side behavior is demonstrated against a real production endpoint.

Quick answer: Read the log file first. On macOS: ~/Library/Logs/Claude; on Windows: %APPDATA%\Claude\logs. A local server that disconnects is a dead child process, usually a PATH or config problem. A remote connector that disconnects is usually expired OAuth or an unreachable server. And since July 28, 2026, transport mismatches between spec eras are a growing third cause.

What does "Server disconnected" actually mean?

For a local server, Claude Desktop spawns your server as a child process and talks to it over stdin/stdout. If that process exits, for any reason, the transport closes and Claude reports the server as disconnected. The message tells you that the process died, not why. The why is in the logs, which is why finding them is the first step and not a last resort.

For a remote server, there is no process on your machine at all. Anthropic's documentation is explicit: "Claude connects to your remote MCP server from Anthropic's cloud infrastructure, rather than from your local device." So when a remote connector shows as disconnected, checking your local Node version or PATH is wasted effort. The relevant questions are whether the server is reachable from the public internet and whether your OAuth token is still valid.

Keep that split in mind, because almost every fix below belongs to one side or the other.

Where are the Claude MCP logs?

The official locations, from the MCP project's own documentation:

  • macOS: ~/Library/Logs/Claude
  • Windows: %APPDATA%\Claude\logs

Two kinds of files live there. mcp.log "will contain general logging about MCP connections and connection failures." Files named mcp-server-SERVERNAME.log "will contain the stderr output from the named server". Since stdio servers may use stderr for all their logging, these files are not limited to errors. To watch them live on macOS:

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

On Windows: type "%APPDATA%\Claude\logs\mcp*.log".

In Claude Code, the equivalent first move is claude mcp list, which prints a health status per server: ✔ Connected, ! Needs authentication, ⏸ Pending approval, or ✘ Failed to connect with the underlying error. The /mcp command inside a session shows the same information and handles OAuth sign-in and manual retries.

One rule that trips people up constantly: after any config change, restart properly. The MCP debugging guide's exact words: for Claude Desktop, "fully quit and reopen; closing the window is not enough."

Why does the filesystem server keep disconnecting?

The filesystem server is the most common first install, so it is where most people first meet this error. The causes below apply to any local stdio server.

Node is installed, but Claude cannot find it

The classic. Your terminal finds npx because your shell profile sets up nvm or fnm. Claude Desktop is a GUI app: it inherits the system PATH, not your shell's, so the same npx call fails with spawn npx ENOENT. Here is what that looks like when I reproduce it in Claude Code with a deliberately wrong path:

 Failed to connect ENOENT: ENOENT: no such file or directory, posix_spawn '/nonexistent/bin/npx'

Two fixes, both endorsed by the MCP debugging guide ("Try using an absolute path for command"): point command at the absolute path of your node or npx binary (which npx in your terminal tells you where it is), or install Node system-wide so the GUI PATH can see it. On Windows there is an extra trap: npx keeps failing "if you have not installed npm globally"; check whether %APPDATA%\npm exists, and run npm install -g npm if not.

The config file has a syntax error

The config lives at ~/Library/Application Support/Claude/claude_desktop_config.json on macOS and %APPDATA%\Claude\claude_desktop_config.json on Windows. A trailing comma or a missing quote and no server in the file loads. Run the contents through any JSON validator before blaming anything else.

Relative paths and missing environment variables

The debugging guide warns that the working directory for servers launched from the config "may be undefined (like / on macOS) since the client could be started from anywhere", so relative paths like ./data break. Always absolute paths, in the config and in .env files. Similarly, stdio servers "inherit only a limited subset of environment variables automatically"; API keys and anything else your server needs must go in the server's env block. Windows users who see a literal ${APPDATA} in a failing path need to add the expanded value to env explicitly.

The server prints to stdout

If you wrote the server yourself: stdout belongs to the protocol. The debugging guide is blunt: local servers "should not log messages to stdout (standard out), as this will interfere with protocol operation." A single stray console.log or print() corrupts the JSON-RPC stream and the connection drops. Log to stderr; it lands in mcp-server-NAME.log where you can actually read it.

A directory the server was given no longer exists

Filesystem-specific: users have reported the server failing at startup when one of its allowed directories is unavailable or was renamed (GitHub issues #3232 and #58765). If you reorganized your folders recently, re-check every path in the args list.

tip: If you installed the server manually with npx and keep fighting Node problems, the one-click extension route sidesteps them entirely: Anthropic's support docs note that "Claude Desktop includes a built-in Node.js environment, so Node.js installation isn't required" for extensions (.mcpb bundles, formerly .dxt). The install guide covers both paths.

What causes "SSE error: Invalid content type, expected 'text/event-stream'"?

This error has a precise meaning that no ranking page seems to state: your client opened a legacy SSE connection and the response was not an event stream. The inner message comes from the eventsource library, which rejects any response whose Content-Type does not start with text/event-stream; the "SSE error:" prefix is added by the MCP TypeScript SDK.

I reproduced it with the SDK directly. Pointing an SSE transport at a normal web page (HTTP 200, text/html) produces the exact string:

SseError: SSE error: Invalid content type, expected "text/event-stream"

So the question is: what served you HTML or JSON where a stream was expected? The usual suspects, roughly in order:

  1. Wrong transport for the endpoint. The server speaks modern Streamable HTTP at something like /mcp, and your client is configured for legacy SSE. In Claude Code, switch the entry: claude mcp add --transport http <name> <url>.
  2. Wrong URL. The SSE stream lives at /sse but you configured the base URL, or vice versa. Check the server's documentation for which endpoint is which.
  3. An auth wall in the way. A login page, a Cloudflare challenge, or a corporate proxy returning an HTML error page all have the wrong Content-Type by definition.
  4. A proxy rewriting headers. Less common, but reverse proxies can strip or alter Content-Type.

The 60-second diagnostic is to ask the URL what it actually returns:

curl -sS -i -N -H "Accept: text/event-stream" https://your-server.example/endpoint | head -15

Look at the status line and Content-Type. A related signature tells you something different: pointing an SSE client at a stateless modern endpoint gets you SSE error: Non-200 status code (405). I reproduced that against Calmara's own endpoint, where a GET returns 405 because the modern transport is POST-only. A 405 here is not a broken server; it is a modern server telling you to use the other transport.

Why did my remote connector stop working?

Remember the split from the first section: a claude.ai custom connector runs from Anthropic's cloud. When one stops working, the causes live on the server side or in the OAuth relationship, not on your machine.

Expired or broken OAuth. Tokens expire; refresh flows fail; some servers forget their clients. Anthropic's documented fix is the right first move: "If authentication fails, try disconnecting and reconnecting from Customize > Connectors." That forces a fresh OAuth flow. (Searches like "mcp expired" describe this situation; there is no actual error string with those words. What expired is the token.)

The server became unreachable. Anthropic's docs: "If your MCP server is behind a corporate firewall, on a private network, or not reachable over the public internet, the connection will fail." Self-hosting behind a firewall means allowlisting Anthropic's published IP ranges for inbound connections.

The mcp-remote bridge. Many stdio-only setups reach remote servers through the third-party mcp-remote package (by Cloudflare's Glen Maddern, not an Anthropic tool). It has its own failure modes, and its README gives the fixes: Node must be 18 or higher; stale credentials are cleared with rm -rf ~/.mcp-auth followed by a client restart; corporate VPNs with certificate interception need NODE_EXTRA_CA_CERTS pointed at the CA file. Its transport strategies matter too: the default http-first falls back to SSE on a 404, and sse-first falls back to HTTP on a 405, so a misconfigured strategy against the wrong kind of server produces exactly the 404/405/content-type errors described above.

Claude Code handles remote OAuth more gracefully than it used to: when a request returns 401, it refreshes the stored token, reconnects, and retries once before flagging the server. If you are running non-interactively, claude mcp login <name> completes a sign-in that headless runs cannot.

Did the July 28, 2026 spec change break my server?

Short version: probably not by removing anything, but possibly by mismatch. The MCP spec revision finalized on July 28, 2026 removed sessions from the protocol core and made the modern transport stateless. I covered what the revision changes and what server operators need to fix in detail when it landed; the troubleshooting-relevant facts are these.

Nothing has actually been removed. The spec's deprecated-features registry states it directly: "No features have been removed under this policy yet." The legacy HTTP+SSE transport is deprecated, not gone, and as of early August 2026 no Claude client has dropped it: Claude Code still documents SSE as a supported transport with a deprecation note. Anthropic has said support for the new revision is rolling out across Claude products, without naming versions or dates.

What does break is the boundary between eras. A 2025-era client talking to a stateless 2026 server, or the reverse, produces a recognizable set of errors:

  • 404 on the modern endpoint: the server may only serve the legacy /sse path. Or it is a modern server and the request named a method it does not know. In that case the body carries a JSON-RPC error, which is the diagnostic: a JSON-RPC body means a live modern server, while an HTML or empty 404 means a wrong URL. Note that Claude Code does not retry 404s ("Authentication and not-found errors are not retried because they require a configuration change to resolve"), so fix the URL first, then retry from /mcp.
  • 405 on GET or DELETE: correct stateless behavior, not a bug. Calmara's endpoint answers a GET like this, and the body says why:
{
  "jsonrpc": "2.0",
  "id": null,
  "error": { "code": -32000, "message": "Method Not Allowed: stateless transport, POST only" }
}
  • Session errors: a client that expects an initialize handshake and a session ID meets a server that never mints one. Upgrading the client fixes it; the current SDK betas negotiate down to older servers automatically, but old clients cannot negotiate up.
  • Version and capability errors: the modern spec defines UnsupportedProtocolVersionError (-32022), which lists the server's supported versions in its data field, and MissingRequiredClientCapabilityError (-32021). If you see numeric codes in the minus-32020s, both sides of your setup are modern but disagree; updating the older side resolves it.

If you operate a server yourself, the Calmara MCP compatibility page and the spec-change article cover the server-side checklist; the one detail worth repeating here is that your 400 and 404 responses should carry real JSON-RPC error bodies, because that body is what tells modern clients not to misdiagnose you as a legacy server.

Why does the server disconnect mid-session?

Everything so far covers servers that fail at startup. Mid-session drops are their own category.

Claude Code's behavior here is precisely documented, and asymmetric: "If an HTTP or SSE server disconnects mid-session, Claude Code automatically reconnects with exponential backoff: up to five attempts, starting at a one-second delay and doubling each time." After five failures you retry manually from /mcp. But: "Stdio servers are local processes and are not reconnected automatically." If your local server crashes mid-session, nothing restarts it. That is by design, and the fix is to find the crash in mcp-server-NAME.log.

Claude Desktop has a known, unresolved class of silent mid-session drops with locally-bridged remote servers (see GitHub issue #61052); users report that the only reliable recovery is fully quitting and relaunching the app. If your server's own logs show a clean exit and no error, you are probably in this bucket.

For self-hosted remote servers, two infrastructure causes dominate: reverse proxies buffering SSE responses, and idle timeouts on quiet connections. The current spec addresses both explicitly: servers should send X-Accel-Buffering: no on SSE responses, and on long-lived streams they are encouraged to emit periodic SSE comment lines as keep-alives. If your server drops after a consistent interval of silence, an intermediary timeout is almost certainly the cause.

FAQ

How do I fix "MCP server disconnected" in Claude Desktop?

Read the log first: ~/Library/Logs/Claude/mcp-server-NAME.log on macOS, %APPDATA%\Claude\logs on Windows. An ENOENT error means a PATH problem (use an absolute path to node/npx); a JSON parse error means a broken config file; a stack trace means the server itself crashed. After any fix, fully quit and reopen Claude Desktop.

Why does my MCP server work in the terminal but not in Claude Desktop?

Because your terminal and Claude Desktop have different PATH environments. GUI apps do not read your shell profile, so nvm-managed Node installs are invisible to them. Use an absolute path as the command in the config, or install Node system-wide.

Is MCP's SSE transport deprecated, and does that break my connector?

Deprecated, yes; removed, no. The spec registry states that no features have been removed yet, and Claude clients still support SSE as of August 2026. What you may hit is a mismatch: a server that dropped SSE for the modern transport while your client entry still says SSE. See the July 28 spec change article for the full picture.

What does "SSE error: Invalid content type, expected 'text/event-stream'" mean?

Your client opened a legacy SSE connection and received something other than an event stream, usually HTML from a login or challenge page, JSON from a modern endpoint, or the wrong URL. Check what the URL actually returns with curl, and switch the client to HTTP transport if the server is modern.

What does "mcp expired" mean?

There is no error with that literal text; what expires is the OAuth token behind a remote connector. Disconnect and reconnect the connector from Customize > Connectors on claude.ai, or clear ~/.mcp-auth if you connect through mcp-remote.

Does Claude Code reconnect a failed MCP server automatically?

Remote HTTP and SSE servers, yes: five attempts with exponential backoff mid-session, three retries on transient startup errors. Local stdio servers, never: a crashed local process stays down until you fix the cause and reconnect. And for remote servers, authentication and not-found errors are never retried, because they need a configuration change to fix.

Do .mcpb extensions have the same problems as manual npx servers?

Mostly not. Extensions run in Claude Desktop's built-in Node.js environment, so the entire class of PATH and Node-version failures does not apply. If an extension's tools go missing, restart Claude Desktop and re-check its credentials in Settings > Extensions.

How do I test whether an MCP server is up without Claude?

For a remote server, POST a JSON-RPC request to its endpoint with curl and look at the status code and body: a JSON-RPC response (even an auth error) means the server is alive and speaking MCP. For a local server, run its command directly in a terminal; startup errors print immediately instead of hiding in a log file.

---

If the server you are troubleshooting is the Calmara connector, the compatibility page lists the current endpoint, transport, and per-client setup steps. And if you are setting up MCP for the first time, start with the step-by-step install guide instead of debugging a hand-written config.

← All articles

Written by Dan Hagen

Try Calmara

Auditable AI memory, tasks, calendar, and notes. Self-hostable, BYOK, free tier.

Get started free