Python MCP server met FastMCP
Definitie
FastMCP is de decorator-gebaseerde Python API uit de mcp SDK (Anthropic) waarmee een Python-functie in drie regels een volwaardige MCP tool wordt. De server communiceert via stdio transport en is registreerbaar in Claude Code naast andere MCP servers.
Context
Relevant wanneer een bestaande Python-tool of CLI (met zuivere functies en geen GUI-koppeling) beschikbaar gemaakt moet worden voor Claude Code of Atelier, zonder FastAPI of web server. Eerste toepassing: pdfcraft-python (PyMuPDF, Tesseract OCR, pikepdf) als lokale PDF-toolkit.
Kernpunten
FastMCP decorator pattern
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("tool-naam")
@mcp.tool()
def mijn_functie(pad: str, kwaliteit: int = 80) -> dict:
"""Beschrijving die de LLM ziet als tool-beschrijving.
Args:
pad: Absolute path naar het bestand.
kwaliteit: JPEG kwaliteit 1-95. Default: 80.
"""
# implementatie
return {"result": ..., "ok": True}
def main():
mcp.run(transport="stdio")FastMCP genereert automatisch JSON Schema vanuit Python type-annotaties. De docstring wordt de description. Args:-regels worden de parameter-beschrijvingen.
Installatie en venv
/opt/homebrew/bin/python3.13 -m venv .venv
.venv/bin/pip install mcpPython 3.13 heeft stabielere binary wheels (PyMuPDF, pikepdf, Pillow) dan 3.14 op macOS. Altijd een venv gebruiken — systeempython heeft de deps niet.
Registratie in Claude Code
In ~/.claude.json (root-level, niet ~/.claude/settings.local.json) onder mcpServers:
"tool-naam": {
"type": "stdio",
"command": "/absoluut/pad/naar/.venv/bin/python",
"args": ["-m", "pakket.mcp_server"],
"env": {}
}Het command-pad moet absoluut zijn naar de venv Python. python3 resolveert naar systeempython zonder de benodigde packages. cwd is niet nodig: de venv-Python laadt modules relatief aan zichzelf, niet aan de werkdirectory. Zie wiki-claude-code-mcp-configuratie voor uitleg over welk configuratiebestand Claude Code leest.
MCP handshake volgorde
Bij handmatige smoke tests via stdio:
- Stuur
initialize(metid) - Stuur
notifications/initialized(zonderid— dit is een notificatie, geen request) - Stuur
tools/listoftools/call
Zonder stap 2 reageert de server niet op tools/list.
printf '%s\n%s\n%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}' \
'{"jsonrpc":"2.0","id":3,"method":"tools/list","params":{}}' \
| .venv/bin/python -m pakket.mcp_server 2>/dev/nullFoutafhandeling
FastMCP vangt exceptions op en converteert ze naar MCP error responses — de server crasht niet. Een FileNotFoundError of ValueError in een tool geeft een nette foutmelding terug aan de client. Geen extra try/except nodig rondom de kern-aanroep.
Input/output patroon voor bestandstools
def _resolve_input(path: str) -> Path:
p = Path(path).expanduser().resolve()
if not p.exists():
raise FileNotFoundError(f"Niet gevonden: {p}")
return p
def _prepare_output(path: str) -> Path:
p = Path(path).expanduser().resolve()
p.parent.mkdir(parents=True, exist_ok=True)
return pAltijd expanduser().resolve() voor paden zodat ~-expansie en relatieve paden correct werken.
pyproject.toml entry point
[project.scripts]
tool-naam-mcp = "pakket.mcp_server:main"Na pip install -e . is het commando beschikbaar als tool-naam-mcp in de venv. Handig als alternatief voor -m pakket.mcp_server.
Verbanden
- Zie ook: wiki-vault-mcp-architectuur (TypeScript MCP server, dezelfde stdio-principes)
- Gerelateerd project: pdfcraft (
~/Claude/projects/pdfcraft/)
Bronnen
Anthropic. (2025). Model Context Protocol Python SDK. https://github.com/modelcontextprotocol/python-sdk