Overview
Claude Code connects to external tools and data sources through the Model Context Protocol (MCP), an open standard for AI-tool integrations. Once a server is connected, Claude can read from and act on that system directly instead of working from text you paste into the session.
This guide is about connecting servers that already exist — a vendor's hosted endpoint, a published package, or your own local script — not about writing one. The single tool you use is the claude mcp add command, plus the in-session /mcp command for authentication. You connect a server once, choose where its configuration lives, and it loads automatically in the sessions you scoped it to.
Connect a server when you find yourself copying data into chat from another tool such as an issue tracker, a database, or a monitoring dashboard. Browse reviewed remote connectors in the Anthropic Directory; any remote server listed there can be added with the same command.
Trust before you connect. Local stdio servers run their command with your user privileges, and remote servers can fetch external content that exposes you to prompt-injection risk. Verify a server's source and review its command, URL, and headers before adding it.
Connect a server with claude mcp add
Every server is added with one CLI command from your terminal. The transport you pick — stdio, HTTP, or SSE — depends on how the server runs.
Remote HTTP server (recommended for cloud services)
HTTP is the recommended transport for remote servers and the most widely supported 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
# With a Bearer token header
claude mcp add --transport http secure-api https://api.example.com/mcp \
--header "Authorization: Bearer your-token"
In .mcp.json or claude mcp add-json, the type field accepts streamable-http as an alias for http, so configs copied from server docs work without modification.
Remote SSE server (deprecated)
The SSE (Server-Sent Events) transport is deprecated — prefer HTTP where the server supports it. SSE is still available for servers that only expose an SSE endpoint.
# 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
# With an authentication header
claude mcp add --transport sse private-api https://api.company.com/sse \
--header "X-API-Key: your-key-here"
Local stdio server
Stdio servers run as local processes on your machine and are ideal for tools that need direct system access or custom scripts. The command that launches the server goes after a -- separator.
# Basic syntax
claude mcp add [options] <name> -- <command> [args...]
# Real example: an Airtable server launched with npx, with an env var
claude mcp add --env AIRTABLE_API_KEY=YOUR_KEY --transport stdio airtable \
-- npx -y airtable-mcp-server
# A read-only PostgreSQL server
claude mcp add --transport stdio db -- npx -y @bytebase/dbhub \
--dsn "postgresql://readonly:pass@prod.db.com:5432/analytics"
The -- (double dash) is required for stdio servers. It separates Claude's own flags (--transport, --env, --scope) from the command that runs the server; everything after -- is passed to the server untouched. Without it, Claude Code would try to parse the server's own flags (like a trailing --port 8080) as its own options. --env accepts multiple KEY=value pairs, but place at least one other flag between --env and the server name so the CLI doesn't read the name as another pair.
Adding from a JSON config
If you already have a JSON snippet for a server (for example from its README), add it directly:
# Basic syntax
claude mcp add-json <name> '<json>'
# An HTTP server with a header
claude mcp add-json weather-api '{"type":"http","url":"https://api.weather.com/mcp","headers":{"Authorization":"Bearer token"}}'
# A stdio server
claude mcp add-json local-weather '{"type":"stdio","command":"/path/to/weather-cli","args":["--api-key","abc123"],"env":{"CACHE_DIR":"/tmp"}}'
Already configured servers in Claude Desktop? Import them with claude mcp add-from-claude-desktop (macOS and WSL only), which reads Claude Desktop's config and lets you pick which servers to bring over.
Transport comparison
| Transport |
Where the server runs |
Add command |
Auth |
Status |
| stdio |
Local process on your machine |
claude mcp add ... -- <command> |
--env vars / args |
Supported |
| HTTP |
Remote endpoint (cloud service) |
claude mcp add --transport http |
OAuth via /mcp, or --header |
Recommended for remote |
| SSE |
Remote endpoint (streaming) |
claude mcp add --transport sse |
OAuth via /mcp, or --header |
Deprecated — use HTTP |
If an HTTP or SSE server drops mid-session, Claude Code reconnects automatically with exponential backoff (up to five attempts) and shows the server as pending in /mcp. Stdio servers are local processes and are not reconnected automatically.
Choose a scope: where the config lives
The --scope flag controls which projects the server loads in and whether the configuration is shared with your team. There are three scopes:
| Scope |
Loads in |
Shared with team |
Stored in |
local (default) |
Current project only |
No |
~/.claude.json |
project |
Current project only |
Yes, via version control |
.mcp.json in project root |
user |
All your projects |
No |
~/.claude.json |
# Local (default): private to you in this project
claude mcp add --transport http stripe https://mcp.stripe.com
# Project: shared with the team via a committed .mcp.json
claude mcp add --transport http paypal --scope project https://mcp.paypal.com/mcp
# User: available to you across every project
claude mcp add --transport http hubspot --scope user https://mcp.hubspot.com/anthropic
Use local for personal or experimental servers and anything with credentials you don't want in version control. Use project to share a server with everyone on a repo — the command creates or updates a .mcp.json at the project root that you commit:
{
"mcpServers": {
"shared-server": {
"command": "/path/to/server",
"args": [],
"env": {}
}
}
}
For security, Claude Code prompts each user for approval before using project-scoped servers from .mcp.json. Pending servers show as ⏸ Pending approval in claude mcp list; run claude interactively to review and approve them. Reset those choices with claude mcp reset-project-choices.
Use user scope for personal utility servers you want everywhere. When the same server name is defined in more than one place, precedence is local → project → user (the highest-precedence entry wins; fields are not merged).
Keep secrets out of committed config
Project-scoped .mcp.json supports environment-variable expansion in command, args, env, url, and headers, so teammates can share a config without sharing keys:
{
"mcpServers": {
"api-server": {
"type": "http",
"url": "${API_BASE_URL:-https://api.example.com}/mcp",
"headers": {
"Authorization": "Bearer ${API_KEY}"
}
}
}
}
${VAR} expands to the variable's value and ${VAR:-default} falls back to a default. If a required variable has no value and no default, Claude Code fails to parse the config.
Authenticate remote servers with /mcp OAuth
Many cloud servers require OAuth 2.0. Add the server first, then complete the browser flow from inside Claude Code with the /mcp command:
# 1. Add the server (no token needed up front)
claude mcp add --transport http sentry https://mcp.sentry.dev/mcp
# 2. Inside a Claude Code session, run:
/mcp
Then follow the browser login. Claude Code flags a server as needing authentication when it returns 401 Unauthorized or 403 Forbidden, so it surfaces in the /mcp menu automatically. Tokens are stored securely and refreshed automatically; revoke access with "Clear authentication" in the /mcp menu. OAuth works with HTTP (and SSE) servers, not stdio.
If you configured a static Authorization header and the server rejects it, Claude Code reports the connection as failed rather than falling back to OAuth — fix or remove the header to use the OAuth flow. If the browser doesn't open, copy the URL it prints and open it manually; if the redirect fails after you authenticate, paste the full callback URL from your browser back into the prompt Claude Code shows.
Some servers require a fixed redirect URI. Use --callback-port to pin the OAuth callback port to one you pre-registered (localhost:PORT/callback):
claude mcp add --transport http \
--callback-port 8080 \
my-server https://mcp.example.com/mcp
For servers that don't support Dynamic Client Registration, register an OAuth app in the server's developer portal, then pass --client-id (and --client-secret, which prompts with masked input):
claude mcp add --transport http \
--client-id your-client-id --client-secret --callback-port 8080 \
my-server https://mcp.example.com/mcp
The client secret is stored in your system keychain (macOS) or a credentials file, never in your config.
Manage and verify your servers
# List all configured servers
claude mcp list
# Show details for one server (transport, scope, OAuth status)
claude mcp get github
# Remove a server
claude mcp remove github
Inside a session, run /mcp to check live status: it shows the tool count next to each connected server and flags servers that advertise tools but expose none. Servers you added in Claude.ai connectors also appear here when you're signed in with a Claude.ai account.
Use what a connected server offers
Once a server is connected, three kinds of capabilities become available in your session:
- Tools — Claude calls them automatically as your prompts require. With Tool Search (on by default) only the tools Claude needs load into context, so adding more servers has minimal context cost.
- Resources — reference them with
@ mentions, for example Can you analyze @github:issue://123 and suggest a fix?. Type @ to browse available resources alongside files.
- Prompts — appear as slash commands in the form
/mcp__servername__promptname, with arguments passed space-separated: /mcp__github__pr_review 456.
Troubleshooting
- Server not listed after adding. Run
claude mcp list; a project-scoped server shows ⏸ Pending approval until you approve it in an interactive claude session.
- Remote server won't connect (401/403). It needs OAuth — run
/mcp and complete the browser login. If you set a static Authorization header that's rejected, remove it so OAuth can take over.
- Stdio server fails to start. Verify the command after
-- runs on its own in a terminal, that any runner (npx, uvx) is installed, and that required --env variables are set. Remember the -- separator before the command.
- Server's own flags rejected. Put every server flag after
--; anything before it is parsed as a Claude Code option.
- Config won't parse. A
${VAR} referenced in .mcp.json with no value and no :-default fails the parse — set the variable or add a default.
- Wrong definition is used. Local scope overrides project, which overrides user. Use
claude mcp get <name> to confirm which entry is active.
Next steps
Start with one server you already use — a hosted connector over HTTP, or a local stdio tool — at the default local scope, authenticate with /mcp if prompted, and confirm it with claude mcp list. When the team needs the same tools, promote it to a committed .mcp.json with --scope project and keep secrets in environment variables. For the full reference, see the Claude Code MCP documentation.