Fix Claude Desktop MCP Server Not Connecting: Manual JSON Configuration
Quick Answer
- Root cause: Most connection failures stem from JSON syntax errors (trailing commas), relative paths, or the server executable not being found.
- First checks: Validate your
claude_desktop_config.jsonwith a JSON validator, ensure all paths are absolute, and fully quit Claude Desktop (Cmd+Q) before restarting. - Minimal fix: Use the exact JSON structure with
command,args(absolute paths only), and optionalenvfields. Never use relative paths like./server.py. - Environment: This applies to Claude Desktop on macOS/Windows when manually configuring MCP servers via the
mcpServersJSON block.
What Problem It Solves
When Claude Desktop fails to connect to a custom MCP server, the issue is almost always in how the server is configured in claude_desktop_config.json. This guide helps you diagnose and fix connection failures by ensuring correct JSON structure, absolute paths, and proper environment variable handling.
Unlike .mcpb one-click installations, manual JSON configuration gives you full control over server startup parameters, environment variables, and execution paths—but it also introduces more points of failure.
When This Error or Setup Appears
You'll encounter connection issues when:
- You've added a custom MCP server to
claude_desktop_config.jsonbut Claude Desktop shows no available tools - The server fails to start silently without error messages in the UI
- You're using relative paths or have JSON syntax errors that Claude Desktop doesn't explicitly report
- You need to pass environment variables (like API keys) to your server
Minimal Working Configuration
The configuration lives in claude_desktop_config.json. Here's a minimal working example:
JSON{ "mcpServers": { "my-notes": { "command": "python", "args": [ "/Users/tony/projects/notes-mcp/server.py" ], "env": { "LOG_LEVEL": "info" } } } }
Critical rules:
command: The executable to run the MCP server (e.g.,python,node,dotnet)args: Array of arguments. Always use absolute paths—never./server.pyor../server.pyenv: Optional object for environment variables the server needs
Parameters and Environment Variables
| Parameter | Required | Description |
|---|---|---|
command | Yes | The executable to run the MCP server (e.g., python, node, dotnet) |
args | Yes | Array of arguments for the command. Use absolute paths only |
env | No | Optional environment variables the server needs |
Root Cause Analysis
Connection failures typically stem from one of these root causes:
-
JSON syntax errors: Trailing commas are the most common culprit. JSON does not allow a comma after the last key-value pair or array element. Claude Desktop does not validate or report these errors.
-
Relative paths: Using
./server.pyor../server.pyinargs. Claude Desktop's working directory may not be what you expect, so the server binary is never found. -
Server not starting: The
commandexecutable might not be in PATH, or the server script has errors. Test by running the exact command manually in a terminal. -
Configuration not reloaded: Closing the window is not enough—you must fully quit Claude Desktop (Cmd+Q on macOS, right-click exit on Windows) for configuration changes to take effect.
Common Errors and Fixes
JSON configuration has trailing comma
Error: "args": ["/path/to/server.py",] or "env": {"KEY": "value",}
Solution: Validate your JSON with jq or an online validator. Remove any trailing commas from the last element in arrays or the last key in objects.
Using relative paths
Error: "args": ["./server.py"] or "args": ["../server.py"]
Solution: Always use absolute paths: "args": ["/Users/tony/projects/server.py"]
Claude Desktop not showing MCP tools
Solution:
- Fully quit Claude Desktop (Cmd+Q or right-click exit)
- Restart and check if tools appear
- If not, go to Settings → Advanced → View Logs to find MCP connection errors
- Test the server command manually in a terminal to verify it starts correctly
Tool call fails
Solution:
- Check server logs (stderr) for error messages
- Verify Claude's parameters match your server's JSON Schema
- Test the same parameters by running the server directly
- Ensure tool descriptions are clear to prevent Claude from generating non-existent fields
Production Notes and Security Checks
Critical limitations:
- Concurrency: Claude Desktop does not support multiple concurrent instances of the same MCP server
- File locking: If your server operates on local files (e.g., SQLite), Claude Desktop's caching may cause file locks
- Permissions: MCP servers run with the current user's privileges—no built-in isolation
- Network security: Servers default to localhost, but binding to
0.0.0.0exposes them to the LAN - Configuration errors: JSON syntax errors are not reported by Claude Desktop, making debugging difficult
- Secret leakage: Hardcoding API keys in JSON can expose them to other processes or logs
Security recommendations:
- Use environment variables or
.envfiles for sensitive information—never hardcode secrets in JSON - Ensure servers listen only on
127.0.0.1 - Implement server-side permission validation and input sanitization
- Regularly check logs for accidental secret exposure
FAQ
Q: Why does Claude Desktop still show no MCP tools after I configured the JSON?
A: The most common causes are JSON syntax errors (trailing commas) or relative paths. Validate your JSON with a tool like jq, ensure all paths in args are absolute, and fully quit Claude Desktop (Cmd+Q or right-click exit) before restarting. Check logs at Settings → Advanced → View Logs for specific MCP connection errors.
Q: Can I add multiple MCP servers in one configuration file?
A: Yes. Add multiple entries under mcpServers with different keys. Each entry must be separated by a comma, but the last entry must not have a trailing comma. Example:
JSON{ "mcpServers": { "notes": { "command": "python", "args": ["/path/to/notes-server.py"] }, "tasks": { "command": "node", "args": ["/path/to/tasks-server/dist/index.js"] } } }
Q: How do I securely manage API keys for my MCP server?
A: Avoid hardcoding secrets in the JSON configuration. Use the env field to reference environment variables, then read them in your server code via os.environ.get(). For example, set "GITHUB_TOKEN": "ghp_your_token_here" in the env object, and in your Python server use GITHUB_TOKEN = os.environ.get('GITHUB_TOKEN'). For higher security, use .env files or a secrets manager.