Applied Intelligence
Module 10: MCP and Tool Integration

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:

  1. Claude Code sends a request to the MCP server without a token
  2. Server returns HTTP 401 Unauthorized with a WWW-Authenticate header pointing to authorization metadata
  3. Claude Code retrieves authorization server details from the protected resource metadata endpoint
  4. PKCE parameters are generated and the authorization request is initiated
  5. After user approval, an access token is exchanged using the original PKCE verifier
  6. 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.

/mcp

This 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:

  1. Claude Code generates a random code_verifier (43-128 characters)
  2. It computes code_challenge by hashing the verifier with SHA-256 and Base64URL-encoding it
  3. The authorization request includes the challenge
  4. Token exchange includes the original un-hashed verifier
  5. 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:

PatternExamplePurpose
<service>github, notionSimple, single-purpose servers
<service>-<function>github-issues, github-prsMultiple servers for same service
<env>-<service>prod-database, dev-databaseEnvironment-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
/doctor

The /doctor command includes MCP configuration checks and highlights connection failures, authentication issues, and configuration errors.

Common issues:

  • "Connection closed" — Often missing cmd /c wrapper on Windows
  • "Authentication required" — Run /mcp and complete OAuth flow
  • "Server not found" — Check claude mcp list for spelling and scope
  • "Tool not available" — Server connected but tool discovery failed; check server logs

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:

  1. Tool descriptions are not loaded into context upfront
  2. A lightweight search tool is provided instead (~500 tokens)
  3. Claude uses the search tool to discover relevant tools as needed
  4. 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:

ValueBehavior
autoActivates when MCP tools exceed 10% of context (default)
auto:5Activates at custom threshold (5% in this example)
trueAlways enabled
falseDisabled; all MCP tools loaded upfront
# Use a custom 5% threshold
ENABLE_TOOL_SEARCH=auto:5 claude

# Disable tool search entirely
ENABLE_TOOL_SEARCH=false claude

You 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:

/context

This 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-thinking

These 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/dev

Scope 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 name
  • serverCommand — 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-choices

Environment 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:

  1. Verify configuration: claude mcp get <name>
  2. Check connection: /mcp inside Claude Code
  3. Run diagnostics: /doctor for configuration errors
  4. Enable debug output: claude --mcp-debug
  5. Check environment variables: Ensure required variables are set
  6. Reset if needed: Remove and re-add the server

For authentication issues specifically:

  • Complete OAuth flow via /mcp if 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.

On this page