SpyBara
Go Premium

mcp.md 2026-01-08 21:02 UTC to 2026-01-09 21:01 UTC

No changes for this document in this history range.

2026
Wed 7 21:01 Thu 8 21:02 Fri 16 21:01 Mon 19 21:01 Tue 20 21:03 Fri 23 21:01 Sat 24 03:29

Connect Claude Code to tools via MCP

Learn how to connect Claude Code to your tools with the Model Context Protocol.

export const MCPServersTable = ({platform = "all"}) => { const ifYouAreAnAiAgentReadingThisYouShouldInsteadFetch = 'https://api.anthropic.com/mcp-registry/docs'; const [servers, setServers] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const fetchServers = async () => { try { setLoading(true); const allServers = []; let cursor = null; do { const url = new URL('https://api.anthropic.com/mcp-registry/v0/servers'); url.searchParams.set('version', 'latest'); url.searchParams.set('limit', '100'); if (cursor) { url.searchParams.set('cursor', cursor); } const response = await fetch(url); if (!response.ok) { throw new Error(Failed to fetch MCP registry: ${response.status}); } const data = await response.json(); allServers.push(...data.servers); cursor = data.metadata?.nextCursor || null; } while (cursor); const transformedServers = allServers.map(item => { const server = item.server; const meta = item._meta?.['com.anthropic.api/mcp-registry'] || ({}); const worksWith = meta.worksWith || []; const availability = { claudeCode: worksWith.includes('claude-code'), mcpConnector: worksWith.includes('claude-api'), claudeDesktop: worksWith.includes('claude-desktop') }; const remoteUrl = server.remotes?.[0]?.url || meta.url; const remoteType = server.remotes?.[0]?.type; const isTemplatedUrl = remoteUrl?.includes('{'); let setupUrl; if (isTemplatedUrl && meta.requiredFields) { const urlField = meta.requiredFields.find(f => f.field === 'url'); setupUrl = urlField?.sourceUrl || meta.documentation; } const urls = {}; if (!isTemplatedUrl) { if (remoteType === 'streamable-http') { urls.http = remoteUrl; } else if (remoteType === 'sse') { urls.sse = remoteUrl; } } let envVars = []; if (server.packages && server.packages.length > 0) { const npmPackage = server.packages.find(p => p.registryType === 'npm'); if (npmPackage) { urls.stdio = npx -y ${npmPackage.identifier}; if (npmPackage.environmentVariables) { envVars = npmPackage.environmentVariables; } } } return { name: meta.displayName || server.title || server.name, description: meta.oneLiner || server.description, documentation: meta.documentation, urls: urls, envVars: envVars, availability: availability, customCommands: meta.claudeCodeCopyText ? { claudeCode: meta.claudeCodeCopyText } : undefined, setupUrl: setupUrl }; }); setServers(transformedServers); setError(null); } catch (err) { setError(err.message); console.error('Error fetching MCP registry:', err); } finally { setLoading(false); } }; fetchServers(); }, []); const generateClaudeCodeCommand = server => { if (server.customCommands && server.customCommands.claudeCode) { return server.customCommands.claudeCode; } const serverSlug = server.name.toLowerCase().replace(/[^a-z0-9]/g, '-'); if (server.urls.http) { return claude mcp add ${serverSlug} --transport http ${server.urls.http}; } if (server.urls.sse) { return claude mcp add ${serverSlug} --transport sse ${server.urls.sse}; } if (server.urls.stdio) { const envFlags = server.envVars && server.envVars.length > 0 ? server.envVars.map(v => --env ${v.name}=YOUR_${v.name}).join(' ') : ''; const baseCommand = claude mcp add ${serverSlug} --transport stdio; return envFlags ? ${baseCommand} ${envFlags} -- ${server.urls.stdio} : ${baseCommand} -- ${server.urls.stdio}; } return null; }; if (loading) { return

Loading MCP servers...
; } if (error) { return
Error loading MCP servers: {error}
; } const filteredServers = servers.filter(server => { if (platform === "claudeCode") { return server.availability.claudeCode; } else if (platform === "mcpConnector") { return server.availability.mcpConnector; } else if (platform === "claudeDesktop") { return server.availability.claudeDesktop; } else if (platform === "all") { return true; } else { throw new Error(Unknown platform: ${platform}); } }); return <>

  <div className="cards-container">
    {filteredServers.map(server => {
const claudeCodeCommand = generateClaudeCodeCommand(server);
const mcpUrl = server.urls.http || server.urls.sse;
const commandToShow = platform === "claudeCode" ? claudeCodeCommand : mcpUrl;
return <div key={server.name} className="server-card">
          <div>
            {server.documentation ? <a href={server.documentation}>
                <strong>{server.name}</strong>
              </a> : <strong>{server.name}</strong>}
          </div>

          <p style={{
  margin: '0.5rem 0',
  fontSize: '0.9rem'
}}>
            {server.description}
          </p>

          {server.setupUrl && <p style={{
  margin: '0.25rem 0',
  fontSize: '0.8rem',
  fontStyle: 'italic',
  opacity: 0.7
}}>
              Requires user-specific URL.{' '}
              <a href={server.setupUrl} style={{
  textDecoration: 'underline'
}}>
                Get your URL here
              </a>.
            </p>}

          {commandToShow && !server.setupUrl && <>
            <p style={{
  display: 'block',
  fontSize: '0.75rem',
  fontWeight: 500,
  minWidth: 'fit-content',
  marginTop: '0.5rem',
  marginBottom: 0
}}>
              {platform === "claudeCode" ? "Command" : "URL"}
            </p>
            <div className="command-row">
              <code>
                {commandToShow}
              </code>
            </div>
          </>}
        </div>;

})}

</>; };

Claude Code can connect to hundreds of external tools and data sources through the Model Context Protocol (MCP), an open source standard for AI-tool integrations. MCP servers give Claude Code access to your tools, databases, and APIs.

What you can do with MCP

With MCP servers connected, you can ask Claude Code to:

Here are some commonly used MCP servers you can connect to Claude Code:

Installing MCP servers

MCP servers can be configured in three different ways depending on your needs:

Option 1: Add a remote HTTP server

HTTP servers are the recommended option for connecting to remote MCP servers. This is the most widely supported transport for cloud-based services.

# Basic syntax
claude mcp add --transport http <name> <url>

# Real example: Connect to Notion
claude mcp add --transport http notion https://mcp.notion.com/mcp

# Example with Bearer token
claude mcp add --transport http secure-api https://api.example.com/mcp \
  --header "Authorization: Bearer your-token"

Option 2: Add a remote SSE server

# Basic syntax
claude mcp add --transport sse <name> <url>

# Real example: Connect to Asana
claude mcp add --transport sse asana https://mcp.asana.com/sse

# Example with authentication header
claude mcp add --transport sse private-api https://api.company.com/sse \
  --header "X-API-Key: your-key-here"

Option 3: Add a local stdio server

Stdio servers run as local processes on your machine. They're ideal for tools that need direct system access or custom scripts.

# Basic syntax
claude mcp add [options] <name> -- <command> [args...]

# Real example: Add Airtable server
claude mcp add --transport stdio --env AIRTABLE_API_KEY=YOUR_KEY airtable \
  -- npx -y airtable-mcp-server

Managing your servers

Once configured, you can manage your MCP servers with these commands:

# List all configured servers
claude mcp list

# Get details for a specific server
claude mcp get github

# Remove a server
claude mcp remove github

# (within Claude Code) Check server status
/mcp

Dynamic tool updates

Claude Code supports MCP list_changed notifications, allowing MCP servers to dynamically update their available tools, prompts, and resources without requiring you to disconnect and reconnect. When an MCP server sends a list_changed notification, Claude Code automatically refreshes the available capabilities from that server.

Plugin-provided MCP servers

Plugins can bundle MCP servers, automatically providing tools and integrations when the plugin is enabled. Plugin MCP servers work identically to user-configured servers.

How plugin MCP servers work:

Example plugin MCP configuration:

In .mcp.json at plugin root:

{
  "database-tools": {
    "command": "${CLAUDE_PLUGIN_ROOT}/servers/db-server",
    "args": ["--config", "${CLAUDE_PLUGIN_ROOT}/config.json"],
    "env": {
      "DB_URL": "${DB_URL}"
    }
  }
}

Or inline in plugin.json:

{
  "name": "my-plugin",
  "mcpServers": {
    "plugin-api": {
      "command": "${CLAUDE_PLUGIN_ROOT}/servers/api-server",
      "args": ["--port", "8080"]
    }
  }
}

Plugin MCP features:

Viewing plugin MCP servers:

# Within Claude Code, see all MCP servers including plugin ones
/mcp

Plugin servers appear in the list with indicators showing they come from plugins.

Benefits of plugin MCP servers:

See the plugin components reference for details on bundling MCP servers with plugins.

MCP installation scopes

MCP servers can be configured at three different scope levels, each serving distinct purposes for managing server accessibility and sharing. Understanding these scopes helps you determine the best way to configure servers for your specific needs.

Local scope

Local-scoped servers represent the default configuration level and are stored in ~/.claude.json under your project's path. These servers remain private to you and are only accessible when working within the current project directory. This scope is ideal for personal development servers, experimental configurations, or servers containing sensitive credentials that shouldn't be shared.

# Add a local-scoped server (default)
claude mcp add --transport http stripe https://mcp.stripe.com

# Explicitly specify local scope
claude mcp add --transport http stripe --scope local https://mcp.stripe.com

Project scope

Project-scoped servers enable team collaboration by storing configurations in a .mcp.json file at your project's root directory. This file is designed to be checked into version control, ensuring all team members have access to the same MCP tools and services. When you add a project-scoped server, Claude Code automatically creates or updates this file with the appropriate configuration structure.

# Add a project-scoped server
claude mcp add --transport http paypal --scope project https://mcp.paypal.com/mcp

The resulting .mcp.json file follows a standardized format:

{
  "mcpServers": {
    "shared-server": {
      "command": "/path/to/server",
      "args": [],
      "env": {}
    }
  }
}

For security reasons, Claude Code prompts for approval before using project-scoped servers from .mcp.json files. If you need to reset these approval choices, use the claude mcp reset-project-choices command.

User scope

User-scoped servers are stored in ~/.claude.json and provide cross-project accessibility, making them available across all projects on your machine while remaining private to your user account. This scope works well for personal utility servers, development tools, or services you frequently use across different projects.

# Add a user server
claude mcp add --transport http hubspot --scope user https://mcp.hubspot.com/anthropic

Choosing the right scope

Select your scope based on:

Scope hierarchy and precedence

MCP server configurations follow a clear precedence hierarchy. When servers with the same name exist at multiple scopes, the system resolves conflicts by prioritizing local-scoped servers first, followed by project-scoped servers, and finally user-scoped servers. This design ensures that personal configurations can override shared ones when needed.

Environment variable expansion in .mcp.json

Claude Code supports environment variable expansion in .mcp.json files, allowing teams to share configurations while maintaining flexibility for machine-specific paths and sensitive values like API keys.

Supported syntax:

Expansion locations: Environment variables can be expanded in:

Example with variable expansion:

{
  "mcpServers": {
    "api-server": {
      "type": "http",
      "url": "${API_BASE_URL:-https://api.example.com}/mcp",
      "headers": {
        "Authorization": "Bearer ${API_KEY}"
      }
    }
  }
}

If a required environment variable is not set and has no default value, Claude Code will fail to parse the config.

Practical examples

{/* ### Example: Automate browser testing with Playwright

# 1. Add the Playwright MCP server
claude mcp add --transport stdio playwright -- npx -y @playwright/mcp@latest

# 2. Write and run browser tests
> "Test if the login flow works with test@example.com"
> "Take a screenshot of the checkout page on mobile"
> "Verify that the search feature returns results"
``` */}

### Example: Monitor errors with Sentry

```bash  theme={null}
# 1. Add the Sentry MCP server
claude mcp add --transport http sentry https://mcp.sentry.dev/mcp

# 2. Use /mcp to authenticate with your Sentry account
> /mcp

# 3. Debug production issues
> "What are the most common errors in the last 24 hours?"
> "Show me the stack trace for error ID abc123"
> "Which deployment introduced these new errors?"

Example: Connect to GitHub for code reviews

# 1. Add the GitHub MCP server
claude mcp add --transport http github https://api.githubcopilot.com/mcp/

# 2. In Claude Code, authenticate if needed
> /mcp
# Select "Authenticate" for GitHub

# 3. Now you can ask Claude to work with GitHub
> "Review PR #456 and suggest improvements"
> "Create a new issue for the bug we just found"
> "Show me all open PRs assigned to me"

Example: Query your PostgreSQL database

# 1. Add the database server with your connection string
claude mcp add --transport stdio db -- npx -y @bytebase/dbhub \
  --dsn "postgresql://readonly:pass@prod.db.com:5432/analytics"

# 2. Query your database naturally
> "What's our total revenue this month?"
> "Show me the schema for the orders table"
> "Find customers who haven't made a purchase in 90 days"

Authenticate with remote MCP servers

Many cloud-based MCP servers require authentication. Claude Code supports OAuth 2.0 for secure connections.

1

Add the server that requires authentication

For example:

claude mcp add --transport http sentry https://mcp.sentry.dev/mcp
2

Use the /mcp command within Claude Code

In Claude code, use the command:

> /mcp

Then follow the steps in your browser to login.

Add MCP servers from JSON configuration

If you have a JSON configuration for an MCP server, you can add it directly:

1

Add an MCP server from JSON

# Basic syntax
claude mcp add-json <name> '<json>'

# Example: Adding an HTTP server with JSON configuration
claude mcp add-json weather-api '{"type":"http","url":"https://api.weather.com/mcp","headers":{"Authorization":"Bearer token"}}'

# Example: Adding a stdio server with JSON configuration
claude mcp add-json local-weather '{"type":"stdio","command":"/path/to/weather-cli","args":["--api-key","abc123"],"env":{"CACHE_DIR":"/tmp"}}'
2

Verify the server was added

claude mcp get weather-api

Import MCP servers from Claude Desktop

If you've already configured MCP servers in Claude Desktop, you can import them:

1

Import servers from Claude Desktop

# Basic syntax 
claude mcp add-from-claude-desktop 
2

Select which servers to import

After running the command, you'll see an interactive dialog that allows you to select which servers you want to import.

3

Verify the servers were imported

claude mcp list 

Use Claude Code as an MCP server

You can use Claude Code itself as an MCP server that other applications can connect to:

# Start Claude as a stdio MCP server
claude mcp serve

You can use this in Claude Desktop by adding this configuration to claude_desktop_config.json:

{
  "mcpServers": {
    "claude-code": {
      "type": "stdio",
      "command": "claude",
      "args": ["mcp", "serve"],
      "env": {}
    }
  }
}

MCP output limits and warnings

When MCP tools produce large outputs, Claude Code helps manage the token usage to prevent overwhelming your conversation context:

To increase the limit for tools that produce large outputs:

# Set a higher limit for MCP tool outputs
export MAX_MCP_OUTPUT_TOKENS=50000
claude

This is particularly useful when working with MCP servers that:

Use MCP resources

MCP servers can expose resources that you can reference using @ mentions, similar to how you reference files.

Reference MCP resources

1

List available resources

Type @ in your prompt to see available resources from all connected MCP servers. Resources appear alongside files in the autocomplete menu.

2

Reference a specific resource

Use the format @server:protocol://resource/path to reference a resource:

> Can you analyze @github:issue://123 and suggest a fix?
> Please review the API documentation at @docs:file://api/authentication
3

Multiple resource references

You can reference multiple resources in a single prompt:

> Compare @postgres:schema://users with @docs:file://database/user-model

Use MCP prompts as slash commands

MCP servers can expose prompts that become available as slash commands in Claude Code.

Execute MCP prompts

1

Discover available prompts

Type / to see all available commands, including those from MCP servers. MCP prompts appear with the format /mcp__servername__promptname.

2

Execute a prompt without arguments

> /mcp__github__list_prs
3

Execute a prompt with arguments

Many prompts accept arguments. Pass them space-separated after the command:

> /mcp__github__pr_review 456
> /mcp__jira__create_issue "Bug in login flow" high

Managed MCP configuration

For organizations that need centralized control over MCP servers, Claude Code supports two configuration options:

  1. Exclusive control with managed-mcp.json: Deploy a fixed set of MCP servers that users cannot modify or extend
  2. Policy-based control with allowlists/denylists: Allow users to add their own servers, but restrict which ones are permitted

These options allow IT administrators to:

Option 1: Exclusive control with managed-mcp.json

When you deploy a managed-mcp.json file, it takes exclusive control over all MCP servers. Users cannot add, modify, or use any MCP servers other than those defined in this file. This is the simplest approach for organizations that want complete control.

System administrators deploy the configuration file to a system-wide directory:

The managed-mcp.json file uses the same format as a standard .mcp.json file:

{
  "mcpServers": {
    "github": {
      "type": "http",
      "url": "https://api.githubcopilot.com/mcp/"
    },
    "sentry": {
      "type": "http",
      "url": "https://mcp.sentry.dev/mcp"
    },
    "company-internal": {
      "type": "stdio",
      "command": "/usr/local/bin/company-mcp-server",
      "args": ["--config", "/etc/company/mcp-config.json"],
      "env": {
        "COMPANY_API_URL": "https://internal.company.com"
      }
    }
  }
}

Option 2: Policy-based control with allowlists and denylists

Instead of taking exclusive control, administrators can allow users to configure their own MCP servers while enforcing restrictions on which servers are permitted. This approach uses allowedMcpServers and deniedMcpServers in the managed settings file.

Restriction options

Each entry in the allowlist or denylist can restrict servers in three ways:

  1. By server name (serverName): Matches the configured name of the server
  2. By command (serverCommand): Matches the exact command and arguments used to start stdio servers
  3. By URL pattern (serverUrl): Matches remote server URLs with wildcard support

Important: Each entry must have exactly one of serverName, serverCommand, or serverUrl.

Example configuration

{
  "allowedMcpServers": [
    // Allow by server name
    { "serverName": "github" },
    { "serverName": "sentry" },

    // Allow by exact command (for stdio servers)
    { "serverCommand": ["npx", "-y", "@modelcontextprotocol/server-filesystem"] },
    { "serverCommand": ["python", "/usr/local/bin/approved-server.py"] },

    // Allow by URL pattern (for remote servers)
    { "serverUrl": "https://mcp.company.com/*" },
    { "serverUrl": "https://*.internal.corp/*" }
  ],
  "deniedMcpServers": [
    // Block by server name
    { "serverName": "dangerous-server" },

    // Block by exact command (for stdio servers)
    { "serverCommand": ["npx", "-y", "unapproved-package"] },

    // Block by URL pattern (for remote servers)
    { "serverUrl": "https://*.untrusted.com/*" }
  ]
}

How command-based restrictions work

Exact matching:

Stdio server behavior:

Non-stdio server behavior:

How URL-based restrictions work

URL patterns support wildcards using * to match any sequence of characters. This is useful for allowing entire domains or subdomains.

Wildcard examples:

Remote server behavior:

Example: URL-only allowlist
{
"allowedMcpServers": [
{ "serverUrl": "https://mcp.company.com/*" },
{ "serverUrl": "https://*.internal.corp/*" }
]
}

Result:

  • HTTP server at https://mcp.company.com/api: ✅ Allowed (matches URL pattern)
  • HTTP server at https://api.internal.corp/mcp: ✅ Allowed (matches wildcard subdomain)
  • HTTP server at https://external.com/mcp: ❌ Blocked (doesn't match any URL pattern)
  • Stdio server with any command: ❌ Blocked (no name or command entries to match)
Example: Command-only allowlist
{
"allowedMcpServers": [
{ "serverCommand": ["npx", "-y", "approved-package"] }
]
}

Result:

  • Stdio server with ["npx", "-y", "approved-package"]: ✅ Allowed (matches command)
  • Stdio server with ["node", "server.js"]: ❌ Blocked (doesn't match command)
  • HTTP server named "my-api": ❌ Blocked (no name entries to match)
Example: Mixed name and command allowlist
{
"allowedMcpServers": [
{ "serverName": "github" },
{ "serverCommand": ["npx", "-y", "approved-package"] }
]
}

Result:

  • Stdio server named "local-tool" with ["npx", "-y", "approved-package"]: ✅ Allowed (matches command)
  • Stdio server named "local-tool" with ["node", "server.js"]: ❌ Blocked (command entries exist but doesn't match)
  • Stdio server named "github" with ["node", "server.js"]: ❌ Blocked (stdio servers must match commands when command entries exist)
  • HTTP server named "github": ✅ Allowed (matches name)
  • HTTP server named "other-api": ❌ Blocked (name doesn't match)
Example: Name-only allowlist
{
"allowedMcpServers": [
{ "serverName": "github" },
{ "serverName": "internal-tool" }
]
}

Result:

  • Stdio server named "github" with any command: ✅ Allowed (no command restrictions)
  • Stdio server named "internal-tool" with any command: ✅ Allowed (no command restrictions)
  • HTTP server named "github": ✅ Allowed (matches name)
  • Any server named "other": ❌ Blocked (name doesn't match)

Allowlist behavior (allowedMcpServers)

Denylist behavior (deniedMcpServers)

Important notes


To find navigation and other pages in this documentation, fetch the llms.txt file at: https://code.claude.com/docs/llms.txt