← All articles

MCP Failed to Connect in Claude Code: Causes and Fixes

July 7, 2026·18 min read·MCPForge

MCP Failed to Connect in Claude Code: Causes and Fixes

Quick Answer

When Claude Code fails to connect to an MCP server, the failure can occur at any of seven stages: configuration loading, process launch, transport establishment, authentication, MCP initialization, capability discovery, or session maintenance. Randomly removing and re-adding servers wastes time.

Do this first:

  1. Run claude mcp list — see every configured server and its current status
  2. Run claude mcp get <name> — inspect the exact configuration for the failing server
  3. Identify whether it's a local stdio server or a remote HTTP server
  4. stdio: Run the exact configured command in your terminal; inspect stderr and exit code
  5. stdio: Compare PATH, environment variables, and working directory between your terminal and the Claude Code process
  6. Remote: Verify the URL, HTTP response, transport type, and authentication
  7. Enable debug logging via claude --mcp-debug to capture Claude Code-side diagnostics
  8. Test independently with MCP Inspector to isolate server failures from Claude Code-specific behavior
  9. If Inspector works but Claude Code fails, investigate configuration scope, environment, authentication, and transport compatibility

Claude Code MCP Failed to Connect: 60-Second Checklist

  • Identify the failing server name from claude mcp list
  • Inspect its full configuration with claude mcp get <name>
  • Confirm whether stdio or remote HTTP transport
  • Confirm which configuration scope the server is registered in
  • For stdio: run the exact command manually from the same working directory
  • Verify the executable resolves with which/command -v (macOS/Linux) or Get-Command (Windows)
  • Verify command and arguments are correct — no shell syntax inside the command field
  • Check every required environment variable exists with the correct name
  • Check stderr output and exit code from the manual run
  • Check that the process doesn't exit immediately (non-zero exit = startup failure)
  • Check stdout for contamination — any non-JSON output breaks the stdio stream
  • For remote: curl the MCP endpoint and inspect the HTTP status code
  • For remote: verify HTTPS, correct hostname, correct path, correct port
  • For remote: verify authentication credentials and token validity
  • Run with claude --mcp-debug and capture output
  • Test with MCP Inspector to isolate the failure
  • If multiple servers configured, reduce to one server and retry

Jump to the Right Fix

Error or SymptomStart Here
Server not listed after adding itCheck the Claude Code MCP Configuration
Server listed but shows disconnectedIdentify Which MCP Server Failed
command not found or spawn ENOENTVerify Executable Resolution
Server exits immediately (non-zero exit code)Check Immediate Process Exit and stderr
Server works in terminal but fails in Claude CodeMCP Server Works in Terminal but Fails in Claude Code
Missing environment variable error in stderrVerify Environment Variables
HTTP 401 from remote serverVerify Authentication
HTTP 403 from remote serverVerify Authentication
HTTP 404 from remote serverInspect the Configured URL and Transport
Connection refusedTest Network Reachability
Timeout connecting to remote serverTest Network Reachability
MCP initialization failureVerify MCP Initialization (stdio)
Malformed protocol / JSON parse errorCheck stdout Contamination
Server connects but tools don't appearConnected but Tools Do Not Appear
MCP Inspector works, Claude Code failsTest the Server Independently with MCP Inspector
Authentication error on remote serverClaude Code MCP Authentication Errors
Was working before, now failsMCP Server Worked Before but Fails Now
Failure started after Claude Code updateMCP Failed to Connect After Claude Code Update

Want to analyze your API security?

Import your OpenAPI spec and generate a Security Report automatically.

First: Identify Which MCP Server Failed

bash
claude mcp list

This lists every MCP server currently configured across all scopes, with their connection status. Look for the server that is missing or shows a disconnected/failed state.

Once you know the server name:

bash
claude mcp get <server-name>

This returns the full registered configuration: transport type, command, arguments, environment variable names (not values), and configuration scope.

What to check in the output:

  • Transport: stdio means a local process; http or sse means a remote endpoint
  • Scope: local, project, or user — a mismatch here explains why a server works for one developer but not another
  • Command: Verify it matches what you intended
  • Args: Verify no missing or transposed arguments
  • Env: Verify the variable names match what the server actually reads

Common confusion: A server appearing in claude mcp list does not mean it is connected. The list shows configured servers. The status field shows whether the connection succeeded. A server with no tools showing may be connected but returning an empty tool list — that is a different problem than a connection failure.


How Claude Code Connects to MCP Servers

Understanding the connection lifecycle helps you pinpoint exactly where the failure occurs.

  1. Claude Code loads MCP configuration from all applicable scopes
  2. Scope precedence resolves conflicts between local, project, and user configuration
  3. For stdio servers: Claude Code spawns the configured process as a child
  4. For remote servers: Claude Code opens an HTTP connection to the configured URL
  5. Transport is established (stdio pipe or HTTP stream)
  6. Authentication occurs when required (bearer tokens, OAuth)
  7. MCP initialization handshake completes (initialize / initialized)
  8. tools/list and capability discovery complete
  9. The connection is maintained for the session
Failure StageClaude Code SymptomHow to VerifyWhat to Fix
Configuration loadingServer missing from claude mcp listCheck scope; run claude mcp get <name>Re-add with correct scope
Process launchDisconnected immediately; spawn errorRun command manually; check PATHFix executable path or install dependency
Transport establishmentProcess running but no responseCheck stdout contamination; check stderrFix non-protocol stdout output
AuthenticationHTTP 401/403; OAuth failureInspect credentials; curl the endpointFix credentials or re-authorize
MCP initializationConnected but tools missing; protocol errorTest with MCP InspectorFix server implementation or version mismatch
Capability discoveryConnected, no tools shownTest tools/list via InspectorFix server's tool registration
Session maintenanceWas connected, then droppedCheck server logs; check process healthFix server stability or connection keepalive

Check the Claude Code MCP Configuration

Claude Code supports multiple configuration scopes. Getting the scope wrong is one of the most common reasons a server fails to appear or connect.

Configuration scopes

ScopeWhere it appliesHow to add
LocalCurrent project only, not committedclaude mcp add --scope local <name> ...
ProjectAll users of the project via .mcp.jsonclaude mcp add --scope project <name> ...
UserAll projects for the current userclaude mcp add --scope user <name> ...

The .mcp.json file in the project root is the project-scope configuration. It can be committed to source control but should never contain secrets directly — use environment variable references instead.

Common configuration failures

  • Wrong scope: Added to user scope but expected it in a specific project, or vice versa
  • Stale configuration: Old broken entry from a previous claude mcp add attempt
  • Duplicate names: Two entries with the same name in different scopes — the precedence may not be what you expect
  • Wrong command: Copied from documentation without adjusting for your local install
  • Missing env vars in .mcp.json: A teammate committed project configuration that references env vars they have locally but you don't
  • Configuration requires session restart: After adding or modifying an MCP server, start a new Claude Code session for the change to take effect

Removing and re-adding

Before removing a server, inspect it first:

bash
claude mcp get <name>

If the configuration is correct but the server fails, removing and re-adding with identical settings will not fix anything. Only remove when you have identified the configuration is wrong and know the correct values.


Fix Local stdio MCP Servers in Claude Code

1. Inspect the Exact Configuration

bash
claude mcp get <server-name>

Do not troubleshoot from memory. The command, argument order, environment variable names, and scope must match exactly. Transposed arguments and misremembered variable names cause silent failures.

2. Run the Exact Command Manually

Take the command and args from claude mcp get output and run them directly in your terminal:

bash
# npx-based server
npx -y @modelcontextprotocol/server-filesystem /tmp/test-dir

# Node.js server
node /absolute/path/to/server/index.js

# Python server
python -m my_mcp_server

# uvx-based server
uvx my-mcp-server

Interpreting the result:

What you seeWhat it means
command not foundExecutable not in PATH or not installed
Process exits immediately with code > 0Startup error — check stderr
ModuleNotFoundError / Cannot find moduleMissing dependency
Error: ENOENTFile or executable path doesn't exist
Process stays alive, no outputLikely waiting for stdio input — this is normal
Process outputs non-JSON textstdout contamination — will break MCP

Important: A stdio MCP server that starts correctly will wait silently for JSON-RPC messages on stdin. A process staying alive without output does not prove MCP initialization succeeds — it only proves the process launched. Test actual MCP behavior with MCP Inspector.

3. Verify Executable Resolution

Claude Code launches the server process without your interactive shell environment. Executables available via nvm, pyenv, Homebrew, or user-local installs may not be available.

macOS/Linux:

bash
# Check which executable your shell would use
command -v npx
command -v node
command -v python3
command -v uvx

# Check the actual PATH in your current environment
echo $PATH

Windows PowerShell:

powershell
# Check executable resolution
Get-Command npx
Get-Command node
Get-Command python
Get-Command uvx

# Check PATH
$env:PATH -split ';'

If the executable is found in your shell but fails in Claude Code, use its absolute path in the configuration:

bash
# Get the absolute path
which npx          # macOS/Linux
(Get-Command npx).Source   # Windows PowerShell

Then update the server configuration to use the absolute path.

4. Check Command and Arguments

The command field must be the executable only — no shell syntax, no pipes, no &&, no environment variable assignments:

json
// BROKEN — shell syntax inside command field
{
  "command": "cd /app && node server.js",
  "args": []
}

// BROKEN — executable and args combined
{
  "command": "node server.js --port 3000",
  "args": []
}

// CORRECT
{
  "command": "node",
  "args": ["/absolute/path/to/server.js", "--port", "3000"]
}

Windows path escaping in JSON:

json
{
  "command": "C:\\Users\\username\\AppData\\Roaming\\npm\\node.exe",
  "args": ["C:\\path\\to\\server.js"]
}

Spaces in paths on Windows must use either escaped backslashes or forward slashes inside JSON strings. Do not wrap paths in extra quotes inside the args array.

5. Verify Environment Variables

Environment variables set in your shell profile (.bashrc, .zshrc, PowerShell profile) are not available in the Claude Code child process unless explicitly passed in the MCP server configuration.

Verify a variable exists without printing the secret:

bash
# macOS/Linux — prints the length, not the value
echo ${#MY_API_KEY}

# Or confirm it exists at all
[[ -n "$MY_API_KEY" ]] && echo "set" || echo "not set"
powershell
# Windows PowerShell — check if set
if ($env:MY_API_KEY) { "set" } else { "not set" }

In Claude Code MCP configuration, pass required environment variables explicitly:

json
{
  "mcpServers": {
    "my-server": {
      "command": "node",
      "args": ["/path/to/server.js"],
      "env": {
        "MY_API_KEY": "${MY_API_KEY}"
      }
    }
  }
}

Verify variable name spelling — a variable named OPENAI_API_KEY will not satisfy a server reading OPENAI_KEY.

6. Check Working Directory Assumptions

Do not assume Claude Code launches the server from your project root or home directory. If the server reads a relative config file, relative database path, or local credential file, it will fail when launched from a different working directory.

Fix: Use absolute paths for all file references inside the server, or pass the path as a configuration argument. Do not rely on a relative ./config.json resolving correctly when launched by Claude Code.

7. Check Immediate Process Exit and stderr

Capture both stderr and exit code when running the server manually:

bash
# macOS/Linux
npx -y @my-org/mcp-server 2>/tmp/mcp-stderr.txt; echo "Exit: $?"
cat /tmp/mcp-stderr.txt

# Or combined
npx -y @my-org/mcp-server > /dev/null 2>&1; echo "Exit: $?"
powershell
# Windows PowerShell
$proc = Start-Process -FilePath "node" -ArgumentList "server.js" -RedirectStandardError "err.txt" -PassThru -Wait
$proc.ExitCode
Get-Content err.txt

A non-zero exit code with a startup error in stderr points directly to the fix. Common causes: missing dependency, invalid configuration, missing environment variable, unsupported Node.js version.

8. Check stdout Contamination

For stdio MCP servers, stdout is the protocol channel. Any non-JSON-RPC output on stdout — startup banners, console.log debug lines, progress indicators, or dependency installation output — corrupts the message stream and causes Claude Code to fail initialization.

Broken Node.js/TypeScript:

typescript
// This breaks the stdio MCP stream
console.log('Server starting...');
console.log('Connected to database');

Correct — always use stderr for logging:

typescript
// Safe: stderr does not interfere with stdio MCP protocol
console.error('Server starting...');
process.stderr.write('Connected to database\n');

Broken Python:

python
print("Server starting...")  # Breaks stdout stream

Correct Python:

python
import sys
print("Server starting...", file=sys.stderr)  # Safe

Also watch for npx package installation output — by default npx may print progress to stdout when downloading a package. Use npx --quiet or pre-install the package.

9. Verify MCP Initialization

A process that launches cleanly and stays alive still may fail the MCP handshake. The initialize request must receive a valid initialize response before Claude Code considers the connection established. Causes of initialization failure:

  • Server sends malformed JSON-RPC response
  • Server crashes on the first received message
  • Server implements an incompatible protocol version
  • Server returns a valid JSON response that isn't a valid MCP initialization response

The cleanest way to verify MCP initialization independently is MCP Inspector — see that section below.


Fix Remote MCP Servers in Claude Code

1. Inspect the Configured URL and Transport

bash
claude mcp get <server-name>

Verify:

  • URL scheme: https:// not http:// for production endpoints
  • Hostname: no typos, no stale staging hostnames
  • Path: /mcp or /api/mcp — not the homepage /
  • Transport type: http (Streamable HTTP) vs sse (legacy SSE)

Connecting to a homepage that returns HTML instead of an MCP endpoint causes an immediate protocol failure that looks like a connection error.

2. Test Network Reachability

macOS/Linux:

bash
# DNS resolution
nslookup api.example.com

# HTTPS reachability and response
curl -I https://api.example.com/mcp

# With authentication header (replace with actual token)
curl -I -H "Authorization: Bearer YOUR_TOKEN" https://api.example.com/mcp

Windows PowerShell:

powershell
# DNS resolution
Resolve-DnsName api.example.com

# HTTPS reachability
Invoke-WebRequest -Uri https://api.example.com/mcp -Method Head

# TCP connectivity
Test-NetConnection -ComputerName api.example.com -Port 443

3. Inspect the HTTP Response

HTTP ResultLikely FailureNext Step
DNS resolution failureWrong hostname or network issueFix hostname; check DNS
Connection refusedWrong port; server downVerify port; check server status
TLS/SSL errorCertificate mismatch; expired certVerify cert; check server
TimeoutFirewall; server unresponsiveCheck network path; check server
400 Bad RequestMalformed request; wrong transportVerify transport type in configuration
401 UnauthorizedMissing or invalid credentialsAdd/fix authentication credentials
403 ForbiddenValid credentials, insufficient permissionsCheck account permissions
404 Not FoundWrong endpoint pathCorrect the URL path
405 Method Not AllowedWrong HTTP method; wrong transportVerify transport compatibility
429 Too Many RequestsRate limitedBack off; check API quotas
5xx Server ErrorServer-side failureCheck upstream service status

4. Verify Current MCP Transport Support

Claude Code supports Streamable HTTP as the current transport for remote MCP servers. This uses a single HTTP endpoint that supports both request/response and server-sent streaming.

Legacy SSE transport (which used separate GET and POST endpoints) is an older pattern. If a server you are connecting to uses the legacy SSE transport, check current Claude Code documentation to confirm whether it is still supported, as transport support can change across versions.

Transport configuration mismatch — configuring sse for a server that expects Streamable HTTP, or vice versa — causes an initialization failure that looks like a connection error.

5. Verify Authentication

Claude Code supports OAuth and bearer token authentication for remote MCP servers.

  • Missing credentials: The request reaches the server but lacks an Authorization header → HTTP 401
  • Invalid token: Token is set but wrong, expired, or from the wrong issuer → HTTP 401
  • Insufficient permissions: Token is valid but the account lacks access → HTTP 403
  • OAuth flow incomplete: OAuth authorization was started but not completed → server unreachable or 401
  • Expired OAuth token: OAuth access token expired and refresh failed → 401 after initial success

For OAuth-protected servers, Claude Code should initiate the authorization flow automatically. If the browser-based auth page never appeared, or you dismissed it, the credentials were never stored. Refer to current Claude Code documentation for the command to re-initiate authorization for a specific server.

6. Verify MCP Initialization (Remote)

An HTTP endpoint responding with 200 OK does not guarantee a valid MCP session. The server must still complete the MCP initialization handshake over the transport. Test with MCP Inspector to verify that the MCP session initializes and tools appear before blaming Claude Code.


Claude Code MCP Configuration Scopes Explained for Troubleshooting

ScopeWhere It AppliesCommon Connection MistakeHow to Verify
localCurrent project on your machine onlyAdded locally, expected it in CI or a teammate's machineclaude mcp get <name> shows scope: local
projectAll machines using this project via .mcp.jsonCommitted secrets directly; references env vars not set on other machinesInspect .mcp.json at project root
userAll projects for your user accountExpected project-specific server to appear everywhereclaude mcp get <name> shows scope: user

Common scope-related failures:

  • Server works for you (local scope) but a teammate can't connect (they don't have local scope config)
  • Project .mcp.json references MY_API_KEY but the teammate never set that variable
  • User-scope server has a stale configuration from a previous project that no longer applies
  • Two servers with the same name in different scopes — one silently overrides the other

MCP Server Works in Terminal but Fails in Claude Code

This is among the most frequently reported Claude Code MCP issues. The cause is almost always environmental, not a bug in Claude Code or the server.

Works Manually BecauseFails in Claude Code BecauseHow to VerifyFix
Shell PATH includes nvm/pyenv shimsClaude Code doesn't source shell profilecommand -v node in shell vs absolute path checkUse absolute executable path
export MY_KEY=... set in .zshrcClaude Code process doesn't inherit shell envecho ${#MY_KEY} in terminal vs config checkAdd to env block in MCP config
Running from project root with local .envClaude Code uses different working directoryCheck server's file path assumptionsUse absolute paths; load env explicitly
npx downloads and caches package on first runCached in shell, unavailable to Claude Code child processRun with --quiet flag; check cachePre-install with npm install -g or use absolute path
Docker available in PATHDocker daemon socket not accessible from Claude Code environmentdocker info from a subprocessVerify Docker socket permissions
Shell function or alias masks executableClaude Code doesn't execute shell functions/aliasesUse type mycommand — if it's a function, create a wrapper scriptReplace with an actual executable

Use Claude Code Debugging and Logs

Enable MCP-specific debug output by launching Claude Code with the debug flag:

bash
claude --mcp-debug

This produces verbose output including MCP connection events, initialization messages, and error details. Run your failing session and capture the output.

For general debug mode:

bash
claude --debug

Check current Anthropic Claude Code documentation for the exact supported flags in your installed version — flag names can change across releases.

What to look for in debug output:

  • spawn errors or ENOENT — executable resolution failure
  • Process exit code on launch — non-zero means startup failure
  • stderr content captured from the child process — shows server-side errors
  • Transport establishment failure — protocol negotiation errors
  • initialize request/response — missing or malformed response causes initialization failure
  • Authentication error messages — HTTP status or OAuth error descriptions
  • tools/list response — empty or error here explains missing tools

If official documentation does not currently specify a stable log file path for MCP events on your OS, rely on --mcp-debug output rather than searching for log files that may not exist or change location across versions.


Test the Server Independently with MCP Inspector

MCP Inspector is the official tool for testing MCP server behavior independently of any client. Use it to isolate whether the failure is in the server itself or in how Claude Code connects.

bash
# Install and run Inspector against a stdio server
npx @modelcontextprotocol/inspector npx -y @my-org/mcp-server

# With environment variables
npx @modelcontextprotocol/inspector \
  -e MY_API_KEY=$MY_API_KEY \
  npx -y @my-org/mcp-server

# Against a remote HTTP server
npx @modelcontextprotocol/inspector \
  --cli https://api.example.com/mcp \
  --header "Authorization: Bearer $MY_TOKEN"

Use the current @modelcontextprotocol/inspector documentation for up-to-date flags — the CLI interface evolves alongside the SDK.

Interpreting Inspector results:

Inspector ResultWhat It MeansNext Step
Inspector can't start the serverServer startup fails independently of Claude CodeFix server installation or configuration
Process starts, initialization failsServer-side MCP implementation issueFix server code or update server
Initializes, but no tools listedServer exposes no tools, or tool registration failsFix server tool registration
Inspector succeeds, Claude Code failsClaude Code environment or configuration differenceCompare launch environments; check scope and auth
Both Inspector and Claude Code failServer-side issueFix server
Inspector connects and tools appearServer is functionalInvestigate Claude Code configuration, scope, environment

Important: Inspector success proves the server is functional when launched with those specific arguments and environment variables. It does not prove Claude Code can launch it identically — PATH, environment, and working directory may still differ.

For a deeper dive into validating your MCP server implementation before connecting it to any client, use the MCPForge Verify tool to run automated capability and protocol conformance checks.


Claude Code MCP Authentication Errors

Authentication failures look similar to connection failures but have distinct causes:

SymptomMost Likely CauseVerificationFix
HTTP 401, no prior authMissing Authorization headercurl -I <endpoint> with no authAdd credentials to env configuration
HTTP 401 despite credentials setWrong variable name; empty value; expired tokenPrint token length; verify nameFix variable name; refresh token
HTTP 403Token valid, insufficient permissionCheck API key scopes in provider dashboardUpdate key permissions or use correct key
OAuth page never appearedOAuth flow not triggeredCheck server type; check Claude Code OAuth supportFollow OAuth flow; check documentation
Was authenticated, now 401Token expired; OAuth token not refreshedCheck token expiry; check refresh behaviorRe-authorize; generate new token
No auth header expected but 401Proxy or gateway adding auth requirementCurl directly and via proxyConfigure proxy auth or bypass

For OAuth servers, Claude Code handles the authorization flow automatically when the server implements OAuth 2.0 metadata discovery correctly. If authorization was never completed, or the authorization server is unreachable, the connection will fail at the authentication stage.


Claude Code Connects to MCP Server but Tools Do Not Appear

A connected server with no visible tools is not a connection failure — it is a capability discovery issue.

Verify connection first:

bash
claude mcp list
# Confirm the server shows a connected status, not disconnected

Then investigate tool discovery:

  • Server exposes no tools: The server may be a resource-only server, or tool registration failed silently. Test with MCP Inspector — if tools/list returns an empty array, the server itself has no tools registered.
  • Authorization required for tools: Some servers require per-tool authorization or scope-gated tools. A connected session may not have sufficient permissions to list all tools.
  • Tool count limits: Very large tool sets may be subject to limits in Claude Code's context window. If a server exposes dozens or hundreds of tools, some may not appear.
  • Deferred tool loading: Check current Claude Code documentation for any deferred or on-demand tool loading behavior, as this may affect which tools appear by default.

If tools/list via MCP Inspector returns tools but Claude Code doesn't show them, this is worth reporting with a minimal reproduction — see the bug report checklist below.


MCP Failed to Connect After Claude Code Update

Don't assume a regression without evidence. Follow this workflow:

  1. Record the exact Claude Code version where the failure occurs: claude --version
  2. Identify when it stopped working — was it immediately after an update?
  3. Check whether the MCP server or its dependencies also changed — correlation is not causation
  4. Review the Claude Code changelog for the installed version for any MCP-related changes
  5. Test the server independently with MCP Inspector — if it also fails there, it's not a Claude Code regression
  6. Compare in another environment — does it fail on a colleague's machine with the same Claude Code version?
  7. Create a minimal reproduction — one server, minimum configuration, verified failure

A genuine regression requires evidence that: (a) nothing changed except Claude Code, (b) the server works independently, and (c) the failure is reproducible across environments.


MCP Server Worked Before but Fails Now

When a previously-working configuration breaks, these are the most common causes:

  • Expired credentials: API keys, tokens, or OAuth access tokens expired
  • Changed environment variables: Variable renamed, removed, or rotated
  • Dependency update: npx pulled a new package version with a breaking change
  • Executable path change: Node.js, Python, or tool updated and path changed
  • Project moved: Absolute paths or working directory assumptions now wrong
  • Configuration scope change: Server accidentally re-added to a different scope
  • Server deployment change: Remote server endpoint, auth method, or transport changed
  • Protocol version change: Server updated to newer MCP protocol; Claude Code version mismatch
  • Upstream outage: Remote server temporarily unavailable

Quick regression checklist:

  • Verify credentials not expired
  • Run claude mcp get <name> — compare with known-good configuration
  • Check dependency versions with npm list <package> or pip show <package>
  • Verify executable still at same path: which node, which python3
  • For remote servers: curl the endpoint and check response
  • Check whether any other configuration files changed recently

Windows-Specific Claude Code MCP Fixes

powershell
# Find exact executable path
Get-Command npx | Select-Object -ExpandProperty Source
Get-Command node | Select-Object -ExpandProperty Source
Get-Command python | Select-Object -ExpandProperty Source
Get-Command uvx | Select-Object -ExpandProperty Source

# Check if environment variable is set
if ($env:MY_API_KEY) { Write-Output "Set (length: $($env:MY_API_KEY.Length))" } else { Write-Output "Not set" }

# Test DNS
Resolve-DnsName api.example.com

# Test TCP
Test-NetConnection -ComputerName api.example.com -Port 443

# Capture stderr from a process
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = "node"
$pinfo.Arguments = "C:\path\to\server.js"
$pinfo.RedirectStandardError = $true
$pinfo.UseShellExecute = $false
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit(5000) | Out-Null
$p.StandardError.ReadToEnd()

Windows-specific issues:

  • JSON path escaping: Backslashes in paths must be doubled in JSON: C:\\Users\\name\\server.js
  • Spaces in paths: Use forward slashes or escaped paths, never bare spaces in path strings
  • npm global installs: Often in %APPDATA%\npm — not always in system PATH for child processes
  • Python launcher: py launcher may resolve differently than python or python3; use the absolute path from Get-Command python
  • WSL boundaries: A server installed inside WSL is not directly available to Claude Code running on Windows unless WSL interop is configured
  • uv/uvx: If installed via cargo or the standalone installer, verify it's in the system PATH rather than only the user shell PATH

macOS and Linux Claude Code MCP Fixes

bash
# Verify executable resolution
command -v npx
command -v node
command -v python3
command -v uvx

# Full PATH in current shell
echo $PATH

# Check executable permissions
ls -la /path/to/server/index.js
chmod +x /path/to/server/index.js  # Only if it should be executable

# Check current working directory
pwd

# Capture stderr and exit code
node /path/to/server.js 2>/tmp/server-err.txt; echo "Exit: $?"
cat /tmp/server-err.txt

# DNS check
nslookup api.example.com

# HTTP response including headers
curl -sv https://api.example.com/mcp 2>&1 | head -50

macOS-specific issues:

  • Homebrew PATH: /opt/homebrew/bin (Apple Silicon) or /usr/local/bin (Intel) — may not be in Claude Code's PATH
  • nvm: Manages Node.js versions by manipulating PATH in shell profile — not available in non-shell child processes; use the absolute path from ~/.nvm/versions/node/vX.Y.Z/bin/node
  • pyenv: Same issue — shell shims in ~/.pyenv/shims may not resolve; use absolute Python path
  • Shell differences: macOS defaults to zsh; startup files are .zshrc and .zprofile; non-interactive processes don't source these files

Minimal Claude Code MCP Reproduction

For local stdio servers

  1. claude --version — record the exact version
  2. claude mcp get <name> — record exact configuration
  3. If multiple servers, disable all others temporarily; test one server
  4. Strip configuration to minimum: only required command, args, and env vars
  5. Run the exact command with the exact arguments in your terminal
  6. Capture stderr: your-command 2>/tmp/err.txt; echo "Exit: $?"; cat /tmp/err.txt
  7. npx @modelcontextprotocol/inspector <command> <args> — verify MCP behavior independently
  8. Start Claude Code with --mcp-debug and attempt connection
  9. Compare the point where terminal run succeeds but Claude Code fails
  10. Record the exact first stage where behavior diverges

For remote servers

  1. claude mcp get <name> — record exact URL, transport, and auth method
  2. nslookup <hostname> — verify DNS resolves
  3. curl -I <url> — verify HTTP response
  4. curl -I -H "Authorization: Bearer $TOKEN" <url> — verify authenticated response
  5. npx @modelcontextprotocol/inspector --cli <url> --header "Authorization: Bearer $TOKEN" — verify MCP session
  6. Start Claude Code with --mcp-debug and attempt connection
  7. Compare Inspector behavior with Claude Code behavior
  8. Record the exact first stage where behavior diverges

What each step proves: A successful manual server launch proves the process can start. A successful Inspector session proves the MCP protocol works. A failure only in Claude Code proves the issue is in how Claude Code launches or configures the session — not in the server itself.


What to Collect Before Reporting a Claude Code MCP Bug

Before opening a GitHub issue or community thread:

  • claude --version output
  • Operating system and version
  • MCP server name and version (or commit hash)
  • stdio or remote HTTP
  • Transport type
  • Configuration scope
  • Sanitized configuration (no API keys, tokens, URLs with embedded credentials, or personal data)
  • Exact command and arguments
  • First error message, exactly as shown
  • Process exit code
  • Relevant stderr output
  • HTTP status code (remote servers)
  • Authentication method used (not the credentials themselves)
  • Whether MCP Inspector reproduces the failure
  • Minimal reproduction steps
  • What changed recently (package updates, Claude Code update, configuration change)
  • Expected behavior
  • Actual behavior

Before sharing: Remove all API keys, bearer tokens, OAuth tokens, passwords, private endpoint URLs, personal data, and any other secrets. Inspect every config field and environment variable reference.


Prevention: Avoiding Future MCP Connection Failures

  • Always use absolute paths for executables and file references in MCP configuration
  • Always pass required environment variables explicitly in the env block — never rely on shell inheritance
  • Never write to stdout in stdio server implementations — use stderr for all logging
  • Pre-install MCP server packages rather than relying on npx to download them at connection time
  • Store secrets outside committed configuration — use environment variables in project .mcp.json, not hardcoded values
  • Test each server with MCP Inspector before connecting it to Claude Code for the first time
  • Pin MCP server versions in production to avoid unexpected breaking changes from package updates
  • Validate your MCP server's protocol conformance before deploying — the MCPForge Verify tool can catch implementation issues that only surface when a client connects
  • Read the production deployment guide if you are running MCP servers at scale — Running MCP in Production covers stability, monitoring, and environment management that directly reduces connection failure rates

References

Frequently Asked Questions

Why does Claude Code say MCP failed to connect?

The failure can happen at multiple stages: configuration loading, process launch, transport establishment, authentication, or MCP protocol initialization. The message itself doesn't tell you which stage failed. Start with `claude mcp list` to see status, then identify whether the server is local stdio or remote HTTP — each has a distinct diagnostic path.

How do I check MCP server status in Claude Code?

Run `claude mcp list` to see all configured MCP servers and their connection status. Run `claude mcp get <server-name>` to inspect the exact configuration of a specific server including its command, arguments, environment, and scope.

How do I see which MCP servers are configured in Claude Code?

Run `claude mcp list` from any terminal. This shows all servers across all configuration scopes (local, project, user). To see where a server is defined and its full configuration, run `claude mcp get <server-name>`.

Why does my MCP server work in the terminal but fail in Claude Code?

Claude Code launches the server as a child process with its own environment — it does not inherit your interactive shell's PATH, environment variables, or working directory context. An executable available in your shell may not be resolvable from the Claude Code process. Use absolute paths or verify the executable resolves in the Claude Code environment.

How do I debug an MCP server in Claude Code?

Run Claude Code with `--debug` or `--mcp-debug` flag to enable verbose output that includes MCP-specific connection and initialization diagnostics. Check the official Anthropic Claude Code documentation for the current supported flags, as they may change across versions.

Can PATH or environment variables cause Claude Code MCP connection failures?

Yes — this is one of the most common causes. Claude Code launches the server process without the interactive shell environment. Any executable found via shell PATH configuration (e.g., nvm, pyenv, Homebrew, or user-level npm installs) may not be available. Set absolute paths in the configuration or explicitly pass required environment variables in the MCP server configuration.

How do I fix authentication errors for remote MCP servers in Claude Code?

First verify the endpoint is reachable and returns the correct HTTP status. HTTP 401 means credentials are missing or invalid. HTTP 403 means credentials were accepted but the account lacks permission. For OAuth servers, Claude Code should initiate an OAuth flow — check whether authorization was completed. For API key servers, verify the key is correctly set in the environment or configuration.

Why does MCP Inspector connect when Claude Code does not?

Inspector and Claude Code may launch the server with different environments, working directories, or arguments. If Inspector connects successfully, the server itself is functional — the issue is how Claude Code launches or configures it. Compare the exact command, arguments, working directory, and environment variables used by each tool.

Why is my MCP server connected but its tools are missing?

A successful connection doesn't guarantee tool discovery. The server may expose no tools, tool registration may require authorization, or Claude Code may have a tool-count limit in context. Verify the server is actually connected (not just listed), then check whether `tools/list` returns tools when called independently via MCP Inspector.

Should I remove and re-add the MCP server to fix a connection failure?

Only as a last resort after verifying the configuration is actually wrong. Removing and re-adding without diagnosing means you may reintroduce the same broken configuration. Always inspect the current configuration first with `claude mcp get <name>` before making changes.

How do I report a reproducible Claude Code MCP bug?

Collect: Claude Code version, OS, server name/version, transport type, scope, sanitized configuration, exact error message, stderr output, exit code, and whether MCP Inspector reproduces the failure. Create a minimal reproduction with one server and the fewest environment variables needed. Strip all secrets, tokens, and credentials before sharing.

Check your MCP security posture

Generate a Security Score, detect risky tools, and review permissions before exposing APIs to AI agents.