Skip to content

Claude Code MCP Server Not Loading: The Diagnostic Order

Most advice for this is a list of things to try in no particular order, which is how people end up reinstalling Node at 1am. Each step's answer determines whether the next one can even be true.

August 8, 20269 min readShift The Culture

You added an MCP server, the command printed Added…, and the tools are not there. Most advice for this is a list of things to try in no particular order, which is how people end up reinstalling Node at 1am. There is a fixed order to check, because each step's answer determines whether the next one can even be true. Work down it and you will land on the actual cause instead of the first plausible one.

1. The server is not in the list at all → you edited a file that does not apply here

This is the single most common cause, and it is a scope problem, not a syntax problem. Claude Code stores MCP configuration at three scopes, in two files:

the three scopes and where they actually live
local    ~/.claude.json     under the entry for ONE project path   ← the default
project  .mcp.json          in the project root, shared via git
user     ~/.claude.json     top level, applies to all your projects

Local is the default scope. If you ran claude mcp add foo -- npx -y foo with no --scope, that server was written into ~/.claude.json keyed to the directory you happened to be in. Open the project next door and it is gone — correctly, by design, and with no message saying so. The fix is almost always:

claude mcp add --scope user <name> -- npx -y <package>

Two further traps in this step. A project-scope server must be in .mcp.json at the project root — a .mcp.json nested in a subdirectory, or a .claude/.mcp.json, is not the documented location and will not be picked up. And MCP “local scope” has no relationship to .claude/settings.local.json; that file holds general settings, not MCP servers. The naming collision has cost more debugging hours than the feature has saved.

2. It is listed, but with the wrong command → scope precedence, and nothing merges

When the same server name is defined at more than one scope, Claude Code connects once, using the highest-precedence definition: local, then project, then user. The important detail is what “uses” means — the entire entry from that source wins. Fields are not merged across scopes. A stale local-scope entry pointing at a path that no longer exists silently beats the correct project entry your team committed, and the error you see is a connection failure with no hint that a shadowing definition exists.

claude mcp get <name> shows the resolved entry. If the command in it is not the command you wrote, you have found your problem: remove the shadowing definition rather than editing the one you were looking at.

Nothing warns you that two scopes define the same server. The higher one simply wins, whole.

3. ⏸ Pending approval → this is not an error

Project-scoped servers from .mcp.json are not connected to until you approve them in an interactive session — a security boundary, since .mcp.json arrives with the repository. Run claude in the project, review the prompt, approve. To reset those choices later: claude mcp reset-project-choices.

The version of this that looks like a bug: a repository cannot approve its own servers. As of v2.1.196, claude mcp list and claude mcp get read .mcp.json approvals only from settings files that are not checked into the repository, until you trust the workspace by running claude in it and accepting the workspace-trust dialog. So a freshly cloned repo that ships enableAllProjectMcpServers in its committed .claude/settings.json is ignored, and the server sits at ⏸ Pending approval looking broken. Accept the trust dialog and it connects.

4. Approved, still absent → check the disable lists

There are two unrelated pairs of settings that can suppress a server, and their names are close enough to be genuinely confusing:

  • enabledMcpjsonServers / disabledMcpjsonServers — control approval of servers defined in a project's .mcp.json. A server in disabledMcpjsonServers is blocked in every mode, including headless runs.
  • enabledMcpServers / disabledMcpServers — recorded per project in ~/.claude.json when you toggle a server in the UI. Different mechanism, different file, unrelated to the pair above.

If you ever toggled a server off in a session and forgot, this is where that decision is living.

5. ✘ Failed to connect → the command cannot run, or cannot run in time

Now it is a process problem, and the questions are ordinary ones. Run the server's command yourself, exactly as configured, from the same directory:

reproduce the launch by hand
npx -y some-mcp-server
# a working stdio server starts and waits silently on stdin.
# an error, a usage message, or an immediate exit is your answer.
  • PATH.A GUI-launched client does not inherit your shell's PATH. A server that works in your terminal and fails in a desktop app is usually this — use an absolute path to the binary (which npx) in that client's config.
  • The -- separator. In claude mcp add, everything after --is passed to the server untouched; everything before it is parsed as Claude's own flags. Flags for your server placed before the -- get eaten.
  • Startup timeout. A first npx run that downloads a package can exceed the default. MCP_TIMEOUT=10000 claude sets a ten-second startup timeout; running the package once by hand to warm the npx cache also fixes it permanently.
  • Environment variables. Variables are set in the server'senvironment, not Claude Code's. Expansion like ${CLAUDE_PROJECT_DIR} inside a .mcp.json command needs a default — ${CLAUDE_PROJECT_DIR:-.} — outside of plugin-provided configs.
  • Transport name. When configuring by JSON, the type field accepts streamable-http as an alias for http, so a config copied straight from a server's docs works unmodified. If you hand-translated it to something else, translate it back.

6. ! Needs authentication → sign in, and know where that fails silently

Run claude mcp login <name> from your shell, or /mcp inside a session. Use claude mcp login <name> --no-browser on a remote box.

The trap is non-interactive mode: a claude -p run or an Agent SDK session has no /mcppanel and cannot run an OAuth flow. Recent versions tell Claude that the server's tools are unavailable until you authorise it, so the model can name the server that needs sign-in — but you have to complete the sign-in from an interactive session. If your CI keeps behaving as though a server does not exist, this is a strong candidate.

7. Connected, tools still not used → connection is not the last step

A green tick means the handshake completed and tools were retrieved. It does not mean the model calls them. Two current behaviours matter here:

  • Tool search. On recent models, MCP tool definitions are deferred and searched rather than all loaded upfront — the default. That is usually what you want (it is the difference between ten servers costing you a large fixed slice of every context window and costing you approximately nothing), but it means a tool can be present and not visible in the way you expect. ENABLE_TOOL_SEARCH controls it.
  • Failed servers are reported to the model.When a configured server fails to connect, recent versions tell Claude which server failed and why, so it can say so instead of answering as if the server were never configured. Older versions did not, which is where “the agent pretends my server does not exist” comes from.

8. It works in your terminal and not in your session

claude mcp listruns where you are standing, with your shell's environment, right now. A session has its own working directory (so its own local- and project-scope servers), possibly a different environment, and it resolved its server list when it started — before the edit you just made. Inside a session, /mcp is authoritative. If the two disagree, restart the session first; if they still disagree, check what directory the session is actually in.

For the full separation of “configured” vs “connected” vs “running as a process” — including why the process count is always higher than the server count — see how to see which MCP servers are actually running.

The two checks worth automating

Steps 1 and 2 are a file-archaeology problem, and it is the same archaeology every time: which config declares this server, and is another one shadowing it. We wrote that check into a free MCP server so the agent can answer it too. whats-loaded-mcp has an mcp_servers tool that lists every MCP server configured across your clients and the file that declares each one — plus the reason it exists, which is telling you what is consuming your context window before you type.

both are one line, MIT, no config
claude mcp add --scope user whats-loaded  -- npx -y whats-loaded-mcp
claude mcp add --scope user whats-running -- npx -y whats-running-mcp

Its sibling whats-running-mcp covers the process half of step 5 — what is actually alive, what is holding a port, and what is an orphan of a client that already quit. Both are MIT, read-only, no telemetry, and stay free: source for whats-loaded-mcp and whats-running-mcp on GitHub, and the rest of the set on our agent tools page.

The order, on one screen

mcp not loading — work down, do not skip
claude mcp list                     status per server

not listed        → wrong scope. --scope user. check .mcp.json is at project ROOT
wrong command     → another scope shadows it. claude mcp get <name>
⏸ pending         → approve interactively; accept the workspace trust dialog
approved, absent  → disabledMcpjsonServers / disabledMcpServers
✘ failed          → run the command by hand. PATH, the -- separator, MCP_TIMEOUT
! needs auth      → claude mcp login <name>   (cannot be done in -p / SDK runs)
green, unused     → tool search; restart the session; check the session's cwd

Behaviour described here comes from Anthropic's Claude Code MCP documentation — installation scopes and precedence, health statuses, project-server approval and workspace trust, timeouts, and tool search. Where a behaviour changed in a specific version, that version is named above; check the docs against the version you are running before concluding you have found a bug.

SharePost on X
Free · 13 pages · no upsell inside

Get the Operator Field Kit — free

Six production prompts, the five-step operator setup, and nine rules from our own failure log.

  • 6 complete prompts — printed in full, not previews
  • The five-step setup, each step with a pass/fail test
  • 9 rules from the failure log that produced them

The kit, then the occasional operator note. One click unsubscribes and we never sell the address.

Keep reading