Was macht MCP Python Entwicklungsskill?
Baue MCP-Server und -Clients in Python mit dem mcp SDK (enthält FastMCP).
Schnellübersicht
- Paket:
mcpauf PyPI (enthält FastMCP). Installieren:pip install "mcp[cli]" - Für LangChain/LangGraph-Integration:
pip install langchain-mcp-adapters - Spezifikationsversionen:
2024-11-05,2025-03-26,2025-06-18,2025-11-25 - Imports:
from mcp.server.fastmcp import FastMCP, Context, Image
Bevor du mit dem Codieren beginnst
Lies die entsprechende Referenzdatei aus dem references/-Verzeichnis dieses Skills, je nachdem, was der Benutzer benötigt:
| Der Benutzer möchte... | Diese Datei lesen |
|---|---|
| Einen MCP-Server erstellen (Tools, Resources, Prompts) | references/server.md |
| Einen MCP-Client oder Multi-Server-Agenten erstellen | references/client.md |
| Context verwenden (Logging, Fortschritt, Sampling, Auslösung) | references/context.md |
| Transporte, Authentifizierung, Sicherheit, Lebenszyklus verstehen | references/protocol.md |
Lies immer die relevante Referenzdatei, bevor du Code schreibst. Die Referenzen enthalten exakte Importpfade, API-Signaturen, Rückgabetyp-Mappings und Fallstricke, die für korrekten Code entscheidend sind.
Architektur auf einen Blick
Host (Claude Desktop / IDE / benutzerdefinierter Agent)
├── MCP Client 1 ──► MCP Server A (lokal, STDIO)
├── MCP Client 2 ──► MCP Server B (entfernt, Streamable HTTP)
└── MCP Client 3 ──► MCP Server C (entfernt, OAuth 2.1)
- Host: KI-Anwendung, die Clients erstellt
- Client: 1:1-Verbindung zu einem einzelnen Server
- Server: Stellt Tools, Resources und Prompts bereit
Drei Primitive: Tools (modellgesteuerte Funktionen), Resources (anwendungsgesteuerte schreibgeschützte Daten), Prompts (benutzergesteuerte Nachrichtenvorlagen).
Zwei Transporte: STDIO (lokaler Unterprozess, einzelner Client) und Streamable HTTP (Netzwerk, Multi-Client, Standardendpunkt /mcp).
Minimale Servervorlage (Copy-Paste-Startvorlage)
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("MyServer")
@mcp.tool()
def my_tool(param: str) -> str:
"""Beschreibt, was dieses Tool tut."""
return f"Ergebnis: {param}"
@mcp.resource("data://config")
def get_config() -> str:
"""Serverkonfiguration."""
return '{"key": "value"}'
if __name__ == "__main__":
mcp.run() # Standardmäßig STDIO; verwende mcp.run(transport="streamable-http") für HTTP
Minimale Clientvorlage
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
import asyncio
async def main():
params = StdioServerParameters(command="python", args=["server.py"])
async with stdio_client(params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
result = await session.call_tool("my_tool", {"param": "hello"})
print(result.content[0].text)
asyncio.run(main())
Wichtige Regeln und Fallstricke
- Docstrings sind erforderlich für
@mcp.tool()-Funktionen — sie werden zur Tool-Beschreibung, die an das LLM gesendet wird. Kein Docstring = das LLM weiß nicht, was das Tool tut. - Typannotationen sind erforderlich — FastMCP generiert daraus JSON-Schema. Verwende
Annotated[str, Field(description="...")]für ausführliche Parameterdokumentation. - Context wird per Typannotation injiziert — füge
ctx: Contextals Parameter hinzu; es wird automatisch aus dem Eingabeschema des Tools ausgeschlossen. - Rückgabetypen sind wichtig:
str→ TextContent,dict→ JSON TextContent,bytes→ BlobResourceContents,Image→ ImageContent,list→ mehrere Inhaltsblöcke. - Fehler: Ausnahmen in Tools auslösen → werden an das LLM mit
isError=Truezurückgegeben. Gib keine Fehlerstrings als normale Ausgabe zurück. - STDIO-Server dürfen niemals auf stdout ausgeben — alle Nicht-MCP-Ausgaben gehen an stderr. Verwende
loggingmit stderr-Handler oderctx.info(). - Async wird bevorzugt für Tools, die I/O durchführen. Sowohl synchrone als auch asynchrone Handler werden unterstützt.
- Tool-Annotationen sind Hinweise, keine Durchsetzung:
readOnlyHint,destructiveHint,idempotentHint,openWorldHint. - MultiServerMCPClient (v0.1.0+) ist KEIN asynchroner Context-Manager. Direkt instanziieren:
client = MultiServerMCPClient({...}). - InMemorySaver ist nur für die Entwicklung — verwende in der Produktion PostgresSaver oder SqliteSaver.
Entwicklungs-Workflow
mcp dev server.py # Starten mit MCP Inspector (Debugging-UI)
mcp dev server.py --with pandas # Mit zusätzlichen Abhängigkeiten
mcp install server.py # In Claude Desktop registrieren
mcp install server.py -e API_KEY=x # Mit Umgebungsvariablen
mcp run server.py # Direkt ausführen
Wann welcher Transport verwendet werden sollte
| Szenario | Transport | Warum |
|---|---|---|
| Lokales CLI-Tool / Desktop-Integration | STDIO | Kein Netzwerk, Mikrosekunden-Latenz |
| Produktions-API, Multi-Client | Streamable HTTP | Skalierbar, lastverteilt |
| Serverless (Lambda, Cloud Run) | Streamable HTTP + stateless_http=True | Zustandslos pro Anfrage |
| Einbettung in bestehende FastAPI/Starlette | Streamable HTTP (mounten) | Teilt ASGI-App |