TOC
What Is MCP (Model Context Protocol)?
MCP (Model Context Protocol) is an open standard developed by Anthropic that enables AI assistants like Claude to connect with external data sources and tools. Think of it as a universal plugin system — MCP servers expose capabilities (called “tools”) that Claude can call to interact with databases, APIs, file systems, and custom business logic.
Why Build a Custom MCP Server?
- Connect Claude to your internal APIs — Let Claude query your company databases, CRM, or internal tools
- Automate workflows — Give Claude the ability to trigger deployments, update tickets, or send notifications
- Access private data — Connect Claude to data sources it can’t reach through the public internet
- Custom business logic — Implement domain-specific calculations or transformations
Prerequisites
- Python 3.10+
- Claude Code or Claude Desktop installed
- Basic familiarity with Python async/await
Step 1: Install the MCP Python SDK
pip install mcp
Step 2: Create Your Server
Create a new file called my_server.py:
from mcp.server.fastmcp import FastMCP
# Create an MCP server
mcp = FastMCP("My Custom Server")
# Define a tool
@mcp.tool()
def get_weather(city: str) -> str:
"""Get current weather for a city."""
# Your implementation here
return f"Weather in {city}: 72°F, Sunny"
# Define a resource
@mcp.resource("config://app")
def get_config() -> str:
"""Return application configuration."""
return "App version: 1.0.0"
Step 3: Configure Claude to Use Your Server
Add your server to Claude’s MCP configuration:
{
"mcpServers": {
"my-server": {
"command": "python",
"args": ["path/to/my_server.py"]
}
}
}
Step 4: Advanced Features
Adding Database Access
import sqlite3
@mcp.tool()
def query_database(sql: str) -> str:
"""Execute a read-only SQL query."""
conn = sqlite3.connect("mydb.sqlite")
cursor = conn.execute(sql)
results = cursor.fetchall()
conn.close()
return str(results)
Adding API Integration
import httpx
@mcp.tool()
async def fetch_api_data(endpoint: str) -> str:
"""Fetch data from an external API."""
async with httpx.AsyncClient() as client:
response = await client.get(f"https://api.example.com/{endpoint}")
return response.text
Best Practices
- Keep tools focused: Each tool should do one thing well
- Write clear descriptions: Claude uses the docstring to understand when and how to call your tool
- Handle errors gracefully: Return meaningful error messages, don’t let exceptions crash the server
- Use type hints: They help Claude understand what parameters to pass
- Implement read-only by default: Be cautious about giving write access to databases or APIs
Real-World MCP Server Ideas
- Jira/Linear ticket management
- Database query interface for analytics
- CI/CD pipeline monitoring and triggering
- Slack message sending and channel reading
- Custom documentation search
- Internal knowledge base access
Conclusion
Building MCP servers is one of the most powerful ways to extend Claude’s capabilities for your specific needs. Start with a simple tool, test it with Claude Code, and gradually add more functionality. The MCP ecosystem is growing rapidly, and custom servers let you stay at the forefront of AI-assisted development.
