The Definitive Guide to MCP Server Configuration in Claude Code
If you've ever felt frustrated trying to configure MCP (Model Context Protocol) servers in Claude Code, you're not alone. The configuration system has multiple overlapping files, unclear precedence rules, and documentation that doesn't fully explain the hierarchy. After wrestling with this myself, here's everything you need to know to get your MCP servers working reliably across all your projects.
The Configuration Hierarchy Problem
Claude Code supports MCP server configuration in five different locations, each with different scopes and precedence:
<project>/.mcp.json- Project-specific config (highest priority)~/.claude.json→projects[path].mcpServers- Project overrides in main config~/.claude/.mcp.json- Default workspace config~/.claude.json→mcpServers- TRUE GLOBAL config~/.config/claude-code/mcp_config.json- Legacy/deprecated
The lack of clear documentation about this hierarchy is what causes most of the frustration. You configure a server in one location, expecting it to work everywhere, but it only shows up in specific projects.
Figure 1: The five levels of MCP configuration hierarchy and their precedence
Understanding Scope: Global vs Project-Specific
Global Configuration (Available Everywhere)
For MCP servers you want available in all projects, use:
~/.claude.json → mcpServers
This is the true global configuration. Any server defined here will be available across your entire system, regardless of which project directory you're working in.
Example global configuration:
{
"mcpServers": {
"membrane": {
"type": "sse",
"url": "http://10.10.10.25:8765/sse",
"description": "MemBrane dual-memory system"
},
"gitlab": {
"command": "bunx",
"args": ["@modelcontextprotocol/server-gitlab"],
"env": {
"GITLAB_PERSONAL_TOKEN": "your-token-here",
"GITLAB_API_URL": "https://your-gitlab-instance.com/api/v4"
},
"description": "GitLab repository management"
}
}
}
Project-Specific Configuration
For servers that should only be available in specific projects, you have two options:
Option 1: Project .mcp.json file (recommended for clarity)
Create .mcp.json in your project root:
{
"mcpServers": {
"project-specific-server": {
"command": "node",
"args": ["server.js"],
"description": "Project-specific MCP server"
}
}
}
Option 2: Project override in ~/.claude.json
{
"projects": {
"/path/to/project": {
"mcpServers": {
"project-specific-server": {
...
}
}
}
}
}
MCP Server Types
Figure 2: The three transport types supported by Claude Code MCP servers
Claude Code supports three transport types for MCP servers:
1. stdio (Standard Input/Output)
Most common for locally-run servers. The server communicates via stdin/stdout.
{
"command": "python",
"args": ["-m", "my_mcp_server"],
"cwd": "/path/to/server",
"env": {
"API_KEY": "secret"
}
}
2. SSE (Server-Sent Events)
For servers running as HTTP services. Uses server-sent events for bidirectional communication.
{
"type": "sse",
"url": "http://localhost:8765/sse",
"description": "HTTP-based MCP server"
}
3. HTTP
For simple HTTP-based servers.
{
"type": "http",
"url": "https://api.example.com/mcp/",
"headers": {
"Authorization": "Bearer token"
}
}
Common Configuration Patterns
Remote Servers via SSH
You can run MCP servers on remote machines:
{
"command": "ssh",
"args": [
"user@remote-host",
"cd /path/to/server && .venv/bin/python -m server"
],
"description": "Remote MCP server via SSH"
}
Docker-Based Servers
Run MCP servers in containers:
{
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"your-mcp-image:latest"
],
"description": "Dockerized MCP server"
}
Python Virtual Environments
Proper path to Python executable in venv:
{
"command": "/absolute/path/to/.venv/bin/python",
"args": ["-m", "src.mcp_server"],
"cwd": "/absolute/path/to/project"
}
Troubleshooting Checklist
Figure 3: Common MCP configuration issues and their solutions
When your MCP server isn't showing up:
- Check the right config file - Are you editing global or project-specific?
- Use absolute paths - Relative paths often don't work as expected
- Restart Claude Code - Configuration changes require a restart
- Check server status - Is the server actually running (for SSE/HTTP)?
- Verify credentials - Check environment variables and API keys
- Look at logs - Claude Code logs can show connection errors
- Test the command manually - Run the command in your terminal first
Best Practices
1. Start Global, Override Locally
Define commonly-used servers globally in ~/.claude.json → mcpServers, then override or add project-specific servers only when needed.
2. Use Descriptive Names
Give your servers clear, descriptive names and include the description field:
{
"gitlab": {
"description": "GitLab repository management for company-gitlab.com"
}
}
3. Separate Credentials
Don't commit API keys to version control. Store them in:
- Environment variables
- The
envsection of your MCP config - Separate credential files outside the repo
4. Document Your Setup
Create a MCP_SERVERS.md in your project documenting which servers are available and how to configure them.
Example: Complete Working Configuration
Here's a complete example showing both global and project-specific configuration:
~/.claude.json (global):
{
"mcpServers": {
"memory": {
"type": "sse",
"url": "http://localhost:8765/sse",
"description": "Personal memory system"
},
"gitlab": {
"command": "bunx",
"args": ["@modelcontextprotocol/server-gitlab"],
"env": {
"GITLAB_PERSONAL_TOKEN": "glpat-xxx",
"GITLAB_API_URL": "https://gitlab.com/api/v4"
}
}
}
}
project/.mcp.json (project-specific):
{
"mcpServers": {
"database": {
"command": "npx",
"args": ["@company/database-mcp"],
"env": {
"DATABASE_URL": "postgresql://localhost/myapp"
},
"description": "Project database access"
}
}
}
Conclusion
The MCP configuration system in Claude Code is powerful but poorly documented. Once you understand the hierarchy and know which config file to use for which purpose, it becomes manageable:
- Global servers:
~/.claude.json → mcpServers - Project servers:
<project>/.mcp.json - Always use absolute paths
- Always restart after config changes
Understanding this hierarchy will save you hours of frustration. The design isn't intuitive, but now you have a reference guide to get it right the first time.
Have you encountered other MCP configuration gotchas? Let me know in the comments below.
Related Posts
The Token Economy: Why Optimizing AI Usage Is Like Managing a Power Grid
Most token optimization advice tells you to use fewer tokens. That's the wrong problem. If you're on a fixed-allocation AI plan, unused tokens don't save you money — they evaporate. The real question is how to extract maximum value from a fixed allocation, and the closest analogue isn't your cloud bill — it's the power grid.
Autonomous Memory Systems: Building MemBrane from Scratch
The holy grail of personal AI is continuity - systems that remember context across sessions, learn from interactions, and improve over time. Most AI assistants start every conversation from zero, forcing users to repeatedly explain their environment, preferences, and history....
Building a Personal AI Infrastructure: Lessons from 2025
2025 marked a transformative year in personal AI infrastructure. What started as experimenting with Claude Code evolved into a comprehensive, production-grade system that fundamentally changed how tec...
Enjoyed this article?
Subscribe to get notified about new posts on software engineering, AI development, and infrastructure.
No spam, unsubscribe anytime.