MCP Server Configuration and Management
The ongoing work
Installing servers takes five minutes. Living with them—authenticating, coordinating, keeping context under control—takes ongoing attention.
This section covers the operational side: OAuth flows for remote servers, managing multiple configurations, preventing tool descriptions from eating your context window, and sharing setups across teams.
OAuth 2.1 authentication
Remote MCP servers typically require authentication. The protocol standardizes on OAuth 2.1 with mandatory PKCE (Proof Key for Code Exchange).
How authentication works
The flow follows six steps:
- Claude Code sends a request to the MCP server without a token
- Server returns
HTTP 401 Unauthorizedwith aWWW-Authenticateheader pointing to authorization metadata - Claude Code retrieves authorization server details from the protected resource metadata endpoint
- PKCE parameters are generated and the authorization request is initiated
- After user approval, an access token is exchanged using the original PKCE verifier
- The original request is retried with the Bearer token
This happens automatically. You click through a browser authorization prompt and forget about it.
The /mcp command
Inside a Claude Code session, the /mcp command manages server connections and authentication.
/mcpThis displays:
- Connected servers and their status
- Available tools from each server
- Authentication state for servers requiring OAuth
For servers showing "Authentication required," select the server and choose "Authenticate." A browser window opens to complete the OAuth flow.
If authentication fails repeatedly, use claude mcp remove <name> to delete the server configuration, then re-add it.
Stale OAuth state can cause persistent authentication failures.
PKCE requirements
MCP mandates PKCE with the S256 (SHA-256) method. This prevents authorization code interception attacks.
The flow works like this:
- Claude Code generates a random
code_verifier(43-128 characters) - It computes
code_challengeby hashing the verifier with SHA-256 and Base64URL-encoding it - The authorization request includes the challenge
- Token exchange includes the original un-hashed verifier
- The authorization server verifies the hash matches before issuing tokens
You don't implement this yourself. Claude Code handles PKCE automatically for any OAuth-enabled MCP server.
Token management
Access tokens are stored securely and refreshed automatically when they expire. You can clear authentication state using:
# Remove and re-add to clear OAuth tokens
claude mcp remove github
claude mcp add --transport http github https://api.githubcopilot.com/mcp/For project-scoped servers, claude mcp reset-project-choices clears approval decisions but doesn't affect OAuth tokens.
Managing multiple servers
Three servers feel manageable. Seven servers with overlapping tools and different scopes feel like a mess. Here's how to keep things under control.
Viewing server state
The CLI offers inspection commands:
# List all configured servers across scopes
claude mcp list
# Show details for a specific server
claude mcp get filesystem
# Check configuration file contents
cat ~/.claude.json | jq '.mcpServers'Inside Claude Code, /mcp provides real-time status including which tools each server exposes.
Naming conventions
Consistent naming helps as server counts grow. Consider a naming pattern:
| Pattern | Example | Purpose |
|---|---|---|
<service> | github, notion | Simple, single-purpose servers |
<service>-<function> | github-issues, github-prs | Multiple servers for same service |
<env>-<service> | prod-database, dev-database | Environment-specific servers |
Names must be unique within a scope.
A local server named github overrides a user-scoped server with the same name.
Debugging server issues
When servers misbehave:
# Run Claude Code with MCP debug output
claude --mcp-debug
# Inside Claude Code, check diagnostics
/doctorThe /doctor command includes MCP configuration checks and highlights connection failures, authentication issues, and configuration errors.
Common issues:
- "Connection closed" — Often missing
cmd /cwrapper on Windows - "Authentication required" — Run
/mcpand complete OAuth flow - "Server not found" — Check
claude mcp listfor spelling and scope - "Tool not available" — Server connected but tool discovery failed; check server logs
MCP Tool Search
Here's a problem nobody warns you about: tool descriptions eat context. A single server can expose 50+ tools. Users with 7+ servers have reported 67,000+ tokens consumed by tool descriptions before typing a single prompt.
MCP Tool Search fixes this by loading tools on demand rather than upfront.
How it works
When tool descriptions would exceed 10% of the context window, Claude Code activates Tool Search automatically:
- Tool descriptions are not loaded into context upfront
- A lightweight search tool is provided instead (~500 tokens)
- Claude uses the search tool to discover relevant tools as needed
- Only discovered tools (typically 3-5 per search) are loaded
The difference is dramatic: context usage drops from 77,000+ tokens to around 8,700 tokens in typical configurations.
Configuration options
The ENABLE_TOOL_SEARCH environment variable controls behavior:
| Value | Behavior |
|---|---|
auto | Activates when MCP tools exceed 10% of context (default) |
auto:5 | Activates at custom threshold (5% in this example) |
true | Always enabled |
false | Disabled; all MCP tools loaded upfront |
# Use a custom 5% threshold
ENABLE_TOOL_SEARCH=auto:5 claude
# Disable tool search entirely
ENABLE_TOOL_SEARCH=false claudeYou can also set this in your settings.json under the env field.
Tool Search requires Sonnet 4+ or Opus 4+. Haiku models do not support this feature.
Verifying context usage
Check where your tokens are going:
/contextThis breaks down token allocation across system prompt, conversation history, and tool definitions. If MCP tools dominate the breakdown, Tool Search should already be active.
Configuration scopes in practice
The three scopes—local, project, and user—serve different purposes in practice.
Personal development workflow
For individual work, user scope provides utilities available everywhere:
# Memory server across all projects
claude mcp add --scope user memory -- npx -y @modelcontextprotocol/server-memory
# Sequential thinking for complex reasoning
claude mcp add --scope user thinking -- npx -y @modelcontextprotocol/server-sequential-thinkingThese appear in every Claude Code session without per-project configuration.
Team configurations
Project scope enables team sharing via .mcp.json:
{
"mcpServers": {
"database": {
"command": "npx",
"args": ["-y", "@bytebase/dbhub", "--dsn", "${DATABASE_URL}"]
},
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
"headers": {
"Authorization": "Bearer ${GITHUB_TOKEN}"
}
}
}
}Team members set environment variables locally. The configuration file contains structure, not secrets.
When Claude Code encounters .mcp.json, it prompts for approval before loading project-scoped servers.
This prevents untrusted repositories from automatically connecting to MCP servers.
Overriding team configurations
Local scope lets you override without modifying shared files:
# Override team database with local instance
claude mcp add --scope local database -- npx -y @bytebase/dbhub --dsn postgresql://localhost:5432/devScope precedence (local > project > user) means your local configuration takes effect without touching .mcp.json.
Enterprise managed configurations
Organizations can deploy managed configurations that users cannot modify.
Managed MCP servers
A managed-mcp.json file provides servers that are always available:
File locations:
- macOS:
/Library/Application Support/ClaudeCode/managed-mcp.json - Linux:
/etc/claude-code/managed-mcp.json - Windows:
C:\Program Files\ClaudeCode\managed-mcp.json
{
"mcpServers": {
"company-internal": {
"type": "http",
"url": "https://mcp.internal.company.com/api",
"headers": {
"Authorization": "Bearer ${COMPANY_API_TOKEN}"
}
}
}
}Users cannot remove or override managed servers—that's the point.
Allowlists and denylists
The managed settings file controls which servers users can add:
Settings file locations:
- macOS:
/Library/Application Support/ClaudeCode/managed-settings.json - Linux:
/etc/claude-code/managed-settings.json - Windows:
C:\ProgramData\ClaudeCode\managed-settings.json
{
"allowedMcpServers": [
{ "serverName": "github" },
{ "serverCommand": ["npx", "-y", "@modelcontextprotocol/server-filesystem"] },
{ "serverUrl": "https://mcp.company.com/*" }
],
"deniedMcpServers": [
{ "serverUrl": "https://*.untrusted.com/*" }
]
}Matching rules:
serverName— Matches the configured server nameserverCommand— Matches exact command and arguments (stdio servers)serverUrl— Matches remote server URLs with wildcard support
Allowlist behavior:
- Undefined: No restrictions
- Empty array: Complete lockdown (no user-added servers)
- List of entries: Only matching servers allowed
Denylists take absolute precedence. A server on both lists is blocked.
Operational patterns
Regular maintenance
Server configurations accumulate like browser tabs. Clean them out periodically:
# List all servers
claude mcp list
# Remove unused servers
claude mcp remove old-experiment
claude mcp remove deprecated-service
# Reset project approvals after .mcp.json changes
claude mcp reset-project-choicesEnvironment variable hygiene
Secrets in configuration files get committed to git. Don't do that.
# Set in shell profile, not in .mcp.json
export DATABASE_URL="postgresql://user:pass@host:5432/db"
export GITHUB_TOKEN="ghp_xxxxx"Use the ${VAR:-default} syntax to provide fallbacks for optional servers:
{
"mcpServers": {
"cache": {
"command": "npx",
"args": ["-y", "@company/cache-server"],
"env": {
"REDIS_URL": "${REDIS_URL:-redis://localhost:6379}"
}
}
}
}Troubleshooting checklist
When a server stops working:
- Verify configuration:
claude mcp get <name> - Check connection:
/mcpinside Claude Code - Run diagnostics:
/doctorfor configuration errors - Enable debug output:
claude --mcp-debug - Check environment variables: Ensure required variables are set
- Reset if needed: Remove and re-add the server
For authentication issues specifically:
- Complete OAuth flow via
/mcpif prompted - Clear and re-authenticate if tokens seem stale
- Verify the authorization server is reachable
The next section addresses security boundaries—what servers can access and how to limit their permissions.