Guide · MCP failed to connect

Claude Code MCP Failed to Connect: 8 Errors, Fixed

When Claude Code says an MCP server failed to connect, the reason is on the same line, right after ✘ Failed to connect. It usually names the fix: the program isn’t installed, it started and quit, it took longer than 30 seconds, or nothing answered at the address.

We broke a server each of those ways on purpose on November 1, 2026, with Claude Code 2.1.311 and Codex 0.164.0 on Linux, and copied what each agent printed. Every output below comes from that test, with long file paths shortened. Claude Code separates some messages with a long dash, which we’ve typed as a hyphen.

Codex fails the same ways but reports it somewhere else. Its list command reads your config and stops, so a broken server still says enabled. The Codex section shows where the real state is.

Quick answer
  • Run claude mcp list and read the end of the line. A broken server shows ✘ Failed to connect and the reason. claude mcp get with its name adds the scope and the command that removes it.
  • ENOENT means the program isn’t there. CONNECTION_CLOSED means it started and quit, often over a missing key. Claude Code’s debug log shows the server’s own error.
  • ! Needs authentication means sign in. Run claude mcp login with the server’s name, or pick it in /mcp. A slow server times out at 30 seconds; raise MCP_TIMEOUT.
  • In Codex, codex mcp list can’t tell you. It says enabled for a broken server. Type /mcp in a session to see failed, and press F2 for the reason.
  • Each check covers one agent on one computer. Context Board lists every failing server of both agents on every computer you link, with the reason and how to fix it.

Read the reason in claude mcp list

Open a terminal in your project folder and run this.

claude mcp list

Claude Code starts every approved server it can use from that folder, the way a new session would, and prints a line for each. Our test setup had seven servers. One works, one waits for approval, and we broke the other five on purpose. It printed this.

Checking MCP server health…

team-docs: node ok-server.mjs - ⏸ Pending approval (run `claude` to approve)
docs-search: node ok-server.mjs - ✔ Connected
acme-crm: acme-crm-mcp --stdio - ✘ Failed to connect - ENOENT: Executable not found in $PATH: "acme-crm-mcp"
analytics: node crash-server.mjs - ✘ Failed to connect - CONNECTION_CLOSED: Connection closed
notes-cloud: http://127.0.0.1:4471/mcp (HTTP) - ! Needs authentication
offline-api: http://127.0.0.1:4479/mcp (HTTP) - ✘ Failed to connect - ECONNREFUSED: Unable to connect. Is the computer able to access the url?
slow-start: node slow-server.mjs - ✘ Failed to connect - MCP server "slow-start" connection timed out after 30000ms

The list took 30.6 seconds to print, because Claude Code waited the full time for slow-start before it gave up. A list that hangs before it prints is the first sign one server is slow.

For one server in more detail, run claude mcp get with its name. The Issue line repeats the reason, and the last line is the exact command that removes it.

$ claude mcp get acme-crm
acme-crm:
  Scope: Local config (private to you in this project)
  Status: ✘ Failed to connect
  Issue: ENOENT: Executable not found in $PATH: "acme-crm-mcp"
  Type: stdio
  Command: acme-crm-mcp
  Args: --stdio
  Environment:

To remove this server, run: claude mcp remove acme-crm -s local

Inside a session, type /mcp for the same servers. It’s also where you sign in to one, reconnect one after a fix, or turn one off for a project. If you’ve never listed your servers before, our guide to listing MCP servers in Claude Code and Codex covers where each one is saved.

Every Claude Code MCP error, and its fix

Match the end of your line to a row.

What the line saysWhat happenedFix
ENOENT: Executable not found in $PATHThe program isn’t installed, or Claude Code can’t find itInstall it, or use its full path
CONNECTION_CLOSED: Connection closedIt started, then quit before it answeredRead its error in the debug log
connection timed out after 30000msIt took longer than Claude Code waitsStart Claude Code with a bigger MCP_TIMEOUT
ECONNREFUSED: Unable to connectNothing answered at the addressCheck the URL, or start the server
! Needs authenticationA web server wants you to sign inclaude mcp login, or /mcp
Dynamic Client Registration rejectedIt wants a sign-in, but won’t register Claude CodeSend a token in a header instead
⏸ Pending approvalA project server you haven’t approvedRun claude in the folder and say yes
has a “url” but no “type”The entry was skippedAdd “type”: “http”

The first four are below. Sign-in and approval have their own sections after them.

ENOENT: the program isn’t there

Copy the command from claude mcp get and run it yourself. If your terminal can’t find it either, install it. If your terminal finds it and Claude Code doesn’t, ask the terminal where it lives with which acme-crm-mcp, then add the server again with that full path.

claude mcp remove acme-crm -s local
claude mcp add acme-crm -- /usr/local/bin/acme-crm-mcp --stdio

The words can change with the computer. In an October test on another machine, the same missing program came back as CONNECTION_CLOSED instead. Running the command yourself settles which one you have in a few seconds.

CONNECTION_CLOSED: it started, then quit

This one hides its cause. The server ran, printed an error and exited, and claude mcp list doesn’t show what it printed. The debug log does.

claude --debug-file mcp.log mcp get analytics

Open mcp.log and search for the server’s name. Ours held the server’s last words (times trimmed).

[DEBUG] MCP server "analytics": Starting connection with timeout of 30000ms
[ERROR] MCP server "analytics" Server stderr: Error: EXAMPLE_API_KEY is not set
[ERROR] MCP server "analytics" Connection failed (CONNECTION_CLOSED): Connection closed

A missing key is a common cause, as in our test. Remove the server and add it again with the key, using -e EXAMPLE_API_KEY=your-key before the --. Another is an old Node version: one write-up on dev.to traced ReferenceError: TransformStream is not defined to an app running a Node version older than the server needed, and fixed it by pointing the command at a newer Node.

Other MCP apps report this failure and the timeout as numbered codes from the protocol’s own toolkit: MCP error -32000: Connection closed and MCP error -32001: Request timed out. They point to the same causes.

Timed out after 30000ms: it was too slow

Servers started with npx or uvx download themselves on first run, and that can take longer than Claude Code waits. Our slow-start server waited 40 seconds before answering, and Claude Code gave up at 30.

Set a longer wait with the MCP_TIMEOUT environment variable, in milliseconds. We started it at 3000 and the same server failed at timed out after 3000ms, so the setting takes effect.

MCP_TIMEOUT=60000 claude

Or run the npx command once yourself, so the download is done before Claude Code asks.

ECONNREFUSED: nothing at that address

For a web server, check the URL for a typo, a wrong port or a missing /mcp at the end. For one on your own computer, start it before you start Claude Code. Claude Code retries a web server’s first connection up to three times and a program’s not at all, per the Claude Code MCP docs, so after a fix, pick the server in /mcp and choose Reconnect.

MCP server needs authentication in Claude Code

! Needs authentication isn’t a failure. Claude Code marks a web server that way when it answers 401 Unauthorized or 403 Forbidden, because it wants to know who you are. Sign in from your terminal.

claude mcp login notes-cloud

Your browser opens the service’s sign-in. You can do the same from a session: type /mcp, pick the server and follow the steps.

On a computer with no browser, such as a server you reach over SSH, add --no-browser and Claude Code prints the sign-in link. It needs a terminal you can type into, because you paste the redirect address back. Our test, run from a script with no terminal, got this.

Couldn't complete authentication for "notes-cloud": stdin isn't a terminal, so authentication can't be completed here. Re-run in an interactive terminal - e.g. `ssh -t` - and paste the redirect URL when prompted.

Scripts and expired sign-ins work a little differently.

  1. A script can’t sign in. claude -p has no /mcp panel, so it can’t run the sign-in. Sign in from a normal session before the script runs.
  2. A sign-in that worked stops working. When the saved sign-in is refused, /mcp offers Re-authenticate. If that loops, choose Clear authentication and sign in fresh.

Dynamic Client Registration rejected

Before you can sign in, Claude Code registers itself with the service as an app. Some services don’t allow that. Our test server refused, and the reason on its line read Dynamic Client Registration rejected (HTTP 401). GitHub’s hosted server has refused the same way since at least July 2025, as Incompatible auth server: does not support dynamic client registration, in GitHub issue 3433, still open when we read it.

The way round it is a token the service gives you, sent as a header.

claude mcp add --transport http github https://api.githubcopilot.com/mcp/ \
  --header "Authorization: Bearer YOUR_TOKEN"

If the service gives you an app ID for this instead, pass it with --client-id. With a token in a header, Claude Code reports a refused token as a failure instead of offering a sign-in, so a 401 in the reason then means the token is wrong or has expired.

Pending approval: a project server you haven’t said yes to

A server in the project’s .mcp.json is shared with everyone who opens the repo. Claude Code won’t start one until you approve it in that folder, so it isn’t broken, only waiting.

$ claude mcp get team-docs
team-docs:
  Scope: Project config (shared via .mcp.json)
  Status: ⏸ Pending approval (run `claude` to approve)

Run claude in the folder and approve it when asked. If you said no by mistake, claude mcp reset-project-choices clears every yes and no you gave that folder’s servers, and Claude Code asks again next time. The exception is claude -p, which loads project servers without asking.

A mistake in .mcp.json shows up here too. A web server without a type is skipped, and claude mcp list prints a warning under “MCP config diagnostics” instead of a line.

[Warning] [remote-notype] mcpServers.remote-notype: Skipped - MCP server "remote-notype" has a "url" but no "type"; add "type": "http" (or "sse" / "ws") to this entry

Add "type": "http" to the entry and run the list again.

When a Codex MCP server fails to start

Codex keeps its servers in ~/.codex/config.toml. We gave it the same broken servers, then ran its list command.

$ codex mcp list
Name         Command       Args               Env  Cwd  Status   Auth
acme-crm     acme-crm-mcp  --stdio            -    -    enabled  Unsupported
analytics    node          crash-server.mjs   -    -    enabled  Unsupported
docs-search  node          ok-server.mjs      -    -    enabled  Unsupported
slow-start   node          slow-server.mjs    -    -    enabled  Unsupported

Name         Url                        Bearer Token Env Var  Status   Auth
notes-cloud  http://127.0.0.1:4471/mcp  -                     enabled  Not logged in
offline-api  http://127.0.0.1:4479/mcp  -                     enabled  Unknown

Every server says enabled. Status means it’s turned on in the config, and the command never starts a server to find out more. Only Auth hints at a problem, with Not logged in for the server that wants a sign-in.

To see the real state, start codex and type /mcp.

🔌 MCP Tools
  • acme-crm: failed (0 tools)
  • analytics: failed (0 tools)
  • docs-search: connected (1 tool)
  • notes-cloud: authentication required (0 tools)
  • offline-api: failed (0 tools)
  • slow-start: failed (0 tools)

The reasons sit behind a warning count at the bottom of the screen, like ⚠ 6 warnings · f2 to view. Press F2 and step through them with the arrow keys.

MCP client for `acme-crm` failed to start: MCP startup failed: No such file or directory (os error 2)
MCP client for `analytics` failed to start: MCP startup failed: handshaking with MCP server failed: connection closed: initialize response
The notes-cloud MCP server is not logged in. Run `codex mcp login notes-cloud`.

The unreachable server’s warning ran to several lines and ended in error sending request for url (http://127.0.0.1:4479/mcp). Our October test on another machine printed MCP startup failed: program not found for a missing program, so expect the words after “MCP startup failed” to vary.

codex exec is quieter still. Our scripted run logged errors for the two web servers, said nothing about the three broken programs, and finished the task without them.

The fixes match Claude Code’s, with Codex’s own settings. These come from OpenAI’s Codex MCP docs.

  • Not logged in: run codex mcp login notes-cloud.
  • Slow to start: Codex waits 10 seconds by default. Add startup_timeout_sec = 30 to the server’s [mcp_servers.name] block.
  • A key in a variable: bearer_token_env_var takes the variable’s name, not the key itself, and the variable must be set before Codex starts.
  • A project’s own config: .codex/config.toml in a repo loads only after you trust the project.
  • Not ready to fix it: set enabled = false in its block. It stays in the file and stops failing.

See every failing server, on every computer

Each check above covers one agent on one computer, and Codex’s list doesn’t check at all. Use Claude Code and Codex on a laptop and a desktop, and that’s four places a server can break where you won’t see it until a task needs it.

Context Board is ours, so weigh the bias. It’s a live board you build for yourself, and its Connections widget reads every MCP server Claude Code and Codex use on each computer you link. It counts them, says how many need you, and turns red while one is failing and amber while one waits for a sign-in.

Connections2 computers2m
14connections3 need you2 failing · 1 to sign in
Codexapi · main1m
Working
Adding the CRM sync job

The analytics server lost its key on the laptop. Add it back with -e, then press Look again.

Today
  • Install acme-crm-mcp
  • Sign in to notes-cloud
  • Raise MCP_TIMEOUT
An example Context Board named Agents. Every number on it is example data.

Open it and what needs you comes first, then every server by computer and by agent.

  • Failing: the server wouldn’t start or turned down its key, with the reason.
  • Sign in: it’s waiting for you to sign in.
  • Doubled up: one agent has two ways into the same service, like GitHub as a claude.ai connector and as your own server.

Beside each is how to fix it. For a server of your own, that’s the command, ready to copy. For a claude.ai connector or a ChatGPT app, it’s a link to where you manage it. The board never changes your settings itself. You run the command on that computer, then press Look again.

It checks Codex servers the way a session starts them, so a broken one shows as failing, where codex mcp list would say enabled. It never starts a project’s servers. It reads those from the file and marks them Not checked.

A small program called the runner does the looking. You set it up once on each computer, with one line from Connect. It looks every six hours while the widget is on a board, and whenever you press Look again. Keys, tokens and passwords are stripped on your computer and again on the board, so the board gets names, states and fixes, never a secret.

It reads Claude Code and Codex, not Cursor or Claude Desktop. Context Board is free for 3 days, then $12 a month, with every widget included. Start with the computer where a server failed today: link it, add Connections, and press Look again after each fix.

Once everything connects, prune what you don’t use. A server can read and change things in whatever it connects to, so check what each one can do before you keep one you don’t remember adding.

Frequently asked questions

Something else on your mind? Get in touch.

Why does Claude Code say my MCP server failed to connect?

Because the server didn't start, quit before it answered, or took longer than Claude Code waits. claude mcp list prints the reason on the same line. ENOENT means the program isn't installed, CONNECTION_CLOSED means it started and quit (often over a missing key), and ECONNREFUSED means nothing answered at the address.

How do I fix MCP needs authentication in Claude Code?

Sign in. Run claude mcp login with the server's name, or type /mcp in a session, pick the server and follow the steps in your browser. On a computer with no browser, add --no-browser and Claude Code prints the sign-in link instead. Run it in a terminal you can type into, because you paste the redirect address back.

How do I see why an MCP server failed in Claude Code?

Run claude --debug-file mcp.log mcp get with the server's name, then open mcp.log. It records what the server printed before it quit, like a missing API key, which claude mcp list leaves out.

How long does Claude Code wait for an MCP server to start?

30 seconds in our test on Claude Code 2.1.311. A slower server fails with connection timed out after 30000ms. Start Claude Code with MCP_TIMEOUT set in milliseconds, like MCP_TIMEOUT=60000 claude, to wait longer.

Why does codex mcp list say enabled when the server is broken?

Because codex mcp list only reads config.toml and never starts a server. Start a Codex session and type /mcp. A broken server shows as failed, and one that wants a sign-in shows as authentication required. Press F2 to read why.

What does Pending approval mean in Claude Code?

The server comes from the project's .mcp.json and you haven't approved it in this folder, so Claude Code won't start it. Run claude in that folder and say yes. claude mcp reset-project-choices clears the answers you gave before.

Can I see failing MCP servers on all my computers at once?

Not with either agent's commands, which cover one computer each. Context Board's Connections widget lists every Claude Code and Codex server on each computer you link, failing ones first, with the reason and how to fix it. It's free for 3 days, then $12 a month.