Skip to main content

An MCP server fails to connect with CONNECTION_CLOSED

MCP
Failed to connect — CONNECTION_CLOSED: Connection closed

What is actually going on

  • This almost always means the server process started and then exited before completing the MCP handshake. It is rarely a network problem, even though the message sounds like one.
  • Run the server command yourself in a terminal. If it prints a usage or help message, the command in your config is missing a required subcommand.
  • If it starts but does slow work before serving — building an index, syncing a database — it may be exceeding the startup timeout.

The fix

Run the exact command from your config by hand and watch what it does. Pipe an initialize request into it to confirm it answers.

echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"t","version":"1"}}}' | your-mcp-command

If the server answers here but not in Claude Code, the difference is usually environment variables or a slow startup task rather than the command itself.

A configured MCP server never appears, with no error at all

MCP

What is actually going on

  • Silence, rather than a failure, usually means the config file you edited is not one Claude Code reads.
  • Claude Code reads MCP servers from ~/.claude.json (user scope) and .mcp.json (project scope).
  • An mcpServers block placed in ~/.claude/settings.json is ignored — settings.json has no such key, so it fails silently rather than erroring.

The fix

List what is actually registered, then add the server through the CLI so it lands in the right file.

claude mcp list
claude mcp add --scope user <name> <command>
claude mcp add-json --scope user <name> '{"type":"stdio","command":"...","args":[]}'

This one is worth checking first whenever a server "should" be configured but no tools appear. A file that is never read produces no diagnostics.

More MCP workflows and fixes

A remote MCP server reports "Needs authentication"

MCP
Needs authentication

What is actually going on

  • HTTP-based MCP servers use OAuth, and the sign-in happens inside an interactive session rather than at config time.
  • Adding the server to your config is only half the setup.

The fix

Start Claude Code and run /mcp, then complete the sign-in for the server listed as needing authentication.

/mcp

Pressing Enter for a new line submits a half-written prompt

Terminal

What is actually going on

  • By default your terminal sends Enter straight through, so there is no way to type a second line.
  • This is the single most common reason a first session feels broken.

The fix

Run /terminal-setup once. It rebinds Shift+Enter to insert a newline.

/terminal-setup
Full setup walkthrough

claude: command not found, right after a successful install

Install
zsh: command not found: claude

What is actually going on

  • The install succeeded but the directory it installed into is not on your PATH.
  • A shell that was already open will not pick up a PATH change made during install.

The fix

Open a new terminal window first. If it still fails, find the binary and add its directory to your PATH.

# find it
ls ~/.local/bin/claude /usr/local/bin/claude 2>/dev/null

# add to PATH (zsh)
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc

Answers get vague, or the session warns that context is nearly full

Context

What is actually going on

  • Every file read and command output stays in the conversation, so long sessions accumulate material that is no longer relevant.
  • A session that has drifted across several unrelated tasks is usually carrying all of them at once.

The fix

Check utilisation with /context, and reset between unrelated tasks with /clear. Keep CLAUDE.md thin, since it is re-read on every task.

/context
/clear
Keeping CLAUDE.md thin with playbooks

The same safe command asks for approval over and over

Permissions

What is actually going on

  • Approvals are per-action, so a command you run constantly will keep prompting unless it is allowlisted.
  • Permission behaviour also depends on your account type — some accounts decide this server-side, so a local workaround may no longer apply.

The fix

Add the commands you trust to the permissions allowlist in your project settings, rather than disabling permission checks globally.

Prefer narrowing the rule to the specific command over turning the check off. A blanket bypass removes the confirmation on genuinely destructive actions too.

Configuring permissions

Browser automation cannot attach to your already-running Chrome

Install

What is actually going on

  • Chrome only accepts the remote debugging port as a launch flag. There is no way to attach to a browser that is already open.
  • Chrome also refuses the debugging port when pointed at the default profile directory.

The fix

Launch a second Chrome instance with a debugging port and a separate profile directory. Your normal windows stay untouched.

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
  --remote-debugging-port=9222 \
  --user-data-dir="$HOME/.chrome-debug-profile"

# verify
curl -s http://127.0.0.1:9222/json/version

Because the profile is separate, any site you need to be logged into must be signed in again inside that window.

Still stuck?

The MCP track has a longer troubleshooting section covering server configuration in depth, and What's New is worth checking — behaviour you are working around may have changed in a recent release.

MCP workflows and troubleshooting →