Connect Claude Code to tools via MCP
> ## Documentation Index > Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt > Use this file to discover all available pages before exploring further.
Overview
Documentation Index
Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt Use this file to discover all available pages before exploring further.
Connect Claude Code to tools via MCP
Learn how to connect Claude Code to your tools with the Model Context Protocol.
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('visibility', 'commercial');
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 remotes = server.remotes || [];
const httpRemote = remotes.find(r => r.type === 'streamable-http');
const sseRemote = remotes.find(r => r.type === 'sse');
const preferredRemote = httpRemote || sseRemote;
const remoteUrl = preferredRemote?.url || meta.url;
const remoteType = preferredRemote?.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.replace('--transport streamable-http', '--transport http');
}
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 <div>Loading MCP servers...</div>;
}
if (error) {
return <div>Error loading MCP servers: {error}</div>;
}
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 <>
<style jsx>{ .cards-container { display: grid; gap: 1rem; margin-bottom: 2rem; } .server-card { border: 1px solid var(--border-color, #e5e7eb); border-radius: 6px; padding: 1rem; } .command-row { display: flex; align-items: center; gap: 0.25rem; } .command-row code { font-size: 0.75rem; overflow-x: auto; } }</style>
<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>;
})} </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.
Connect a server when you find yourself copying data into chat from another tool, like an issue tracker or a monitoring dashboard. Once connected, Claude can read and act on that system directly instead of working from what you paste.
What you can do with MCP
With MCP servers connected, you can ask Claude Code to:
- Implement features from issue trackers: "Add the feature described in JIRA issue ENG-4521 and create a PR on GitHub."
- Analyze monitoring data: "Check Sentry and Statsig to check the usage of the feature described in ENG-4521."
- Query databases: "Find emails of 10 random users who used feature ENG-4521, based on our PostgreSQL database."
- Integrate designs: "Update our standard email template based on the new Figma designs that were posted in Slack"
- Automate workflows: "Create Gmail drafts inviting these 10 users to a feedback session about the new feature."
- React to external events: An MCP server can also act as a channel that pushes messages into your session, so Claude reacts to Telegram messages, Discord chats, or webhook events while you're away.
Popular MCP servers
Here are some commonly used MCP servers you can connect to Claude Code:
Use third party MCP servers at your own risk - Anthropic has not verified the correctness or security of all these servers. Make sure you trust MCP servers you are installing. Be especially careful when using MCP servers that could fetch untrusted content, as these can expose you to prompt injection risk.
Need a specific integration? Find hundreds more MCP servers on GitHub, or build your own using the MCP SDK.
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
The SSE (Server-Sent Events) transport is deprecated. Use HTTP servers instead, where available.
# 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
Important: Option ordering
All options (--transport, --env, --scope, --header) must come before the server name. The -- (double dash) then separates the server name from the command and arguments that get passed to the MCP server.
For example:
claude mcp add --transport stdio myserver -- npx server→ runsnpx serverclaude mcp add --transport stdio --env KEY=value myserver -- python server.py --port 8080→ runspython server.py --port 8080withKEY=valuein environment
This prevents conflicts between Claude's flags and the server's flags.
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.
Automatic reconnection
If an HTTP or SSE server disconnects mid-session, Claude Code automatically reconnects with exponential backoff: up to five attempts, starting at a one-second delay and doubling each time. The server appears as pending in /mcp while reconnection is in progress. After five failed attempts the server is marked as failed and you can retry manually from /mcp. Stdio servers are local processes and are not reconnected automatically.
Push messages with channels
An MCP server can also push messages directly into your session so Claude can react to external events like CI results, monitoring alerts, or chat messages. To enable this, your server declares the claude/channel capability and you opt it in with the --channels flag at startup. See Channels to use an officially supported channel, or Channels reference to build your own.
Tips:
- Use the
--scopeflag to specify where the configuration is stored:local(default): Available only to you in the current project (was calledprojectin older versions)project: Shared with everyone in the project via.mcp.jsonfileuser: Available to you across all projects (was calledglobalin older versions)
- Set environment variables with
--envflags (for example,--env KEY=value) - Configure MCP server startup timeout using the MCP\_TIMEOUT environment variable (for example,
MCP_TIMEOUT=10000 claudesets a 10-second timeout) - Claude Code will display a warning when MCP tool output exceeds 10,000 tokens. To increase this limit, set the
MAX_MCP_OUTPUT_TOKENSenvironment variable (for example,MAX_MCP_OUTPUT_TOKENS=50000) - Use
/mcpto authenticate with remote servers that require OAuth 2.0 authentication
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:
- Plugins define MCP servers in
.mcp.jsonat the plugin root or inline inplugin.json - When a plugin is enabled, its MCP servers start automatically
- Plugin MCP tools appear alongside manually configured MCP tools
- Plugin servers are managed through plugin installation (not `/m