FastMCP is the only way I can build MCP servers without losing my sanity. MCP is Anthropic's protocol for letting Claude talk to your database, APIs, and files. Think of it as giving Claude a keyboard to your backend.
The 3 Things MCP Actually Does
- Tools: Claude can run your Python functions (database queries, API calls)
- Resources: Claude can read your data (files, logs, configuration)
- Prompts: Templates for consistent prompting patterns
Most of the time you just want tools. Resources are useful but the URI templating is confusing as hell. Prompts are completely overhyped - never used them in production.
Why FastMCP vs Official SDK
I spent 6 hours trying to get the official SDK working for a simple file reader. Here's what the same tool looks like:
Official SDK: 45 lines of import hell, type definitions, and protocol handlers
FastMCP: 8 lines with a decorator that just works
from fastmcp import FastMCP
mcp = FastMCP("My Server")
@mcp.tool
def read_file(path: str) -> str:
"""Read file - will crash if file doesn't exist"""
with open(path, encoding='utf-8') as f:
return f.read()
if __name__ == "__main__":
mcp.run() # STDIO transport, works locally
Transport Gotchas I Learned the Hard Way
STDIO: Default, easiest to debug. Breaks on Windows if your PATH is fucked.
HTTP: Production use. Port 8000 gets blocked by some corporate firewalls.
SSE: Don't use unless forced. Times out after about 5 minutes in my experience - there's some hardcoded timeout that kills SSE connections.
STDIO errors actually show up in your terminal. HTTP errors disappear into Claude's logs. I debug everything with STDIO first.
Version Hell
FastMCP 2.x requires Python 3.10+. Python 3.9 breaks with cryptic Union type errors that'll waste your entire afternoon. Python 3.12 mostly works but I've hit some weird async/await edge cases - might be my code, might be the library.
I'm stuck on Python 3.11 because it's the only version that doesn't randomly break. Install with uv add fastmcp
- pip sometimes pulls old dependencies and you'll spend an hour figuring out why nothing works.
What Breaks in Production
I've had servers crash at 2am because:
- Memory leaks: Long-running servers don't clean up properly. Watched one server eat 8GB of RAM overnight because I forgot to close file handles. I restart every 24 hours now.
- Connection hangs: I've seen transport locking issues with long-running HTTP servers. Timeouts help but don't solve it completely.
- Type hint failures: Missing type hints make decorators silently fail. Spent 3 hours wondering why my tool wasn't showing up in Claude - forgot the return type annotation.
- File encoding: Windows UTF-8 issues that don't show up in testing. Works fine on Mac, crashes in production Docker containers with
UnicodeDecodeError
The library is maintained by Prefect so bugs actually get fixed, unlike most Python libraries. Still rough around the edges though - expect to hit weird edge cases.
Resources That Actually Help
- FastMCP docs - Better than most, but assumes you know MCP
- MCP Inspector - Only way to debug without losing your mind
- Examples - Copy these, don't start from scratch