Model Context Protocol (MCP)
Connect Claude Code to external data sources, APIs, and tools through the Model Context Protocol. Extend capabilities with resources, prompts, and tools from MCP servers.
Overview
The Model Context Protocol (MCP) is an open protocol that standardizes how applications provide context to LLMs. MCP servers expose resources, prompts, and tools that Claude Code can use during conversations.
Resources
Access external data sources like databases, file systems, and APIs
Prompts
Reusable prompt templates with context from external sources
Tools
External functions Claude can invoke during execution
Flexible Transports
Connect via HTTP, SSE, or Stdio for any environment
Installation Methods
MCP servers can connect using three transport protocols, each suited for different deployment scenarios.
HTTP Transport
Best for remote MCP servers accessible via HTTP endpoints. Supports standard REST-style communication.
# Add an HTTP MCP server
claude mcp add --transport http server-name https://api.example.com/mcp
# Example: Adding a remote service
claude mcp add --transport http analytics https://analytics.example.com/mcp
SSE Transport (Server-Sent Events)
For real-time streaming connections. Ideal for servers that push updates to clients.
# Add an SSE MCP server
claude mcp add --transport sse server-name https://stream.example.com/mcp
# Example: Real-time monitoring
claude mcp add --transport sse monitoring https://monitor.example.com/events
Stdio Transport
For local executables. Claude Code launches the process and communicates via standard input/output.
# Add a stdio MCP server
claude mcp add --transport stdio server-name -- command arg1 arg2
# Example: NPX-based server
claude mcp add --transport stdio github -- npx -y @modelcontextprotocol/server-github
# Example: Python server with arguments
claude mcp add --transport stdio postgres -- uvx mcp-server-postgres --db-url postgresql://localhost/mydb
# Example: With environment variables
claude mcp add --transport stdio sentry -- npx -y @modelcontextprotocol/server-sentry
Note: The -- separator is required for stdio transport to distinguish the server name from the command arguments.
Server Management Commands
List All MCP Servers
# Show all configured MCP servers
claude mcp list
# Example output:
# Name Scope Transport Status
# github local stdio active
# postgres project stdio active
# analytics user http inactive
Get Server Details
# View detailed information about a specific server
claude mcp get server-name
# Shows: configuration, environment variables, capabilities, status
Remove MCP Server
# Remove a server from configuration
claude mcp remove server-name
# Removes from the appropriate scope (local/project/user)
Interactive Management
Open the interactive MCP management interface:
/mcp
This command provides a visual interface to:
- Browse available MCP servers
- Add new servers with guided configuration
- Edit server settings and environment variables
- Remove servers
- Test server connections
- Authenticate with OAuth when required
MCP Installation Scopes
MCP servers can be configured at three different scopes, each with different visibility and persistence.
| Scope | Location | Visibility | Default |
|---|---|---|---|
| Local | In-memory (session only) | Current session only | Yes |
| Project | .mcp.json |
Current project, version controlled | No |
| User | ~/.claude.json |
All projects for this user | No |
Scope Precedence
When multiple scopes define the same server name, Claude Code uses this priority order:
local > project > user
This allows you to override project or user defaults with session-specific configurations.
Specifying Scope During Installation
# Add to project scope (creates/updates .mcp.json)
claude mcp add --scope project --transport stdio github -- npx -y @modelcontextprotocol/server-github
# Add to user scope (updates ~/.claude.json)
claude mcp add --scope user --transport http analytics https://analytics.example.com/mcp
# Add to local scope (default, session only)
claude mcp add --transport stdio temp-server -- python server.py
Configuration
.mcp.json Format
Project-level MCP configuration file stored at the root of your project:
{
"mcpServers": {
"github": {
"transport": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
},
"postgres": {
"transport": "stdio",
"command": "uvx",
"args": [
"mcp-server-postgres",
"--db-url",
"postgresql://${DB_USER}:${DB_PASSWORD}@localhost/mydb"
]
},
"analytics": {
"transport": "http",
"url": "https://analytics.example.com/mcp",
"headers": {
"Authorization": "Bearer ${ANALYTICS_TOKEN}"
}
}
}
}
Environment Variable Expansion
Use environment variable substitution to keep secrets out of version control:
{
"mcpServers": {
"sentry": {
"transport": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-sentry"],
"env": {
"SENTRY_ORG": "${SENTRY_ORG}",
"SENTRY_TOKEN": "${SENTRY_TOKEN}"
}
}
}
}
Default Values
Provide fallback values when environment variables aren't set:
{
"mcpServers": {
"postgres": {
"transport": "stdio",
"command": "uvx",
"args": [
"mcp-server-postgres",
"--db-url",
"postgresql://${DB_USER:-postgres}:${DB_PASSWORD}@${DB_HOST:-localhost}/${DB_NAME:-myapp}"
]
}
}
}
Security Tip: Always use environment variables for sensitive data like API tokens, passwords, and private keys. Add .env to your .gitignore.
Plugin-Provided MCP Servers
Claude Code plugins can bundle MCP server configurations. When a plugin is installed, its MCP servers become available automatically.
How Plugin Servers Work
- Plugins define MCP servers in their
mcp/directory - Servers are automatically registered when the plugin is active
- Plugin servers appear in
/mcpinterface with a plugin badge - Can be overridden by project or user configurations
Example Plugin Structure
my-plugin/
├── plugin.json
└── mcp/
└── custom-server.json
The plugin's MCP server configuration:
{
"transport": "stdio",
"command": "npx",
"args": ["-y", "my-custom-mcp-server"],
"env": {
"API_KEY": "${MY_PLUGIN_API_KEY}"
}
}
Authentication
Many MCP servers require authentication via OAuth 2.0. Claude Code handles the OAuth flow automatically.
OAuth 2.0 Flow
- Open the
/mcpmenu - Select the server requiring authentication
- Click "Authenticate" or the OAuth prompt
- Complete authentication in your browser
- Tokens are stored securely and refreshed automatically
Supported Authentication Methods
| Method | Description | Example |
|---|---|---|
| OAuth 2.0 | Browser-based authentication flow | GitHub, Google, Slack |
| API Keys | Static tokens via environment variables | OpenAI, Anthropic, Sentry |
| Bearer Tokens | HTTP Authorization headers | Custom APIs |
Revoking Access
# Remove server (also revokes authentication)
claude mcp remove server-name
# Or revoke via /mcp menu > Server Settings > Revoke Access
Practical Examples
GitHub Integration
Access repositories, issues, pull requests, and code search:
# Install GitHub MCP server
claude mcp add --scope project --transport stdio github -- npx -y @modelcontextprotocol/server-github
# Set your GitHub token
export GITHUB_TOKEN=ghp_your_token_here
# Usage examples:
# > @github:repos://owner/repo - Access repository data
# > @github:issues://owner/repo/123 - View specific issue
# > Search GitHub with /mcp__github__search-code
Sentry Error Tracking
Monitor and analyze application errors:
# Install Sentry MCP server
claude mcp add --scope user --transport stdio sentry -- npx -y @modelcontextprotocol/server-sentry
# Configure with environment variables
export SENTRY_ORG=my-organization
export SENTRY_TOKEN=sntrys_your_token_here
# Usage:
# > @sentry:issues://project-slug - List recent issues
# > @sentry:events://issue-id - View error events
# > Analyze error trends with MCP tools
PostgreSQL Database
Query and analyze database schema and data:
# Install PostgreSQL MCP server
claude mcp add --scope project --transport stdio postgres -- uvx mcp-server-postgres --db-url postgresql://localhost/mydb
# With credentials via environment
export DB_USER=postgres
export DB_PASSWORD=secret
claude mcp add --scope project --transport stdio postgres -- uvx mcp-server-postgres --db-url "postgresql://${DB_USER}:${DB_PASSWORD}@localhost/mydb"
# Usage:
# > @postgres:schema://table_name - View table schema
# > @postgres:query://SELECT * FROM users LIMIT 10 - Execute queries
# > Ask Claude to analyze database structure
Filesystem Access
Provide access to specific directories outside the project:
# Install filesystem MCP server
claude mcp add --scope user --transport stdio filesystem -- npx -y @modelcontextprotocol/server-filesystem /path/to/allowed/directory
# Usage:
# > @filesystem:read://path/to/file.txt - Read files
# > @filesystem:list://path/to/directory - List directory contents
Advanced Configuration
Add Server from JSON
Programmatically configure servers with full control:
claude mcp add-json server-name '{
"transport": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-custom"],
"env": {
"API_KEY": "${CUSTOM_API_KEY}",
"API_URL": "https://api.example.com"
}
}'
Import from Claude Desktop
Migrate MCP configurations from Claude Desktop app:
# Import all MCP servers from Claude Desktop config
claude mcp import ~/Library/Application\ Support/Claude/claude_desktop_config.json
# Servers are imported to user scope by default
Serve as MCP Server
Expose your local Claude Code instance as an MCP server for other applications:
# Start Claude Code as an MCP server on stdio
claude mcp serve
# With HTTP transport
claude mcp serve --transport http --port 3000
# Other MCP clients can now connect to your Claude Code instance
Custom Server Development
Build your own MCP server using the official SDKs:
// TypeScript/JavaScript
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new Server({
name: "my-custom-server",
version: "1.0.0"
}, {
capabilities: {
resources: {},
tools: {},
prompts: {}
}
});
// Define resources, tools, and prompts
server.setRequestHandler(ListResourcesRequestSchema, async () => {
return {
resources: [
{ uri: "custom://resource", name: "My Resource" }
]
};
});
const transport = new StdioServerTransport();
await server.connect(transport);
# Python
from mcp.server import Server
from mcp.server.stdio import stdio_server
app = Server("my-custom-server")
@app.list_resources()
async def list_resources():
return [
{
"uri": "custom://resource",
"name": "My Resource"
}
]
if __name__ == "__main__":
stdio_server(app)
MCP Resources & Prompts
Resources
Reference external data in your conversations using the @ syntax:
# General syntax
@server-name:resource://path
# Examples
@github:repos://anthropics/anthropic-sdk-python
@sentry:issues://my-project
@postgres:schema://users
@filesystem:read:///etc/hosts
# In conversation:
> Analyze the recent issues in @sentry:issues://my-project and suggest fixes
Prompts
Execute predefined prompts from MCP servers using slash commands:
# General syntax
/mcp__server-name__prompt-name
# Examples
/mcp__github__search-code
/mcp__sentry__analyze-errors
/mcp__postgres__explain-query
# Prompts can accept parameters via the interactive interface
Listing Available Resources
Discover what resources and prompts are available from your MCP servers:
# Open MCP menu to browse
/mcp
# Then navigate to:
# - Resources tab to see all available @ references
# - Prompts tab to see all available / commands
Output Limits
MCP resources and tool outputs are subject to size limits to prevent context window overflow:
| Resource Type | Limit | Behavior |
|---|---|---|
| Resource content | 1 MB per resource | Truncated with warning |
| Tool output | 500 KB per call | Truncated with warning |
| Total MCP context | Shares conversation context limit | Managed automatically |
Best Practice: For large datasets, use MCP tools to filter or paginate data before retrieving. Design resources to return summaries with options to drill down.
Enterprise Configuration
Organizations can manage MCP servers centrally using the managed configuration file.
Managed Configuration
Located at ~/.claude/managed-mcp.json (or organization-specific path), this file is managed by IT administrators:
{
"allowedServers": [
"github",
"sentry",
"postgres",
"internal-tools"
],
"deniedServers": [
"filesystem",
"exec"
],
"requiredServers": {
"corporate-mcp": {
"transport": "http",
"url": "https://mcp.corp.example.com",
"headers": {
"Authorization": "Bearer ${CORP_MCP_TOKEN}"
}
}
}
}
Allowlist / Denylist
| Configuration | Effect | Use Case |
|---|---|---|
allowedServers |
Only listed servers can be installed | Strict security environments |
deniedServers |
Listed servers are blocked | Block specific risky servers |
requiredServers |
Automatically installed for all users | Corporate integrations |
Precedence Rules
- Managed configuration takes highest priority
- Users cannot override denied servers
- Required servers are always available
- Allowlist is enforced across all scopes
Best Practices
Use Project Scope for Team Servers
Configure shared MCP servers in .mcp.json and commit to version control so the entire team has consistent access.
Protect Secrets with Environment Variables
Never hardcode API keys or tokens. Always use ${VAR} syntax and keep secrets in .env files excluded from version control.
Use User Scope for Personal Tools
Configure personal productivity servers (notes, tasks, calendar) in user scope so they're available across all projects.
Test Servers After Installation
Use /mcp menu to verify servers connect successfully and authenticate properly before relying on them.
Design Focused Resources
When building custom MCP servers, provide granular resources rather than dumping entire datasets. Use pagination and filtering.
Document Server Purpose
Add comments in .mcp.json explaining what each server provides and when to use it.
Monitor Resource Usage
Be mindful of output limits. Large resources consume context window space that could be used for conversation.
Provide Default Values
Use ${VAR:-default} syntax to make servers work out of the box with sensible defaults while allowing customization.