You ran Claude Code this morning, and the MCP server that worked perfectly yesterday is now showing "failed" — no tools, no connection, no clear explanation. If you've hit this wall before, you know how frustrating it is to debug something that "just worked" until it didn't.
I've been there. Running five MCP servers in parallel, one update caused them all to drop simultaneously. I spent most of the day chasing the issue before realizing the root cause was a single missing environment variable. That experience is why I put together this diagnosis guide — not a list of possible fixes, but a step-by-step process for narrowing down the actual cause.
Step 1: Check Server Status with /mcp
Start by typing /mcp in Claude Code's terminal session. This lists all configured MCP servers and their current connection state.
/mcp
You'll see one of three states:
- connected — working normally
- connecting — still initializing (wait a few seconds and check again)
- failed — connection failed (this is what we're diagnosing)
If you see all servers as failed at once, jump to Step 5 (restart) first — a stale process is likely the culprit. If only specific servers are failing, note which ones and continue to Step 2.
Step 2: Read the stderr Logs for Actual Error Messages
The most reliable source of truth when an MCP server fails is its stderr output. Claude Code captures this from the server process and writes it to internal logs. This is where the specific error message lives.
More on reading MCP server stderr logs in Claude Code
To access the logs:
# macOS / Linux
cat ~/.claude/logs/mcp-*.log 2>/dev/null | tail -100
# Or launch Claude Code in debug mode for real-time output
claude --debugDebug mode streams server startup events, connection attempts, and error messages as they happen. Look for these patterns:
ENOENT— executable not found (path problem)ECONNREFUSED— nothing is listening on that port401 Unauthorized— auth token invalid or expiredSyntaxError— your config file has a JSON errorMODULE_NOT_FOUND— Node.js dependency missing (forgotnpm install)
Each of these points to a different fix, so identifying the keyword in the log is the fastest path forward.
Step 3: Validate Your Config File Syntax
MCP servers are configured in ~/.claude.json (CLI) or ~/.claude/claude_desktop_config.json (Claude desktop app). JSON is unforgiving — a single trailing comma or mismatched bracket breaks the entire file silently.
# Check CLI config
cat ~/.claude.json | jq . > /dev/null && echo "✅ JSON syntax OK" || echo "❌ Syntax error"
# Check desktop app config
cat ~/.claude/claude_desktop_config.json | jq . > /dev/null && echo "✅ OK" || echo "❌ Error"When there's an error, jq tells you the exact line and character position. The most common mistake is a trailing comma after the last property:
// ❌ Trailing comma — will break silently
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["server.js"],
}
}
}
// ✅ Correct — no trailing comma
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["server.js"]
}
}
}If you edit configs frequently, consider setting up a pre-save JSON lint check in your editor to catch this before it causes a problem.
Step 4: Check Auth Tokens and Environment Variables
MCP servers that call external APIs (GitHub, Linear, Slack, etc.) depend on auth tokens being available at startup. If a token expired or an environment variable isn't loading, the server starts but immediately fails to authenticate.
# Verify the environment variables are set in your current shell
echo $GITHUB_TOKEN
echo $ANTHROPIC_API_KEY
# Check if they're defined in your shell config
grep -n "GITHUB_TOKEN\|ANTHROPIC_API_KEY" ~/.zshrc ~/.bashrc 2>/dev/nullIf the variables are empty, Claude Code may not be inheriting them from your shell — especially on macOS where GUI-launched apps don't always source .zshrc. The most reliable fix is to pass them explicitly in the config's env field:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxxxxxxxxxxxxxxxxxx"
}
}
}
}Note: writing tokens directly into config files is a security risk. For production use, refer to Claude Code's environment variable configuration guide for safer approaches.
Step 5: Restart Claude Code and the MCP Servers
Sometimes the issue is simply a stale connection or zombie process. Long-running Claude Code sessions can accumulate disconnected MCP processes that hold onto ports without actually serving requests.
# Exit Claude Code cleanly, then check for leftover processes
ps aux | grep claude | grep -v grep
# Kill any remaining Claude Code processes
pkill -f "claude" 2>/dev/null
# Restart
claudeAfter restarting, run /mcp again to confirm the connection state. A clean restart resolves a surprising number of "inexplicably broken" MCP issues.
Quick Reference: Common Causes and Commands
Missing Node.js modules (MODULE_NOT_FOUND)
You cloned or updated an MCP server repo but didn't run npm install:
cd /path/to/your/mcp-server
npm installStale npx cache
If you use npx to run @modelcontextprotocol/server-* packages, an outdated cache can pin an old version that's incompatible with your current Claude Code:
npx clear-npx-cache 2>/dev/null || npm cache clean --forcePort conflict (HTTP-based MCP servers)
If your server runs over HTTP and another process already owns that port:
# Check what's on port 3000
lsof -i :3000
# Free it
kill $(lsof -ti :3000)When Nothing Works
If you've gone through all five steps and the server is still failing, the most reliable next move is to temporarily empty your MCP config and add servers back one by one. This isolates which server (or combination of servers) is causing the problem.
For more complex scenarios — OAuth flows, server-side timeout tuning, multi-server orchestration — Claude Code MCP advanced troubleshooting covers the deeper edge cases.
Most MCP failures come down to three things: a config file syntax error, a missing or expired environment variable, or a stale process. Start with the stderr log — that single step eliminates guesswork and gets you to the actual fix faster than anything else.