This tutorial walks you through building a complete MCP server in Python. For Python environment, async, validation, and production patterns around AI services, use the Python for AI developers guide. For the TypeScript version, see our TypeScript tutorial.
Install
pip install mcp httpx
Create the server
from mcp.server import Server
from mcp.server.stdio import stdio_server
import httpx
server = Server("my-dev-tools")
@server.tool()
async def check_website(url: str) -> str:
"""Check if a website is responding and measure latency."""
try:
async with httpx.AsyncClient() as client:
response = await client.get(url, timeout=10)
return f"{url}: {response.status_code} ({response.elapsed.total_seconds():.2f}s)"
except Exception as e:
return f"{url}: UNREACHABLE β {str(e)}"
@server.tool()
async def count_lines(file_path: str) -> str:
"""Count lines in a file."""
try:
with open(file_path) as f:
count = sum(1 for _ in f)
return f"{file_path}: {count} lines"
except FileNotFoundError:
return f"File not found: {file_path}"
Add the transport
import asyncio
async def main():
async with stdio_server() as (read, write):
await server.run(read, write, server.create_initialization_options())
if __name__ == "__main__":
asyncio.run(main())
Connect to Claude Code
claude mcp add my-tools python /path/to/server.py
Connect to Claude Desktop
Add to config:
{
"mcpServers": {
"my-tools": {
"command": "python",
"args": ["/absolute/path/to/server.py"]
}
}
}
Using FastMCP (simpler API)
pip install fastmcp
from fastmcp import FastMCP
mcp = FastMCP("my-server")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers."""
return a + b
mcp.run()
FastMCP handles transport, error handling, and type validation automatically.
Security
Always validate inputs and handle errors. See our MCP Security Checklist for production guidelines.
Related: Build MCP Server (TypeScript) Β· What is MCP? Β· Best MCP Servers Β· MCP Complete Guide