Lesson 09: MCP Servers
What Is MCP?
MCP (Model Context Protocol) is an open standard that lets Claude connect to external tools, data sources, and services. Think of MCP servers as plugins that extend what Claude Code can do beyond its built-in capabilities.
Without MCP, Claude can:
- Read and write files in your project
- Run shell commands
- Search your codebase
With MCP, Claude can also:
- Query your actual database with natural language
- Create GitHub issues and pull requests
- Monitor errors in Sentry
- Read your Slack messages and send drafts
- Access your Jira, Linear, or Asana tickets
- Integrate with Figma designs
- Connect to hundreds of other tools and APIs
You ←→ Claude Code (MCP Client) ←→ MCP Server ←→ External ServiceAn MCP server exposes tools (functions Claude can call) and optional resources (data Claude can read). Claude sees MCP tools alongside its built-in tools and decides when to use them based on your requests.
Adding MCP Servers with the CLI
The claude mcp add command is the primary way to connect MCP servers. There are three transport types depending on where the server runs.
Adding a Remote HTTP Server (Recommended)
HTTP is the recommended transport for cloud-based MCP servers. Most hosted services use this:
# Basic syntax
claude mcp add --transport http <name> <url>
# Connect to Notion
claude mcp add --transport http notion https://mcp.notion.com/mcp
# Connect to Sentry for error monitoring
claude mcp add --transport http sentry https://mcp.sentry.dev/mcp
# Connect to GitHub
claude mcp add --transport http github https://api.githubcopilot.com/mcp/
# With a Bearer token for authentication
claude mcp add --transport http secure-api https://api.example.com/mcp \
--header "Authorization: Bearer your-token"Adding a Remote SSE Server (Deprecated)
SSE (Server-Sent Events) is an older transport. Use HTTP instead where available:
# Basic syntax
claude mcp add --transport sse <name> <url>
# With an API key header
claude mcp add --transport sse private-api https://api.company.com/sse \
--header "X-API-Key: your-key-here"Adding a Local stdio Server
Stdio servers run as local processes on your machine. They are ideal for tools that need direct system access:
# Basic syntax
claude mcp add [options] <name> -- <command> [args...]
# Add a PostgreSQL database server
claude mcp add --transport stdio db -- npx -y @bytebase/dbhub \
--dsn "postgresql://readonly:pass@localhost:5432/mydb"
# Add Airtable with an environment variable
claude mcp add --transport stdio --env AIRTABLE_API_KEY=YOUR_KEY airtable \
-- npx -y airtable-mcp-server
# Add a custom local server
claude mcp add --transport stdio my-tools -- node /path/to/my-server.jsImportant: Option ordering. All flags (
--transport,--env,--scope,--header) must come before the server name. The--separates the server name from the command that launches the MCP server process. This prevents conflicts between Claude's flags and the server's flags.
Windows users: On native Windows (not WSL), local MCP servers using
npxrequire thecmd /cwrapper. Without it, you will get "Connection closed" errors.Bashclaude mcp add --transport stdio my-server -- cmd /c npx -y @some/package
Adding from JSON Configuration
If you have a JSON configuration (for example, from documentation or a teammate), add it directly:
# HTTP server from JSON
claude mcp add-json weather-api '{"type":"http","url":"https://api.weather.com/mcp","headers":{"Authorization":"Bearer token"}}'
# stdio server from JSON
claude mcp add-json local-tools '{"type":"stdio","command":"/path/to/server","args":["--config","prod"],"env":{"API_KEY":"abc123"}}'Importing from Claude Desktop
If you already have MCP servers configured in Claude Desktop, import them:
# Interactive dialog to select which servers to import
claude mcp add-from-claude-desktopThis reads the Claude Desktop configuration file and lets you select which servers to bring over.
Managing MCP Servers
Once configured, manage your 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
# Reset project approval choices (for .mcp.json servers)
claude mcp reset-project-choicesInside a Claude Code session, use the /mcp command to see all server statuses, authenticate with OAuth servers, and troubleshoot connection issues:
> /mcpConfiguration Scopes and File Locations
MCP servers can be configured at three scope levels using the --scope flag:
| Scope | Flag | Stored In | Use Case |
|---|---|---|---|
| Local (default) | --scope local |
~/.claude.json (under project path) |
Personal servers for this project only |
| Project | --scope project |
.mcp.json in project root |
Team-shared servers (commit to version control) |
| User | --scope user |
~/.claude.json |
Personal servers across all projects |
# Add to local scope (default — only you, only this project)
claude mcp add --transport http stripe https://mcp.stripe.com
# Add to project scope (shared with team via .mcp.json)
claude mcp add --transport http paypal --scope project https://mcp.paypal.com/mcp
# Add to user scope (available in all your projects)
claude mcp add --transport http hubspot --scope user https://mcp.hubspot.com/anthropicThe `.mcp.json` File
Project-scoped servers are stored in .mcp.json at your project root. This file is designed to be committed to version control so your whole team gets the same MCP tools:
{
"mcpServers": {
"project-db": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@bytebase/dbhub", "--dsn", "postgresql://localhost/myproject"],
"env": {}
},
"company-api": {
"type": "http",
"url": "${API_BASE_URL:-https://api.company.com}/mcp",
"headers": {
"Authorization": "Bearer ${API_KEY}"
}
}
}
}Notice the environment variable expansion — .mcp.json supports ${VAR} and ${VAR:-default} syntax in command, args, env, url, and headers fields. This lets you share configuration while keeping secrets in each developer's environment.
Scope Precedence
When servers with the same name exist at multiple scopes, local takes priority over project, which takes priority over user. This lets personal configurations override shared ones.
OAuth Authentication
Many remote MCP servers require authentication. Claude Code supports OAuth 2.0 for secure connections.
Standard OAuth Flow
For servers that support dynamic client registration, the flow is simple:
# 1. Add the server
claude mcp add --transport http sentry https://mcp.sentry.dev/mcp
# 2. Inside Claude Code, authenticate
> /mcp
# Select "Authenticate" for the server — your browser opens for loginAuthentication tokens are stored securely and refreshed automatically. Use "Clear authentication" in the /mcp menu to revoke access.
Pre-Configured OAuth Credentials
Some servers require you to register an OAuth app first. If you see "Incompatible auth server: does not support dynamic client registration," you need to provide credentials manually:
# Register an app in the server's developer portal, then:
claude mcp add --transport http \
--client-id your-client-id --client-secret --callback-port 8080 \
my-server https://mcp.example.com/mcpThe --client-secret flag prompts for the secret with masked input. For CI environments, set it via environment variable:
MCP_CLIENT_SECRET=your-secret claude mcp add --transport http \
--client-id your-client-id --client-secret --callback-port 8080 \
my-server https://mcp.example.com/mcpYou can also use claude mcp add-json with an oauth object:
claude mcp add-json my-server \
'{"type":"http","url":"https://mcp.example.com/mcp","oauth":{"clientId":"your-client-id","callbackPort":8080}}' \
--client-secretThe client secret is stored securely in your system keychain or a credentials file, never in your config files.
Popular MCP Servers
Here are some high-value MCP servers to consider:
GitHub — Code Reviews and Issue Management
claude mcp add --transport http github https://api.githubcopilot.com/mcp/Then in Claude Code:
> "Review PR #456 and suggest improvements"
> "Create a new issue for the authentication bug we found"
> "Show me all open PRs assigned to me"PostgreSQL — Database Queries
claude mcp add --transport stdio db -- npx -y @bytebase/dbhub \
--dsn "postgresql://readonly:pass@localhost:5432/analytics"Then in Claude Code:
> "What's our total revenue this month?"
> "Show me the schema for the orders table"
> "Find customers who haven't purchased in 90 days"Sentry — Error Monitoring
claude mcp add --transport http sentry https://mcp.sentry.dev/mcpThen authenticate with /mcp and ask:
> "What are the most common errors in the last 24 hours?"
> "Show me the stack trace for error ID abc123"
> "Which deployment introduced these new errors?"Puppeteer — Browser Automation
claude mcp add --transport stdio puppeteer -- npx -y @modelcontextprotocol/server-puppeteerClaude can take screenshots, fill forms, and click buttons in a real browser.
Filesystem — Extended File Access
claude mcp add --transport stdio filesystem -- npx -y @modelcontextprotocol/server-filesystem /path/to/allowProvides more powerful file access than Claude Code's built-in file tools, scoped to specific directories.
Need more? Find hundreds of community MCP servers on GitHub, or check the MCP server registry built into the official documentation.
Using MCP Resources
MCP servers can expose resources that you reference with @ mentions, similar to how you reference files:
> Can you analyze @github:issue://123 and suggest a fix?
> Compare @postgres:schema://users with @docs:file://database/user-modelType @ in your prompt to see available resources from all connected servers. Resources are automatically fetched and included as context.
Using Claude Code as an MCP Server
Claude Code itself can act as an MCP server for other applications:
# Start Claude Code as a stdio MCP server
claude mcp serveAdd it to Claude Desktop's configuration file:
{
"mcpServers": {
"claude-code": {
"type": "stdio",
"command": "claude",
"args": ["mcp", "serve"],
"env": {}
}
}
}This gives other MCP clients access to Claude Code's tools (file editing, searching, and so on).
Security Considerations
MCP servers have real access to real systems. Follow these practices:
- Audit before installing. Use third-party MCP servers at your own risk. Anthropic has not verified the correctness or security of all community servers. Be especially careful with servers that fetch untrusted content — these can expose you to prompt injection risk.
- Scope database access. Create read-only database users for Claude. Never give Claude write access to production data unless you have reviewed the tools it exposes.
- Use environment variables for secrets. Never hardcode API keys in
.mcp.jsonfiles that get committed to version control. Use${VAR}expansion syntax instead. - Review tool permissions. A tool named
runArbitrarySQLis far more dangerous thanqueryReadOnly. Understand what each MCP server's tools can do. - Project-scoped server approval. Claude Code prompts for approval before using servers from
.mcp.jsonfiles. This prevents malicious repositories from automatically connecting to arbitrary services. - Managed configuration for organizations. Administrators can deploy a
managed-mcp.jsonfile to control exactly which MCP servers are available, or use allowlists and denylists to set policy.
Debugging MCP Connections
When an MCP server is not working, use these steps to diagnose the problem:
Check Server Status
Inside Claude Code, run /mcp to see which servers are connected, failed, or degraded. This is your first diagnostic tool.
Common Issues and Fixes
| Problem | Cause | Solution |
|---|---|---|
| "Connection closed" on Windows | Windows cannot execute npx directly |
Use cmd /c wrapper: -- cmd /c npx -y @some/package |
| Server times out on startup | Slow npm install or network | Increase timeout: MCP_TIMEOUT=10000 claude |
| "Connection failed" error | Wrong command path or missing dependency | Verify the command works manually in your terminal |
| OAuth authentication fails | Browser did not open or token expired | Run /mcp, select the server, choose "Authenticate" |
| Output truncation warnings | MCP tool returned too much data | Set MAX_MCP_OUTPUT_TOKENS=50000 or configure the server to paginate |
| Tools not appearing | Server connected but tools not loaded | Check if Tool Search is active (auto-enabled when tools exceed 10% of context) |
Verify Your Configuration
# Check what is configured
claude mcp list
# Inspect a specific server's configuration
claude mcp get my-server
# Remove and re-add a problematic server
claude mcp remove my-server
claude mcp add --transport http my-server https://example.com/mcpTest stdio Servers Manually
For local stdio servers, verify the command works outside of Claude Code:
# Does the command run at all?
npx -y @modelcontextprotocol/server-postgres postgresql://localhost/mydb
# Check for missing dependencies
which npx
node --versionEnvironment Variable Tips
- Use absolute paths in configuration and
.envfiles — the working directory for MCP server processes may be undefined. - For stdio servers, messages logged to
stderrare captured by Claude Code for debugging. Servers should never log tostdoutas that interferes with the MCP protocol. - Set
MCP_TIMEOUTto increase the startup timeout (default is a few seconds; set to milliseconds like10000for 10 seconds).
Practical Exercise
- Add a remote server. Connect to GitHub with HTTP transport:Bash
claude mcp add --transport http github https://api.githubcopilot.com/mcp/ - Authenticate. Open Claude Code and run
/mcp, then authenticate with GitHub in your browser. - Use it. Ask Claude: "List my open GitHub issues and summarize the most urgent ones."
- Check status. Run
/mcpagain to see the server's connection status and available tools. - Try a database. If you have a local PostgreSQL database, connect it:Then ask Claude: "Show me all tables in the database and describe the schema."Bash
claude mcp add --transport stdio db -- npx -y @bytebase/dbhub \ --dsn "postgresql://localhost/mydb"
Notice how Claude interacts with external services naturally, without you needing to copy-paste data or switch between tools.