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.
- Run
claude mcp listand read the end of the line. A broken server shows✘ Failed to connectand the reason.claude mcp getwith its name adds the scope and the command that removes it. ENOENTmeans the program isn’t there.CONNECTION_CLOSEDmeans it started and quit, often over a missing key. Claude Code’s debug log shows the server’s own error.! Needs authenticationmeans sign in. Runclaude mcp loginwith the server’s name, or pick it in/mcp. A slow server times out at 30 seconds; raiseMCP_TIMEOUT.- In Codex,
codex mcp listcan’t tell you. It saysenabledfor a broken server. Type/mcpin a session to seefailed, 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 says | What happened | Fix |
|---|---|---|
ENOENT: Executable not found in $PATH | The program isn’t installed, or Claude Code can’t find it | Install it, or use its full path |
CONNECTION_CLOSED: Connection closed | It started, then quit before it answered | Read its error in the debug log |
connection timed out after 30000ms | It took longer than Claude Code waits | Start Claude Code with a bigger MCP_TIMEOUT |
ECONNREFUSED: Unable to connect | Nothing answered at the address | Check the URL, or start the server |
! Needs authentication | A web server wants you to sign in | claude mcp login, or /mcp |
Dynamic Client Registration rejected | It wants a sign-in, but won’t register Claude Code | Send a token in a header instead |
⏸ Pending approval | A project server you haven’t approved | Run claude in the folder and say yes |
has a “url” but no “type” | The entry was skipped | Add “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.
- A script can’t sign in.
claude -phas no/mcppanel, so it can’t run the sign-in. Sign in from a normal session before the script runs. - A sign-in that worked stops working. When the saved sign-in is refused,
/mcpoffers 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 = 30to the server’s[mcp_servers.name]block. - A key in a variable:
bearer_token_env_vartakes the variable’s name, not the key itself, and the variable must be set before Codex starts. - A project’s own config:
.codex/config.tomlin a repo loads only after you trust the project. - Not ready to fix it: set
enabled = falsein 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.
The analytics server lost its key on the laptop. Add it back with -e, then press Look again.
- Install acme-crm-mcp
- Sign in to notes-cloud
- Raise MCP_TIMEOUT
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.