260 lines
9 KiB
Markdown
260 lines
9 KiB
Markdown
---
|
|
title: "MCP Integration in Claude Code"
|
|
aliases: [mcp-servers, model-context-protocol, claude-mcp]
|
|
tags: [claude-code, mcp, integrations, tools, authentication, enterprise]
|
|
sources: [raw/Connect Claude Code to tools via MCP.md]
|
|
created: 2026-04-17
|
|
updated: 2026-04-17
|
|
---
|
|
|
|
# MCP Integration in Claude Code
|
|
|
|
Claude Code connects to external tools, databases, and APIs via the **Model Context Protocol (MCP)** — an open standard for AI-tool integrations. Instead of pasting data into chat, you connect a server once and Claude reads/acts on the system directly.
|
|
|
|
## What MCP Enables
|
|
|
|
Claude Code can:
|
|
- Implement features from issue trackers (JIRA → GitHub PR)
|
|
- Analyze monitoring data (Sentry, Statsig, PostHog)
|
|
- Query databases (PostgreSQL, BigQuery, Supabase)
|
|
- Integrate design tools (Figma → code)
|
|
- Automate workflows (Gmail drafts, Slack messages)
|
|
- React to external events via **channels** (Telegram, webhooks, Discord)
|
|
|
|
## Installing MCP Servers
|
|
|
|
### Three Transport Types
|
|
|
|
| Transport | When to Use | Command |
|
|
|-----------|-------------|---------|
|
|
| HTTP (recommended) | Cloud services, remote APIs | `claude mcp add --transport http <name> <url>` |
|
|
| SSE | Deprecated — use HTTP instead | `claude mcp add --transport sse <name> <url>` |
|
|
| stdio | Local processes, direct system access | `claude mcp add <name> -- <command> [args]` |
|
|
|
|
```sh
|
|
# HTTP example
|
|
claude mcp add --transport http notion https://mcp.notion.com/mcp
|
|
|
|
# With auth header
|
|
claude mcp add --transport http secure-api https://api.example.com/mcp \
|
|
--header "Authorization: Bearer your-token"
|
|
|
|
# stdio example (Airtable)
|
|
claude mcp add --transport stdio --env AIRTABLE_API_KEY=YOUR_KEY airtable \
|
|
-- npx -y airtable-mcp-server
|
|
```
|
|
|
|
**Option ordering rule:** All flags (`--transport`, `--env`, `--scope`, `--header`) must come **before** the server name. `--` separates the server name from its command.
|
|
|
|
### Managing Servers
|
|
|
|
```sh
|
|
claude mcp list # list all configured servers
|
|
claude mcp get <name> # details for a specific server
|
|
claude mcp remove <name> # remove a server
|
|
/mcp # check status inside Claude Code
|
|
```
|
|
|
|
## Configuration Scopes
|
|
|
|
| Scope | Loaded in | Shared | Stored in |
|
|
|-------|-----------|--------|-----------|
|
|
| `local` (default) | Current project only | No | `~/.claude.json` |
|
|
| `project` | Current project only | Yes (via `.mcp.json`) | `.mcp.json` in project root |
|
|
| `user` | All projects | No | `~/.claude.json` |
|
|
|
|
```sh
|
|
claude mcp add --transport http stripe --scope project https://mcp.stripe.com
|
|
claude mcp add --transport http hubspot --scope user https://mcp.hubspot.com/anthropic
|
|
```
|
|
|
|
- **Project scope** → checked into version control → team shares same servers
|
|
- Claude Code prompts for approval before using `.mcp.json` project-scoped servers
|
|
|
|
### Environment Variable Expansion in `.mcp.json`
|
|
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"api-server": {
|
|
"type": "http",
|
|
"url": "${API_BASE_URL:-https://api.example.com}/mcp",
|
|
"headers": { "Authorization": "Bearer ${API_KEY}" }
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Syntax: `${VAR}` or `${VAR:-default}`. Works in `command`, `args`, `env`, `url`, `headers`.
|
|
|
|
## Authentication
|
|
|
|
### OAuth 2.0
|
|
|
|
Run `/mcp` inside Claude Code to authenticate. Tokens are stored securely and auto-refreshed.
|
|
|
|
```sh
|
|
# Fixed callback port (for pre-registered redirect URIs)
|
|
claude mcp add --transport http --callback-port 8080 my-server https://mcp.example.com/mcp
|
|
|
|
# Pre-configured OAuth credentials
|
|
claude mcp add --transport http --client-id <id> --client-secret <secret> my-server <url>
|
|
```
|
|
|
|
### Restrict OAuth Scopes
|
|
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"slack": {
|
|
"type": "http",
|
|
"url": "https://mcp.slack.com/mcp",
|
|
"oauth": { "scopes": "channels:read chat:write search:read" }
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Dynamic Headers (non-OAuth auth)
|
|
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"internal-api": {
|
|
"type": "http",
|
|
"url": "https://mcp.internal.example.com",
|
|
"headersHelper": "/opt/bin/get-mcp-auth-headers.sh"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
- Command must output a JSON object of string key-value pairs to stdout
|
|
- Runs fresh on each connection (10-second timeout, no caching)
|
|
- Available env vars: `CLAUDE_CODE_MCP_SERVER_NAME`, `CLAUDE_CODE_MCP_SERVER_URL`
|
|
|
|
## Advanced Features
|
|
|
|
### Dynamic Tool Updates & Reconnection
|
|
|
|
- MCP `list_changed` notifications → Claude Code auto-refreshes available tools without disconnect
|
|
- HTTP/SSE servers: auto-reconnect with exponential backoff (5 attempts, starting 1s, doubling each time)
|
|
- Stdio servers: not auto-reconnected (local processes)
|
|
|
|
### Push Messages via Channels
|
|
|
|
MCP servers can push messages directly into your session (CI results, alerts, chat). Requires server declaring `claude/channel` capability + `--channels` flag at startup. See [[wiki/claude-code/overview|Claude Code Overview]].
|
|
|
|
### Tool Search (context efficiency)
|
|
|
|
By default, MCP tools are **deferred** — only names load at session start, definitions fetched on demand.
|
|
|
|
| `ENABLE_TOOL_SEARCH` | Behavior |
|
|
|----------------------|----------|
|
|
| (unset) | All tools deferred; falls back to upfront for non-Anthropic `ANTHROPIC_BASE_URL` |
|
|
| `true` | All tools deferred, always |
|
|
| `auto` | Load upfront if within 10% of context window, defer otherwise |
|
|
| `auto:<N>` | Custom threshold percentage |
|
|
| `false` | All tools loaded upfront |
|
|
|
|
Requires Sonnet 4+ or Opus 4+. Haiku does not support tool search.
|
|
|
|
### MCP Output Limits
|
|
|
|
- Warning at 10,000 tokens output
|
|
- Default max: 25,000 tokens (`MAX_MCP_OUTPUT_TOKENS` env var)
|
|
- Per-tool override via `_meta["anthropic/maxResultSizeChars"]` in `tools/list` response (max 500,000 chars)
|
|
|
|
```sh
|
|
export MAX_MCP_OUTPUT_TOKENS=50000
|
|
claude
|
|
```
|
|
|
|
### Claude Code as MCP Server
|
|
|
|
```sh
|
|
claude mcp serve # expose Claude's tools (View, Edit, LS, etc.) to other MCP clients
|
|
```
|
|
|
|
Add to `claude_desktop_config.json`:
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"claude-code": {
|
|
"type": "stdio",
|
|
"command": "/full/path/to/claude",
|
|
"args": ["mcp", "serve"],
|
|
"env": {}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Enterprise / Managed MCP
|
|
|
|
### Option 1: Exclusive control (`managed-mcp.json`)
|
|
|
|
Deploy to system path (requires admin):
|
|
- macOS: `/Library/Application Support/ClaudeCode/managed-mcp.json`
|
|
- Linux/WSL: `/etc/claude-code/managed-mcp.json`
|
|
- Windows: `C:\Program Files\ClaudeCode\managed-mcp.json`
|
|
|
|
Users cannot add/modify servers. Same format as `.mcp.json`.
|
|
|
|
### Option 2: Allowlists / Denylists (policy-based)
|
|
|
|
In managed settings:
|
|
```json
|
|
{
|
|
"allowedMcpServers": [
|
|
{ "serverName": "github" },
|
|
{ "serverCommand": ["npx", "-y", "approved-package"] },
|
|
{ "serverUrl": "https://mcp.company.com/*" }
|
|
],
|
|
"deniedMcpServers": [
|
|
{ "serverUrl": "https://*.untrusted.com/*" }
|
|
]
|
|
}
|
|
```
|
|
|
|
- **Denylist takes absolute precedence** over allowlist
|
|
- Each entry: exactly one of `serverName`, `serverCommand`, or `serverUrl`
|
|
- Command matching is **exact** (order and all args must match)
|
|
- URL patterns support `*` wildcards
|
|
- `allowedMcpServers: []` = complete lockdown (no MCP servers allowed)
|
|
|
|
## Popular MCP Servers (Quick Reference)
|
|
|
|
| Category | Server | Command |
|
|
|----------|--------|---------|
|
|
| Issue tracking | Linear | `claude mcp add --transport http linear https://mcp.linear.app/mcp` |
|
|
| Issue tracking | Atlassian (Jira/Confluence) | `claude mcp add --transport http atlassian https://mcp.atlassian.com/v1/mcp` |
|
|
| Version control | GitHub | `claude mcp add --transport http github https://api.githubcopilot.com/mcp/` |
|
|
| Monitoring | Sentry | `claude mcp add --transport http sentry https://mcp.sentry.dev/mcp` |
|
|
| Database | Supabase | `claude mcp add --transport http supabase https://mcp.supabase.com/mcp` |
|
|
| Design | Figma | `claude mcp add --transport http figma-remote-mcp https://mcp.figma.com/mcp` |
|
|
| Docs/Notes | Notion | `claude mcp add --transport http notion https://mcp.notion.com/mcp` |
|
|
| Automation | Zapier | `claude mcp add zapier --transport http https://mcp.zapier.com/api/v1/connect` |
|
|
| Search | Exa | `claude mcp add --transport http exa https://mcp.exa.ai/mcp` |
|
|
| Communication | Slack | `claude mcp add --transport http --client-id ... --callback-port 3118 slack https://mcp.slack.com/mcp` |
|
|
|
|
## Key Takeaways
|
|
|
|
- **MCP replaces copy-paste**: connect once, Claude reads/acts on the system directly
|
|
- **HTTP transport is the recommended default** for cloud services; SSE is deprecated
|
|
- **Three scopes**: local (default, private), project (team-shared via `.mcp.json`), user (cross-project)
|
|
- **OAuth 2.0** is the standard auth flow; `headersHelper` handles non-OAuth schemes
|
|
- **Tool search** defers MCP tool definitions to keep context lean — enabled by default on Sonnet 4+
|
|
- **Channels** let MCP servers push events into your session (webhooks, alerts, chat)
|
|
- **Enterprise control** via `managed-mcp.json` (exclusive) or allowlist/denylist policies
|
|
- **Dynamic reconnection** on HTTP/SSE servers; stdio servers must be restarted manually
|
|
|
|
## Sources
|
|
|
|
- `raw/Connect Claude Code to tools via MCP.md` (scraped from code.claude.com/docs/en/mcp, 2026-04-17)
|
|
|
|
## Related
|
|
|
|
- [[wiki/claude-code/overview|Claude Code Overview]]
|
|
- [[wiki/agent-sdk/_index|Claude Agent SDK]]
|
|
- [[wiki/architecture/_index|Architecture Patterns]]
|