Claude Code MCP Servers#
Model Context Protocol (MCP) is an open standard for connecting AI models to external tools and data sources. Claude Code acts as an MCP client β you add MCP servers to extend what Claude can do beyond its built-in tools.
Concept#
Without MCP, Claude Code has built-in tools: Read, Edit, Write, Bash, Glob, Grep, WebSearch, WebFetch. With an MCP server, you add arbitrary new tools β databases, APIs, Slack, GitHub, custom scripts β and Claude can call them like any other tool.
Claude Code (MCP client)
β MCP protocol
MCP Server (exposes tools)
β native API
Postgres / GitHub / Slack / your API
Transport methods#
| Transport | When to use | Latency | Setup |
|---|---|---|---|
stdio | Local processes, CLI tools | Lowest | Simplest |
sse (Server-Sent Events) | Remote servers, shared team servers | Medium | Needs HTTP server |
http | REST-compatible MCP servers | Medium | Needs HTTP server |
Add a server β CLI#
# Add a stdio server (local process)
claude mcp add my-server -- node /path/to/server.js
# Add an HTTP/SSE server (remote)
claude mcp add my-remote-server --transport sse https://mcp.example.com/sse
# Add with environment variables
claude mcp add my-db -- node /path/to/db-server.js --env DATABASE_URL=postgresql://localhost/mydb
Output:
β
Added MCP server "my-server"
List connected servers#
claude mcp list
Output:
my-server stdio node /path/to/server.js β
connected
github stdio npx @modelcontextprotocol/server-github β
connected
postgres stdio npx @modelcontextprotocol/server-postgres β
connected
Remove a server#
claude mcp remove my-server
MCP in settings.json#
For team-shared or committed server configs, define them in .claude/settings.json:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
}
},
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres", "${DATABASE_URL}"]
},
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/jay/Code"]
}
}
}
[!TIP] Use
${ENV_VAR}syntax in settings.json to reference environment variables without hardcoding secrets. The value is expanded at runtime from the shell environment.
Useful MCP servers#
GitHub#
claude mcp add github -- npx -y @modelcontextprotocol/server-github
Gives Claude tools to search repos, read files, create issues, open PRs, and review code β all authenticated with your GitHub token.
Required env: GITHUB_PERSONAL_ACCESS_TOKEN
Tools added: create_or_update_file, search_repositories, create_issue, create_pull_request, list_commits, get_file_contents, and more.
PostgreSQL#
claude mcp add postgres -- npx -y @modelcontextprotocol/server-postgres "$DATABASE_URL"
Gives Claude read-only access to your Postgres database β schema inspection, query execution, table listings.
Tools added: query, list_tables, describe_table.
Example use:
> What are the 5 most recently created users in the database?
Filesystem (extended)#
claude mcp add filesystem -- npx -y @modelcontextprotocol/server-filesystem /path/to/root
Extends Claudeβs file access beyond the current directory. Useful for referencing shared docs or a monorepo root from a subdirectory.
Fetch (web scraping)#
claude mcp add fetch -- npx -y @modelcontextprotocol/server-fetch
Gives Claude a fetch tool for retrieving web pages as plain text. Useful for pulling documentation from URLs during a session.
Brave Search#
claude mcp add brave-search -- npx -y @modelcontextprotocol/server-brave-search
Required env: BRAVE_API_KEY (free tier available)
Replaces WebSearch with Brave Search results, which can be more complete than the default.
Slack#
claude mcp add slack -- npx -y @modelcontextprotocol/server-slack
Required env: SLACK_BOT_TOKEN, SLACK_TEAM_ID
Gives Claude tools to read channels, post messages, and search Slack history.
Memory (persistent)#
claude mcp add memory -- npx -y @modelcontextprotocol/server-memory
Gives Claude a key-value store that persists between sessions. Claude can save and recall facts using store_memory and retrieve_memory tools.
Build your own MCP server#
A minimal stdio MCP server in Python:
# my_server.py
import json, sys
def handle(request):
if request["method"] == "tools/list":
return {
"tools": [{
"name": "get_build_status",
"description": "Get the current CI build status for a branch.",
"inputSchema": {
"type": "object",
"properties": {
"branch": {"type": "string", "description": "Git branch name"}
},
"required": ["branch"]
}
}]
}
elif request["method"] == "tools/call":
if request["params"]["name"] == "get_build_status":
branch = request["params"]["arguments"]["branch"]
# Replace with real CI API call
return {"content": [{"type": "text", "text": f"Branch '{branch}': passing"}]}
for line in sys.stdin:
req = json.loads(line)
result = handle(req)
sys.stdout.write(json.dumps({"jsonrpc": "2.0", "id": req.get("id"), "result": result}) + "\n")
sys.stdout.flush()
Add it:
claude mcp add ci-status -- python3 /path/to/my_server.py
Now Claude can call get_build_status(branch="main") during a session.
Check MCP status in-session#
> /mcp
Output:
Connected MCP servers:
github (8 tools) β
postgres (3 tools) β
memory (2 tools) β
MCP permission rules#
MCP tools follow the same permission system as built-in tools. Deny or allow specific MCP tools in settings.json:
{
"permissions": {
"allow": [
"mcp__github__search_repositories",
"mcp__github__get_file_contents",
"mcp__postgres__query"
],
"deny": [
"mcp__github__create_pull_request",
"mcp__github__delete_file",
"mcp__slack__post_message"
]
}
}
MCP tool names follow the pattern mcp__<server-name>__<tool-name>.