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:
- Run
claude mcp list— see every configured server and its current status - Run
claude mcp get <name>— inspect the exact configuration for the failing server - Identify whether it's a local stdio server or a remote HTTP server
- stdio: Run the exact configured command in your terminal; inspect stderr and exit code
- stdio: Compare PATH, environment variables, and working directory between your terminal and the Claude Code process
- Remote: Verify the URL, HTTP response, transport type, and authentication
- Enable debug logging via
claude --mcp-debugto capture Claude Code-side diagnostics - Test independently with MCP Inspector to isolate server failures from Claude Code-specific behavior
- 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) orGet-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-debugand 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 Symptom | Start Here |
|---|---|
| Server not listed after adding it | Check the Claude Code MCP Configuration |
| Server listed but shows disconnected | Identify Which MCP Server Failed |
command not found or spawn ENOENT | Verify Executable Resolution |
| Server exits immediately (non-zero exit code) | Check Immediate Process Exit and stderr |
| Server works in terminal but fails in Claude Code | MCP Server Works in Terminal but Fails in Claude Code |
| Missing environment variable error in stderr | Verify Environment Variables |
| HTTP 401 from remote server | Verify Authentication |
| HTTP 403 from remote server | Verify Authentication |
| HTTP 404 from remote server | Inspect the Configured URL and Transport |
| Connection refused | Test Network Reachability |
| Timeout connecting to remote server | Test Network Reachability |
| MCP initialization failure | Verify MCP Initialization (stdio) |
| Malformed protocol / JSON parse error | Check stdout Contamination |
| Server connects but tools don't appear | Connected but Tools Do Not Appear |
| MCP Inspector works, Claude Code fails | Test the Server Independently with MCP Inspector |
| Authentication error on remote server | Claude Code MCP Authentication Errors |
| Was working before, now fails | MCP Server Worked Before but Fails Now |
| Failure started after Claude Code update | MCP 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
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:
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:
stdiomeans a local process;httporssemeans a remote endpoint - Scope:
local,project, oruser— 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.
- Claude Code loads MCP configuration from all applicable scopes
- Scope precedence resolves conflicts between local, project, and user configuration
- For stdio servers: Claude Code spawns the configured process as a child
- For remote servers: Claude Code opens an HTTP connection to the configured URL
- Transport is established (stdio pipe or HTTP stream)
- Authentication occurs when required (bearer tokens, OAuth)
- MCP initialization handshake completes (
initialize/initialized) tools/listand capability discovery complete- The connection is maintained for the session
| Failure Stage | Claude Code Symptom | How to Verify | What to Fix |
|---|---|---|---|
| Configuration loading | Server missing from claude mcp list | Check scope; run claude mcp get <name> | Re-add with correct scope |
| Process launch | Disconnected immediately; spawn error | Run command manually; check PATH | Fix executable path or install dependency |
| Transport establishment | Process running but no response | Check stdout contamination; check stderr | Fix non-protocol stdout output |
| Authentication | HTTP 401/403; OAuth failure | Inspect credentials; curl the endpoint | Fix credentials or re-authorize |
| MCP initialization | Connected but tools missing; protocol error | Test with MCP Inspector | Fix server implementation or version mismatch |
| Capability discovery | Connected, no tools shown | Test tools/list via Inspector | Fix server's tool registration |
| Session maintenance | Was connected, then dropped | Check server logs; check process health | Fix 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
| Scope | Where it applies | How to add |
|---|---|---|
| Local | Current project only, not committed | claude mcp add --scope local <name> ... |
| Project | All users of the project via .mcp.json | claude mcp add --scope project <name> ... |
| User | All projects for the current user | claude 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
userscope but expected it in a specific project, or vice versa - Stale configuration: Old broken entry from a previous
claude mcp addattempt - 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:
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
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:
# 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 see | What it means |
|---|---|
command not found | Executable not in PATH or not installed |
| Process exits immediately with code > 0 | Startup error — check stderr |
ModuleNotFoundError / Cannot find module | Missing dependency |
Error: ENOENT | File or executable path doesn't exist |
| Process stays alive, no output | Likely waiting for stdio input — this is normal |
| Process outputs non-JSON text | stdout 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:
# 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:
# 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:
# 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:
// 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:
{
"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:
# 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"
# Windows PowerShell — check if set
if ($env:MY_API_KEY) { "set" } else { "not set" }
In Claude Code MCP configuration, pass required environment variables explicitly:
{
"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:
# 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: $?"
# 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:
// This breaks the stdio MCP stream
console.log('Server starting...');
console.log('Connected to database');
Correct — always use stderr for logging:
// Safe: stderr does not interfere with stdio MCP protocol
console.error('Server starting...');
process.stderr.write('Connected to database\n');
Broken Python:
print("Server starting...") # Breaks stdout stream
Correct 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
claude mcp get <server-name>
Verify:
- URL scheme:
https://nothttp://for production endpoints - Hostname: no typos, no stale staging hostnames
- Path:
/mcpor/api/mcp— not the homepage/ - Transport type:
http(Streamable HTTP) vssse(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:
# 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:
# 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 Result | Likely Failure | Next Step |
|---|---|---|
| DNS resolution failure | Wrong hostname or network issue | Fix hostname; check DNS |
| Connection refused | Wrong port; server down | Verify port; check server status |
| TLS/SSL error | Certificate mismatch; expired cert | Verify cert; check server |
| Timeout | Firewall; server unresponsive | Check network path; check server |
| 400 Bad Request | Malformed request; wrong transport | Verify transport type in configuration |
| 401 Unauthorized | Missing or invalid credentials | Add/fix authentication credentials |
| 403 Forbidden | Valid credentials, insufficient permissions | Check account permissions |
| 404 Not Found | Wrong endpoint path | Correct the URL path |
| 405 Method Not Allowed | Wrong HTTP method; wrong transport | Verify transport compatibility |
| 429 Too Many Requests | Rate limited | Back off; check API quotas |
| 5xx Server Error | Server-side failure | Check 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
Authorizationheader → 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
| Scope | Where It Applies | Common Connection Mistake | How to Verify |
|---|---|---|---|
| local | Current project on your machine only | Added locally, expected it in CI or a teammate's machine | claude mcp get <name> shows scope: local |
| project | All machines using this project via .mcp.json | Committed secrets directly; references env vars not set on other machines | Inspect .mcp.json at project root |
| user | All projects for your user account | Expected project-specific server to appear everywhere | claude 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.jsonreferencesMY_API_KEYbut 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 Because | Fails in Claude Code Because | How to Verify | Fix |
|---|---|---|---|
| Shell PATH includes nvm/pyenv shims | Claude Code doesn't source shell profile | command -v node in shell vs absolute path check | Use absolute executable path |
export MY_KEY=... set in .zshrc | Claude Code process doesn't inherit shell env | echo ${#MY_KEY} in terminal vs config check | Add to env block in MCP config |
Running from project root with local .env | Claude Code uses different working directory | Check server's file path assumptions | Use absolute paths; load env explicitly |
npx downloads and caches package on first run | Cached in shell, unavailable to Claude Code child process | Run with --quiet flag; check cache | Pre-install with npm install -g or use absolute path |
| Docker available in PATH | Docker daemon socket not accessible from Claude Code environment | docker info from a subprocess | Verify Docker socket permissions |
| Shell function or alias masks executable | Claude Code doesn't execute shell functions/aliases | Use type mycommand — if it's a function, create a wrapper script | Replace with an actual executable |
Use Claude Code Debugging and Logs
Enable MCP-specific debug output by launching Claude Code with the debug flag:
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:
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:
spawnerrors orENOENT— 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
initializerequest/response — missing or malformed response causes initialization failure- Authentication error messages — HTTP status or OAuth error descriptions
tools/listresponse — 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.
# 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 Result | What It Means | Next Step |
|---|---|---|
| Inspector can't start the server | Server startup fails independently of Claude Code | Fix server installation or configuration |
| Process starts, initialization fails | Server-side MCP implementation issue | Fix server code or update server |
| Initializes, but no tools listed | Server exposes no tools, or tool registration fails | Fix server tool registration |
| Inspector succeeds, Claude Code fails | Claude Code environment or configuration difference | Compare launch environments; check scope and auth |
| Both Inspector and Claude Code fail | Server-side issue | Fix server |
| Inspector connects and tools appear | Server is functional | Investigate 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:
| Symptom | Most Likely Cause | Verification | Fix |
|---|---|---|---|
| HTTP 401, no prior auth | Missing Authorization header | curl -I <endpoint> with no auth | Add credentials to env configuration |
| HTTP 401 despite credentials set | Wrong variable name; empty value; expired token | Print token length; verify name | Fix variable name; refresh token |
| HTTP 403 | Token valid, insufficient permission | Check API key scopes in provider dashboard | Update key permissions or use correct key |
| OAuth page never appeared | OAuth flow not triggered | Check server type; check Claude Code OAuth support | Follow OAuth flow; check documentation |
| Was authenticated, now 401 | Token expired; OAuth token not refreshed | Check token expiry; check refresh behavior | Re-authorize; generate new token |
| No auth header expected but 401 | Proxy or gateway adding auth requirement | Curl directly and via proxy | Configure 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:
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/listreturns 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:
- Record the exact Claude Code version where the failure occurs:
claude --version - Identify when it stopped working — was it immediately after an update?
- Check whether the MCP server or its dependencies also changed — correlation is not causation
- Review the Claude Code changelog for the installed version for any MCP-related changes
- Test the server independently with MCP Inspector — if it also fails there, it's not a Claude Code regression
- Compare in another environment — does it fail on a colleague's machine with the same Claude Code version?
- 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:
npxpulled 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>orpip 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
# 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:
pylauncher may resolve differently thanpythonorpython3; use the absolute path fromGet-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
cargoor the standalone installer, verify it's in the system PATH rather than only the user shell PATH
macOS and Linux Claude Code MCP Fixes
# 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/shimsmay not resolve; use absolute Python path - Shell differences: macOS defaults to
zsh; startup files are.zshrcand.zprofile; non-interactive processes don't source these files
Minimal Claude Code MCP Reproduction
For local stdio servers
claude --version— record the exact versionclaude mcp get <name>— record exact configuration- If multiple servers, disable all others temporarily; test one server
- Strip configuration to minimum: only required command, args, and env vars
- Run the exact command with the exact arguments in your terminal
- Capture stderr:
your-command 2>/tmp/err.txt; echo "Exit: $?"; cat /tmp/err.txt npx @modelcontextprotocol/inspector <command> <args>— verify MCP behavior independently- Start Claude Code with
--mcp-debugand attempt connection - Compare the point where terminal run succeeds but Claude Code fails
- Record the exact first stage where behavior diverges
For remote servers
claude mcp get <name>— record exact URL, transport, and auth methodnslookup <hostname>— verify DNS resolvescurl -I <url>— verify HTTP responsecurl -I -H "Authorization: Bearer $TOKEN" <url>— verify authenticated responsenpx @modelcontextprotocol/inspector --cli <url> --header "Authorization: Bearer $TOKEN"— verify MCP session- Start Claude Code with
--mcp-debugand attempt connection - Compare Inspector behavior with Claude Code behavior
- 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 --versionoutput - 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
envblock — 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
npxto 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