Model Context Protocol
11 min read
What You’ll Learn
This chapter is all about the Model Context Protocol (MCP), the standard for connecting Claude Code to external tools, databases, and APIs. By the end, you’ll know how MCP servers work, which of the three transport modes to pick for your situation, how to add and configure servers at different scopes, how to share server configs with your team through .mcp.json, and how to troubleshoot connection issues when things go sideways.
What MCP Enables
Model Context Protocol (MCP) is the open standard that connects Claude Code to external tools, databases, APIs, ticketing systems, and documentation, beyond the local filesystem.
MCP lets Claude Code reach beyond your local filesystem. On its own, Claude Code can read files, run shell commands, and search your codebase. Add MCP into the mix, and it can also query a database, create tickets in your project management tool, search a knowledge base, interact with cloud services, or call pretty much any API you connect.
MCP servers expose tools that Claude Code calls just like its built in ones. Connect a PostgreSQL MCP server and Claude Code gains a query tool for running SQL. Hook up a Jira MCP server and it picks up tools for creating and updating tickets. From Claude Code’s perspective, MCP tools work identically to its native file and shell tools. It decides when to use them based on what you’re asking for.
One important distinction: you don’t build MCP servers yourself. Instead, you install and connect existing servers that other developers and organizations have published. This chapter focuses on connecting and configuring servers, not developing them.
Architecture Overview
MCP follows a client server architecture. Claude Code acts as the MCP client, connecting to one or more MCP servers that each provide a set of tools. These servers can run locally on your machine as child processes, or remotely on another host over the network.
The diagram above shows how everything fits together. Local servers connect via stdio (standard input/output) and run as child processes of Claude Code. Remote servers connect via HTTP over the network and can live anywhere: on a team server, in the cloud, or behind your corporate firewall. Each server exposes tools that show up in Claude Code’s tool palette right alongside its built in capabilities.
You can connect multiple servers at the same time, and Claude Code handles the connections and routes tool calls to the right server automatically. A typical project might have a local database server (stdio), a remote documentation search server (HTTP), and a cloud API integration (HTTP) all running simultaneously.
Transport Modes
MCP supports three transport protocols, and each one determines how Claude Code talks to the server.
stdio (default for local servers)
With stdio, the server runs as a child process on your machine, and Claude Code communicates with it through stdin and stdout. It’s the simplest transport: no networking, no authentication, no port configuration. Most MCP servers you install locally use stdio by default.
# stdio transport (default, no --transport flag needed)claude mcp add my-tools -- npx @my-org/mcp-toolsThe server starts as a child process when Claude Code launches.
Use stdio when the server runs locally, you installed it via npm or downloaded a binary, and only you need access. The server process starts when Claude Code launches and stops when the session ends. No ports get opened and no network traffic leaves your machine.
HTTP (recommended for remote servers)
With HTTP, the server runs on a remote host and communicates via the Streamable HTTP protocol. It supports authentication headers, works across network boundaries, and handles reconnection gracefully. If the server isn’t running locally, HTTP is the way to go.
# HTTP transport for a remote serverclaude mcp add docs-server --transport http --url https://mcp.example.com/docsReach for HTTP when the server lives on another machine, runs in the cloud, or is shared across a team. It also supports OAuth authentication flows for servers that require user authorization.
# HTTP with custom headers for API key authclaude mcp add analytics --transport http --url https://mcp.example.com/analytics --header "X-API-Key: your-api-key-here"SSE (deprecated)
Server Sent Events was the original remote transport for MCP. SSE is explicitly deprecated in favor of HTTP. It still works, but it’ll be removed in a future release. If you’ve got existing SSE server configurations, it’s time to migrate them to HTTP.
# DEPRECATED: use HTTP insteadclaude mcp add legacy-server --transport sse --url https://old-server.example.com/eventsMigrate existing SSE configurations to HTTP transport.
Don’t use SSE for new servers. If a server only supports SSE, check whether an updated version supports HTTP. If not, SSE will continue to work for now, but plan your migration sooner rather than later.
Adding MCP Servers
The claude mcp add command registers a new MCP server. The basic syntax is: server name, optional flags, a double dash separator, and then the command to start the server.
claude mcp add <name> [flags] -- <command> [args...]Here are some common variations.
# Basic local serverclaude mcp add postgres -- npx @mcp/postgres postgresql://localhost/mydb
# With environment variablesclaude mcp add github --env GITHUB_TOKEN=ghp_xxxxxxxxxxxx -- npx @mcp/github
# Scoped to project (saved in .mcp.json)claude mcp add project-db --scope project -- npx @mcp/postgres postgresql://localhost/projectdb
# Remote HTTP server with authenticationclaude mcp add company-api --transport http --url https://mcp.company.com/api --header "Authorization: Bearer TOKEN_HERE"
# Multiple environment variablesclaude mcp add analytics --env API_KEY=xxx --env REGION=us-east-1 -- npx @mcp/analyticsOnce you’ve added a server, Claude Code starts it automatically on the next session launch. You can verify the connection with /mcp from within an active session.
Server Scopes
MCP server configurations live at one of three scopes, and the scope determines who can see and use the server.
Local (default) stores the config in ~/.claude.json. The server is available only to you on this machine. Pick this scope for personal tools, local databases, or servers you’re experimenting with.
Project stores the config in .mcp.json at your project root. This file is meant to be committed to Git and shared with your team, so everyone who clones the repo gets the same MCP server configuration. It’s the right choice for team databases, shared documentation servers, or project-specific tools.
User stores the config in your user settings. The server is available to you across all projects on this machine. Use this for personal productivity tools you rely on everywhere.
# Local scope (default)claude mcp add my-tool -- npx @my/tool
# Project scope (creates/updates .mcp.json)claude mcp add team-db --scope project -- npx @mcp/postgres $DB_URL
# User scopeclaude mcp add my-notes --scope user -- npx @mcp/notes.mcp.json Format
The .mcp.json file at your project root defines project scoped MCP servers. It’s a JSON file with a mcpServers object where each key is a server name and each value contains that server’s configuration.
{ "mcpServers": { "database": { "command": "npx", "args": ["@mcp/postgres", "postgresql://localhost/mydb"], "env": { "DB_PASSWORD": "${DB_PASSWORD}" } }, "docs": { "command": "npx", "args": ["@mcp/docs-search", "--index", "./docs"] }, "cloud-api": { "type": "http", "url": "https://mcp.example.com/api", "headers": { "Authorization": "Bearer ${API_TOKEN}" } } }}Commit this file to Git for team-wide MCP server configuration.
Notice the ${DB_PASSWORD} and ${API_TOKEN} syntax. Environment variables referenced with ${VAR} get expanded at runtime from the developer’s local environment. This means you can safely commit the config file to Git without exposing secrets; each team member just sets the required environment variables locally.
For stdio servers, you’ll specify command and args. For HTTP servers, use type: "http" and url. Both support an env object for passing environment variables to the server process and a headers object for HTTP authentication.
When a team member clones the repo and fires up Claude Code, all project scoped servers defined in .mcp.json start automatically. Each developer only needs to set the required environment variables (like DB_PASSWORD and API_TOKEN in the example above) in their local shell environment.
OAuth Authentication
Some remote MCP servers require OAuth authentication, and Claude Code handles the flow automatically.
/mcpShows connected servers, their status, and whether authentication is needed.
When you add a server that requires OAuth, Claude Code opens your browser for the authorization flow the first time you connect. After you authorize, tokens are stored locally and refreshed automatically. You don’t need to manage tokens yourself.
If a token expires and the automatic refresh fails, Claude Code will prompt you to reauthorize through the browser flow. This typically only happens if the server’s OAuth configuration changes or if the refresh token itself expires.
OAuth tokens are stored locally alongside your Claude Code configuration. They’re never committed to Git or shared with team members. Each developer goes through their own authorization flow the first time they connect to an OAuth-protected server.
Tool Search
When your MCP setup includes lots of servers with lots of tools, loading all of them into Claude Code’s context at once eats up a significant chunk of tokens. Tool search solves this by dynamically loading tools only when Claude Code actually needs them.
It kicks in automatically when context usage exceeds roughly 10% of the available window. At that point, Claude Code unloads MCP tools it isn’t actively using and maintains a search index instead. When a later prompt needs a tool that was unloaded, Claude Code searches the index and reloads the relevant tools transparently.
This is entirely automatic. You don’t need to configure or trigger tool search yourself. From your perspective, tools simply show up when Claude Code needs them.
If you want to control this behavior, the ENABLE_TOOL_SEARCH environment variable lets you toggle tool search on or off.
# Disable tool search (keep all tools loaded)ENABLE_TOOL_SEARCH=false claude
# Force tool search on (useful for debugging)ENABLE_TOOL_SEARCH=true claudeMost users never need to set this. The default auto-detection works well.
MCP Resources
Beyond tools, MCP servers can also expose resources. While tools are actions Claude Code can perform (run a query, create a ticket), resources are data sources it can reference (a database table, an API endpoint, a documentation page).
You reference MCP resources using @ mentions in your prompts.
Tell me about the schema of @database/usersThe @ syntax tells Claude Code to fetch data from the MCP resource.
Resources are read only references. They give Claude Code additional context for its reasoning without triggering any tool calls. Not every MCP server exposes resources, as it depends on the server implementation. Check the server’s documentation to see what’s available.
The distinction between tools and resources matters because of what happens when you mention them. Referencing a resource with @ fetches data and adds it to context. Calling a tool executes an operation that may have side effects (inserting a database row, creating a ticket, sending a notification). Claude Code handles the distinction automatically. Just describe what you need and it’ll figure out the rest.
Managed MCP
If your organization needs to control which MCP servers developers can connect to, Claude Code supports managed MCP configuration. An administrator distributes a managed-mcp.json file that defines organizational servers and access policies.
{ "mcpServers": { "company-db": { "command": "npx", "args": ["@company/mcp-db"], "env": { "DB_HOST": "db.internal.company.com" } } }, "allowedMcpServers": [ "@company/*", "@mcp/postgres" ], "deniedMcpServers": [ "@mcp/shell-exec" ]}Distributed by administrators. Users cannot remove managed servers.
allowedMcpServers is a whitelist of server packages that developers are permitted to add. When it’s set, developers can only add servers matching these patterns.
deniedMcpServers is a blocklist of server packages that are explicitly forbidden, regardless of the allow list.
Managed servers (those defined in managed-mcp.json) can’t be removed or modified by individual users. They’re always available and always connected. This gives organizations control over which external integrations their developers use while still allowing approved additions.
Troubleshooting
When MCP servers aren’t behaving as expected, start with the /mcp status command inside an active Claude Code session.
/mcpThis shows each configured server with its current state: connected (running and responding), errored (started but hit a problem), or disconnected (not running). For errored servers, you’ll also see the error message.
Common Issues
Server not starting. Double check that the command path is correct. If the server is an npm package, make sure it’s installed (npx will auto-install, but network issues can prevent this). Also verify that required environment variables are set.
# Verify the server command works outside Claude Codenpx @mcp/postgres postgresql://localhost/mydb
# Check environment variablesecho $DB_PASSWORDOutput too large. MCP tools have a maximum output size controlled by MAX_MCP_OUTPUT_TOKENS. If a tool returns more data than this limit allows, the output gets truncated. If you’re seeing incomplete results from an MCP tool, try bumping this limit up.
# Increase the maximum output size for MCP toolsMAX_MCP_OUTPUT_TOKENS=50000 claudeDefault is sufficient for most tools. Increase only if you see truncation.
Server timeout. If a server takes too long to respond, Claude Code times out the request. This usually points to a network issue (for HTTP servers) or a slow operation (for database queries). Check your network connectivity and consider whether the operation can be scoped more narrowly.
Authentication failures. For OAuth servers, try reauthenticating by running /mcp and following the auth flow again. For token based auth, verify that the token is still valid and correctly set in your headers or environment variables.
Tool not appearing. If you added a server but its tools don’t show up, check that the server is connected via /mcp. If tool search is active (see the Tool Search section above), the tools may have been unloaded to save context. They’ll appear automatically when Claude Code determines they’re relevant to your prompt. You can also try explicitly mentioning the tool or server name in your prompt to nudge tool search into reloading it.
Configuration not loading. If you added a server via claude mcp add but it doesn’t show up in your next session, verify the scope matches your expectation. A server added with --scope project only appears when Claude Code runs from that project directory. Check ~/.claude.json for local servers and .mcp.json for project servers.
Best Practices
-
Start with stdio for local development. It’s the simplest transport, requires no configuration, and works for the vast majority of use cases. Only move to HTTP when you need remote access or team sharing.
-
Use
.mcp.jsonfor team shared servers. Commit the file to Git so every team member gets the same MCP configuration. Use${VAR}expansion for secrets to keep credentials out of version control. -
Use environment variable expansion for secrets. Never hardcode API keys, database passwords, or tokens in
.mcp.json. Stick with${VAR}syntax and document which environment variables each team member needs to set. -
Prefer HTTP over SSE for remote servers. SSE is deprecated and will be removed. All new remote server configurations should use HTTP transport.
-
Keep your MCP server count manageable. Each connected server and its tools eat into context window space. Only connect the servers you’re actively using for a project, and remove the ones you no longer need.
-
Verify connections with
/mcpbefore relying on tools. After adding or modifying server configurations, check that everything is connected before kicking off a task that depends on MCP tools. -
Scope servers appropriately. Use local scope for personal experimentation, project scope for team infrastructure, and user scope for personal tools you use across all projects.
Further Reading
- Model Context Protocol, official documentation on transports, scopes, OAuth, and managed MCP
- MCP Specification, the protocol specification and server registry
Next, learn how to create custom skills that extend Claude Code’s capabilities in Custom Skills.