How to Debug an MCP Server
Start here: read the server's log file at ~/Library/Logs/Claude/mcp-server-SERVERNAME.log (macOS). This is the single most useful debugging step — it contains the server's actual output and error messages, which are almost always more informative than anything the Claude UI shows. Then, if needed, test the server directly with MCP Inspector.
In this guide
Step 1 — find and read the logs
Every MCP server in Claude Desktop writes its output to a dedicated log file. These are the most useful debugging artifact available.
# macOS - list all MCP logs ls ~/Library/Logs/Claude/mcp*.log # macOS - follow a specific server log in real time tail -f ~/Library/Logs/Claude/mcp-server-filesystem.log # Windows (PowerShell) ls "$env:APPDATA\Claude\logs\mcp*.log" Get-Content "$env:APPDATA\Claude\logs\mcp-server-filesystem.log" -Tail 50 -Wait # Linux ls ~/.config/Claude/logs/mcp*.log tail -f ~/.config/Claude/logs/mcp-server-filesystem.log
The log file name corresponds to the server key in your mcpServers config. If you named the server "myserver", the log is mcp-server-myserver.log.
Step 2 — interpret error patterns
| Error pattern in log | Cause | Fix |
|---|---|---|
spawn ENOENT | Binary not found | Use absolute path from which npx. See spawn ENOENT guide |
EACCES | Permission denied | Check chmod on the file/dir; on macOS check System Preferences → Privacy → Full Disk Access |
MODULE_NOT_FOUND | npm package missing | Run the server command manually in terminal to trigger install |
ModuleNotFoundError | Python package missing | Run uvx mcp-server-NAME manually; or uv pip install package-name |
ECONNREFUSED | External service not running | Test the connection directly: psql URL, redis-cli ping, etc. |
HTTP 401 | Invalid or missing credentials | Check env block in config; verify the token has not expired |
HTTP 403 | Insufficient permissions | Check the token's permission scopes (e.g. GitHub PAT needs repo scope) |
| Python traceback | Server code crashed | Read the last line of the traceback for the root cause; check for missing env vars |
| Process exited with code 1 | Server crashed immediately | Scroll up in the log to find the error before the exit |
| No output / empty log | Server started then hung | Run the command manually; may be waiting for stdin input or a slow network call |
Step 3 — test the server manually
Run the exact command from your config directly in a terminal. This bypasses Claude Desktop and shows you the raw server output without any filtering:
# Run the server directly (use the same command and args as in your config) /usr/local/bin/npx -y @modelcontextprotocol/server-filesystem /Users/you/projects # For Python/uvx servers /Users/you/.local/bin/uvx mcp-server-git --repository /Users/you/myrepo
A healthy server will start and then wait quietly for input (it speaks MCP over stdio). An error will print immediately. This confirms whether the problem is in the server itself or in how Claude Desktop is invoking it.
If the server errors here, fix the underlying issue first — there is no point debugging the Claude Desktop integration until the server runs cleanly on its own.
Step 4 — use MCP Inspector
MCP Inspector is the official interactive testing tool for MCP servers. It sends real MCP protocol messages and shows the JSON responses:
# Install and run in one command npx @modelcontextprotocol/inspector /usr/local/bin/npx -y @modelcontextprotocol/server-filesystem /tmp # For uvx servers npx @modelcontextprotocol/inspector /Users/you/.local/bin/uvx mcp-server-git --repository /tmp/test
Inspector opens a browser UI (usually at http://localhost:5173). From there you can:
- Complete the MCP initialize handshake
- Call
tools/listto see what tools the server exposes - Call
tools/callwith specific arguments to test individual tools - See the raw JSON request and response for each call
This is the fastest way to verify a server is working correctly without involving Claude Desktop at all.
Live health check: the MCP Server Health Check on hatchloop.dev sends a real MCP initialize + tools/list to any server endpoint and shows the response time and tool list. Useful for HTTP/SSE transport servers.
Step 5 — check the environment
Many MCP servers fail because they have different environment variables in Claude Desktop vs your terminal. To debug this, add temporary verbose logging to the server command:
# Add env inspection to a wrapper script (macOS/Linux) # Create /tmp/mcp-debug.sh: #!/bin/bash echo "PATH=$PATH" >> /tmp/mcp-env.log echo "HOME=$HOME" >> /tmp/mcp-env.log env >> /tmp/mcp-env.log exec /usr/local/bin/npx -y @modelcontextprotocol/server-filesystem "$@"
Or compare the environment directly: set "command": "/usr/bin/env" and "args": ["bash", "-c", "env > /tmp/mcp-env.log && exec /usr/local/bin/npx ..."] temporarily in your config to log the full environment that Claude Desktop provides.
What to look for in the env diff between terminal and Claude Desktop:
- Missing
PATHentries (the core reason for spawn ENOENT) - Missing
HOME(some servers use it to locate config files) - Missing API key env vars (if you set them in shell profile instead of the MCP config's
envblock)
Step 6 — isolate to one server
If multiple servers are failing, isolate the problem by temporarily reducing your config to a single server:
{
"mcpServers": {
"filesystem": {
"command": "/usr/local/bin/npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
}
}
}
If this works, add servers back one at a time until you find which one is causing the problem. One failing server with a bad startup should not prevent others from working, but config JSON errors or PATH issues can sometimes cascade.
FAQ
macOS: ~/Library/Logs/Claude/mcp-server-SERVERNAME.log
Windows: %APPDATA%\Claude\logs\mcp-server-SERVERNAME.log
Linux: ~/.config/Claude/logs/mcp-server-SERVERNAME.log
The SERVERNAME matches the key in your mcpServers config object.
Run the server command directly in a terminal. Or use MCP Inspector: npx @modelcontextprotocol/inspector /path/to/npx -y package-name args.... Inspector opens a browser UI for sending MCP protocol messages interactively.
spawn ENOENT: binary not found — use absolute path. EACCES: permission denied. MODULE_NOT_FOUND: npm package missing — run command manually. ECONNREFUSED: external service not running. HTTP 401: bad credentials. Python traceback: server crashed — read the last line for the cause.
MCP Inspector is an official Anthropic testing tool. Run: npx @modelcontextprotocol/inspector COMMAND ARG1 ARG2. It opens a browser UI where you can send real MCP protocol messages (initialize, tools/list, tools/call) and see the raw JSON responses. The fastest way to verify a server works correctly without Claude Desktop.