Claude MCP Servers: How to Extend Claude with Custom Tools
MCP (Model Context Protocol) servers are local processes that expose tools, resources, and prompts to Claude — letting Claude Code call your internal databases, APIs, and scripts directly without any custom app code. You register an MCP server once in your config, and every Claude Code session on that machine can use it. This guide covers how to install existing servers, build your own in Python, and when to use MCP instead of the tool use API.
What MCP is and why it matters
The Model Context Protocol is an open standard that defines how a host (Claude Code) discovers and calls capabilities from a server process running on your machine. An MCP server advertises three things:
- Tools — functions Claude can call (read a file, query a database, run a script)
- Resources — data sources Claude can read (files, database schemas, API responses)
- Prompts — reusable prompt templates for common workflows
Before MCP, extending Claude meant either writing a custom application using the tool use API or pasting data into the conversation manually. MCP gives Claude Code a standard plug-in interface: write a server once, use it everywhere Claude Code runs.
The protocol runs over stdio or HTTP. Claude Code spawns the server process on startup and communicates with it over standard input/output. The server process lives on your machine — nothing is sent to Anthropic's servers except the tool results that Claude needs to form its response.
MCP vs the tool use API
These two extension mechanisms solve different problems and are not interchangeable:
| MCP | Tool use API | |
|---|---|---|
| Where it runs | Claude Code (CLI) | Custom applications via messages.create() |
| Setup | Config file entry, server process | Define tools inline in your API call |
| Persistence | Server stays running across sessions | Tools defined per API call |
| Best for | Developer workflows, local data sources, internal tooling | Web apps, production backends, user-facing features |
| Who calls the tool | Claude Code orchestrates automatically | Your application code handles the loop |
If you are building a web application that uses Claude to help users, use the tool use API. If you are extending your own Claude Code workflow to connect to a private database or internal API, use MCP. The distinction is: tool use is for apps you ship, MCP is for tools you use.
Installing existing MCP servers in Claude Code
Anthropic and the community maintain a growing registry of ready-to-use MCP servers. Installing one requires two things: the server package (usually an npm package) and a config entry telling Claude Code how to start it.
Add servers to ~/.claude/claude_desktop_config.json for global availability, or to .claude/settings.json in a project directory for project-scoped access:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allow"]
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "your-token"
}
}
}
}
The command and args fields define how Claude Code spawns the server. The env field injects environment variables into the server process — use this for API keys and credentials rather than hardcoding them in the server itself.
After saving the config, restart Claude Code. Run /mcp in Claude Code to confirm the servers are connected and their tools are available.
Popular MCP servers worth installing
@modelcontextprotocol/server-filesystem — Gives Claude read and write access to a specified directory. Useful for letting Claude Code work with files outside the current project.
@modelcontextprotocol/server-github — Full GitHub API access: read issues and PRs, create branches, push commits, manage repositories. Requires a personal access token with appropriate scopes.
@modelcontextprotocol/server-slack — Read and post messages, search channels, look up users. Useful for building Claude-assisted summaries or notifications into your workflow.
@modelcontextprotocol/server-postgres — Query a PostgreSQL database directly from Claude Code. Claude can inspect schemas, run read queries, and use the results in its responses without you copying data manually.
@modelcontextprotocol/server-brave-search — Web search via Brave Search API. Gives Claude access to current information without leaving Claude Code.
@playwright/mcp — Browser automation. Claude can navigate pages, extract content, fill forms, and take screenshots. Useful for scraping and testing workflows.
Building your own MCP server in Python
The mcp Python package provides a server framework that handles the protocol details. Install it with pip install mcp.
A minimal server has two handlers: one that lists available tools, and one that executes them:
from mcp.server import Server
from mcp.server.models import InitializationOptions
import mcp.types as types
server = Server("my-tools")
@server.list_tools()
async def handle_list_tools() -> list[types.Tool]:
return [
types.Tool(
name="get_weather",
description="Get current weather for a city",
inputSchema={
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name"}
},
"required": ["city"]
}
)
]
@server.call_tool()
async def handle_call_tool(name: str, arguments: dict) -> list[types.TextContent]:
if name == "get_weather":
city = arguments["city"]
# Your actual implementation here
return [types.TextContent(type="text", text=f"Weather in {city}: 22°C, partly cloudy")]
raise ValueError(f"Unknown tool: {name}")
To run the server over stdio (the default Claude Code transport), add an entry point:
import asyncio
from mcp.server.stdio import stdio_server
async def main():
async with stdio_server() as (read_stream, write_stream):
await server.run(
read_stream,
write_stream,
InitializationOptions(
server_name="my-tools",
server_version="0.1.0",
),
)
if __name__ == "__main__":
asyncio.run(main())
Save this as my_mcp_server.py, then register it in your config:
{
"mcpServers": {
"my-tools": {
"command": "python",
"args": ["/absolute/path/to/my_mcp_server.py"]
}
}
}
Use an absolute path. Claude Code spawns the server from its own working directory, not yours, so relative paths will fail.
Adding resources and prompts
Beyond tools, MCP servers can expose resources (data Claude can read on demand) and prompts (reusable templates).
A resource handler looks similar to a tool handler:
@server.list_resources()
async def handle_list_resources() -> list[types.Resource]:
return [
types.Resource(
uri="db://schema",
name="Database Schema",
description="Current schema for the production database",
mimeType="text/plain"
)
]
@server.read_resource()
async def handle_read_resource(uri: str) -> str:
if uri == "db://schema":
# Return your actual schema here
return "CREATE TABLE users (id INT, email TEXT, created_at TIMESTAMP);"
raise ValueError(f"Unknown resource: {uri}")
Resources are useful for giving Claude persistent context — database schemas, API documentation, configuration — without consuming message tokens every turn.
When to use MCP versus tool use
Use MCP when:
- You want the capability available in every Claude Code session without repeating setup
- The tool connects to local infrastructure (databases, internal APIs, local files)
- You are building a developer workflow, not a user-facing product
- You want to keep credentials off the internet and out of application code
Use the tool use API when:
- You are building an application where end users interact with Claude
- You need tools defined dynamically based on user context or permissions
- You are deploying to a server or cloud environment where MCP's local process model does not apply
- You need fine-grained control over which tools are available per request
The two are composable. A production application might use the tool use API to expose safe, user-scoped tools, while the developer building that application uses MCP servers locally to inspect the database and debug the API.
Security considerations
MCP servers run as processes on your machine. A few practices to keep in mind:
Do not put credentials in MCP server code. Use the env field in claude_desktop_config.json to pass API keys at runtime. The config file itself should have restricted read permissions (chmod 600).
Scope filesystem access tightly. The filesystem MCP server takes a path argument that defines what Claude can access. Pass the smallest directory that covers your actual use case, not /.
MCP servers are local only. They are not accessible from the internet unless you explicitly expose them. Claude Code connects over stdio or localhost — there is no inbound network surface by default.
Review tool descriptions. Claude decides which tools to call based on the description you write. Vague descriptions cause Claude to use tools at unexpected times. Be specific about what a tool does and when it should be called.
Pin package versions. Using npx -y @modelcontextprotocol/server-github always pulls the latest version. In a stable development environment, pin the version explicitly in the args to avoid breaking changes.
Frequently asked questions
What is an MCP server in simple terms? An MCP server is a small program that runs on your computer and gives Claude Code new abilities — like reading your database, searching GitHub, or calling an internal API. You register it once in a config file and Claude Code can use those abilities in any conversation.
Do MCP servers send my data to Anthropic? The MCP server itself runs entirely on your machine. When Claude calls an MCP tool, the tool result is included in the conversation that goes to Anthropic's API, the same way any message content does. The server code, credentials, and internal systems are not exposed — only the result Claude needs.
Can I use MCP servers with the Claude API (not Claude Code)?
Not directly. MCP is a protocol for Claude Code and the Claude desktop app. To add custom tools when calling the Claude API from your own code, use the tool use API (tools parameter in messages.create()). The underlying capability is similar but the integration path is different.
How many MCP servers can I run at once? There is no hard limit. Claude Code connects to all servers listed in your config and merges their tools into one list. In practice, running more than 10-15 servers can slow down Claude Code startup. Keep your config to servers you actually use.
What languages can I use to build MCP servers? Anthropic maintains official SDKs for Python and TypeScript. Community SDKs exist for Go, Rust, and other languages. The protocol is language-agnostic — any process that can read and write JSON over stdio can implement it.
Take It Further
Claude Agent SDK Cookbook: 40 Production Patterns — Pattern 12 covers MCP Server Development: the full Python MCP server template, resource and prompt handling, testing MCP servers locally, and the patterns for connecting Claude Code to your internal databases and APIs without exposing them to the internet.
→ Get the Agent SDK Cookbook — $49
30-day money-back guarantee. Instant download.