Phillip Pham | 11 Min. Lesezeit | 08.06.2026
TL;DR
FastMCP LangChain Integration ist 2026 der pragmatischste Weg, MCP-Server produktiv zu bauen und in Agent-Pipelines einzubinden. FastMCP reduziert den MCP-Server-Boilerplate um 80%, langchain-mcp-adapters macht aus den Tools eine LangChain-/LangGraph-kompatible Tool-Liste. Pexon Consulting setzt diese Kombination bei Mittelständlern produktiv ein — der Blog zeigt Setup, Production-Hardening und die Stolpersteine, die Standard-Tutorials übersehen.
Warum FastMCP statt Vanilla-MCP-SDK
Wer 2025 die ersten MCP-Server gebaut hat, kennt den Schmerz: Das offizielle MCP Python SDK ist sauber, aber verbose. Für jedes Tool musst du JSON-Schema-Definitionen schreiben, Async-Handler registrieren, Server-Lifecycle managen. Bei drei Tools machbar, bei dreißig nervig. FastMCP wurde Anfang 2025 als Community-Antwort darauf gestartet und ist seit Q3 2025 das De-Facto-Framework für produktive MCP-Server in Python.
Was FastMCP konkret abnimmt: JSON-Schema-Inferenz aus Python-Type-Hints (Pydantic im Hintergrund), automatische Async-Sync-Brücke, eingebaute Transport-Modi (stdio, streamable HTTP, SSE), saubere Resource- und Prompt-Definition über Decorator. Was Anthropic später teilweise ins offizielle SDK gezogen hat, aber FastMCP bleibt vorne weg bei Developer-Experience.
Hier der direkte Vergleich. Vanilla-Style Hello-World:
import asyncio
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
server = Server("crm-server")
@server.list_tools()
async def list_tools():
return [Tool(
name="search_customers",
description="Suche Kunden im CRM",
inputSchema={
"type": "object",
"properties": {"query": {"type": "string"}},
"required": ["query"]
}
)]
@server.call_tool()
async def call_tool(name, args):
if name == "search_customers":
results = await crm_search(args["query"])
return [TextContent(type="text", text=str(results))]
Gleicher Server mit FastMCP:
from fastmcp import FastMCP
mcp = FastMCP("crm-server")
@mcp.tool
def search_customers(query: str) -> list[dict]:
"""Suche Kunden im CRM nach Name oder E-Mail."""
return crm_search(query)
if __name__ == "__main__":
mcp.run()
15 Zeilen statt 80. JSON-Schema wird aus dem Type-Hint query: str und dem Return-Type abgeleitet, die Tool-Beschreibung kommt aus dem Docstring (den der LLM ohnehin sieht). Bei einem Pilotkunden mit 22 Tools haben wir die Migration vom Vanilla-SDK zu FastMCP in einem halben Tag durchgezogen — Codezeilen pro Tool sind von 35-50 auf 4-8 gefallen, Tests blieben alle grün.
FastMCP Server: Minimal-Setup für Production
Der Pexon-Standard für produktive FastMCP-Server hat ein paar Komponenten, die im Hello-World fehlen. Hier der Minimal-Stack, den wir in jedes Kundenprojekt einbauen.
from fastmcp import FastMCP
from fastmcp.exceptions import ToolError
import structlog
log = structlog.get_logger()
mcp = FastMCP(
"crm-server",
instructions="""
Dieser Server liefert Lese- und Schreibzugriff auf das interne CRM.
Tools: search_customers, get_customer_details, create_note.
Schreibende Tools brauchen role=vertrieb oder role=service.
""",
)
@mcp.tool
def search_customers(
query: str,
limit: int = 10,
) -> list[dict]:
"""Volltext-Suche im CRM. Liefert max 'limit' Treffer."""
if not query.strip():
raise ToolError("query darf nicht leer sein")
log.info("crm.search", query=query, limit=limit)
return crm_search(query, limit=limit)
@mcp.tool
def get_customer_details(customer_id: str) -> dict:
"""Holt vollständige Kunden-Details."""
log.info("crm.get_details", customer_id=customer_id)
customer = crm_get(customer_id)
if not customer:
raise ToolError(f"Kunde {customer_id} nicht gefunden")
return customer
@mcp.resource("crm://schema")
def crm_schema() -> str:
"""Datenmodell des CRM als JSON-Schema."""
return open("schemas/crm_schema.json").read()
if __name__ == "__main__":
mcp.run(transport="streamable-http", port=8000)
Was hier neu ist gegenüber Hello-World: Erstens instructions als Server-weite Beschreibung — der LLM bekommt damit Kontext, wann er den Server überhaupt aufrufen soll. Zweitens ToolError für saubere Fehler-Propagation — das Modell sieht die Fehlermeldung im nächsten Turn und kann sinnvoll reagieren. Drittens structlog als strukturiertes Logging — bei produktiven Setups Pflicht, weil normales print() keine Audit-Trail-Qualität hat. Viertens @mcp.resource für statische Daten wie Schemas — der LLM kann die Resource lesen, ohne dass sie als Tool im Loop erscheint. Fünftens transport="streamable-http" statt stdio, weil HTTP für Multi-Client-Setups und Remote-Aufrufe nötig ist.
LangChain-MCP-Adapter: Tools in die Agent-Pipeline holen
Wenn der Server steht, geht es um die Konsumenten-Seite. langchain-mcp-adapters ist das offizielle Paket, das MCP-Tools zu LangChain-kompatiblen Tools macht. Damit funktionieren sie sofort in jedem LangChain-Agent, LangGraph-Graph oder LCEL-Chain.
from langchain_mcp_adapters.client import MultiServerMCPClient
client = MultiServerMCPClient({
"crm": {
"url": "http://crm-server.intern:8000/mcp",
"transport": "streamable_http",
},
"erp": {
"url": "http://erp-server.intern:8001/mcp",
"transport": "streamable_http",
},
"kalender": {
"command": "python",
"args": ["-m", "kalender_mcp"],
"transport": "stdio",
},
})
tools = await client.get_tools()
Was hier passiert: Der MultiServerMCPClient verbindet sich mit drei MCP-Servern parallel — zwei über HTTP-Endpoints (CRM und ERP), einer als lokaler Subprozess (Kalender). get_tools() lädt die Tool-Liste aller drei Server und liefert sie als einheitliche LangChain-Tool-Liste. Der Name jedes Tools bekommt automatisch einen Server-Prefix (z.B. crm__search_customers), damit Tools aus verschiedenen Servern nicht kollidieren.
Praktischer Stolperstein, den wir oft sehen: Wenn deine Tools dynamisch Auth-Token brauchen (User-spezifisch statt Service-Account), musst du den Token-Pass durch eigene Header-Logik machen. MultiServerMCPClient unterstützt das über headers={"Authorization": f"Bearer {token}"} pro Server-Konfiguration. Wir bauen das standardmäßig in einen kleinen Token-Refresh-Wrapper ein, der gegen das Unternehmens-IdP (Keycloak oder Entra ID) regelmäßig nachholt.
LangGraph + FastMCP für Production-Agents
Hier kommt der Workflow zusammen. LangGraph als Orchestrator, FastMCP als Tool-Lieferant, dazwischen der Adapter. Das ist das Setup, das wir bei Pexon in den meisten produktiven Agent-Projekten 2026 einsetzen.
from langgraph.prebuilt import create_react_agent
from langgraph.checkpoint.postgres import PostgresSaver
from langchain_anthropic import ChatAnthropic
from langchain_mcp_adapters.client import MultiServerMCPClient
async def build_agent():
client = MultiServerMCPClient({
"crm": {"url": "http://crm.intern:8000/mcp", "transport": "streamable_http"},
"erp": {"url": "http://erp.intern:8001/mcp", "transport": "streamable_http"},
})
tools = await client.get_tools()
model = ChatAnthropic(
model="claude-sonnet-4-6",
temperature=0.0,
)
checkpointer = PostgresSaver.from_conn_string(
"postgresql://agent_state:***@pg.intern:5432/agents"
)
graph = create_react_agent(
model=model,
tools=tools,
checkpointer=checkpointer,
prompt="""
Du bist ein interner Service-Assistent. Nutze CRM- und ERP-Tools,
um Mitarbeiter-Anfragen zu beantworten. Bei Schreib-Aktionen
IMMER User-Bestätigung einholen.
""",
)
return graph
Was hier zusammenwirkt: ChatAnthropic als LLM (über Bedrock konfigurierbar via base_url), die MCP-Tools aus CRM und ERP als verfügbarer Tool-Pool, ein Postgres-Checkpointer für State-Persistierung über mehrere Conversation-Turns, der create_react_agent als fertiger ReAct-Loop. In ca. 25 Zeilen Code steht ein Production-fähiger Agent, der zwei interne Systeme über MCP anspricht. Das war 2024 ein dreiwöchiges Engineering-Projekt — 2026 ist es ein halber Tag, wenn die MCP-Server stehen.
Was wir Kunden zu diesem Pattern immer mitgeben: Setze temperature=0.0 für Tool-Use-Loops. Höhere Werte führen bei aktuellen Modellen zwar zu kreativeren Outputs, aber bei Tool-Calls steigt die Halluzinations-Rate (falsche Parameter-Werte, nicht-existente Tools). Der Score-Unterschied auf BFCL v4 zwischen Temperature 0.0 und 0.7 ist bei den meisten Modellen rund 4-8 Prozentpunkte zugunsten von 0.0. Bei produktiven Agents ist Determinismus mehr wert als Kreativität.
Production-Hardening: Auth, Rate-Limits, Audit-Trail
Drei Komponenten, die wir Kundenprojekten standardmäßig hinzufügen — und die in den Tutorials konsequent fehlen.
Auth zentral über IdP. FastMCP unterstützt seit Version 2.3 native Auth-Middleware, die Bearer-Tokens validiert und User-Identity in den Tool-Context durchreicht. Wir konfigurieren das gegen Keycloak oder Entra ID, sodass der Tool-Handler weiß, welcher Mensch gerade aufruft — relevant für Permission-Checks innerhalb des Tools und für sauberen Audit-Trail.
from fastmcp.auth import BearerTokenAuth
auth = BearerTokenAuth(
jwks_url="https://idp.example.com/.well-known/jwks.json",
issuer="https://idp.example.com/realms/pexon",
audience="mcp-crm-server",
)
mcp = FastMCP("crm-server", auth=auth)
@mcp.tool
def get_customer_details(customer_id: str, ctx: Context) -> dict:
user_email = ctx.auth.claims.get("email")
if not user_has_permission(user_email, "crm.read"):
raise ToolError(f"User {user_email} hat keine Lese-Berechtigung")
return crm_get(customer_id)
Rate-Limits pro User. Wir bauen das mit Redis-basiertem Token-Bucket — pro User-Identity 60 Tool-Calls pro Minute als Default, anpassbar pro Tool. Schützt vor Loop-Disastern, in denen ein Agent in eine Schleife läuft und das Backend-System überlastet.
Audit-Trail in Postgres oder Loki. Jeder Tool-Call landet als Log-Entry mit User, Tool, Parameter-Hash, Antwort-Hash, Latenz, Cost und Timestamp. Bei einem Vorfall hast du die volle Trail — wer hat wann was mit welchem Ergebnis aufgerufen. Mehr zum konsolidierten Audit-Pattern in unserem Universal MCP Client Blog.
Pexon-Patterns aus Kundenprojekten
Drei Lessons-Learned, die uns 2025/2026 in 12+ MCP-Projekten begegnet sind und die wir Kunden ungefragt mitgeben.
Lesson 1: Ein MCP-Server pro Domäne, nicht pro System. Wir hatten anfangs einen MCP-Server pro Backend-System gebaut — CRM-Server, ERP-Server, Ticket-Server, Wiki-Server. Das endete bei einem Kunden in 14 Servern, die alle separat deployed und überwacht werden mussten. Heute bauen wir nach Domänen: „Customer-Domain“ deckt CRM und Ticket ab, „Operations-Domain“ ERP und Lager, „Knowledge-Domain“ Wiki und SharePoint. Bei drei bis fünf Servern bleibt der Operations-Aufwand handhabbar.
Lesson 2: Schreib-Tools immer mit Confirmation. Lesetools sind unkritisch, Schreibtools sind gefährlich. Wir bauen Schreib-Tools standardmäßig mit einem Bestätigungs-Parameter — der Agent muss explizit confirmed=True setzen, was bedeutet, dass der User die Aktion vorher gesehen und genehmigt hat. Im Frontend implementieren wir das als Inline-Confirmation-Card. Verhindert die häufigste Klasse von Agent-Bugs: schreibende Aktionen ohne menschliche Zustimmung.
Lesson 3: Tool-Beschreibungen sind Production-Critical. Der Docstring deines @mcp.tool ist nicht Dokumentation für Menschen — er ist der Prompt für den LLM, der entscheidet, ob das Tool aufgerufen wird. Vage Docstrings führen zu falscher Tool-Wahl. Wir review-en Docstrings explizit auf Klarheit, mit Eingabe-Beispielen und klarer Abgrenzung zu ähnlichen Tools. Bei einem Kunden hat allein die Verbesserung der Docstrings die Tool-Treffer-Quote von 78% auf 91% erhöht — ohne Code-Änderung am Server.
Häufig gestellte Fragen
FastMCP ist Community-Projekt — wie stabil ist es?
FastMCP wurde 2025 von Jeremiah Lowin gestartet und ist seit Q3 2025 das De-Facto-Framework. Anthropic hat einige FastMCP-Patterns ins offizielle SDK übernommen, FastMCP entwickelt eigenständig weiter. Production-Use bei mehreren US-Vendors und in unseren 12+ Pexon-Projekten — Stabilität ist auf SemVer-Niveau seit Version 2.0. Wir empfehlen FastMCP 2.x für neue Projekte ohne Bedenken.
Funktioniert das auch ohne LangGraph, nur mit Claude Agent SDK oder OpenAI Agents SDK?
Ja. FastMCP-Server sind MCP-Standard-konform — jeder MCP-Client kann sie konsumieren. Claude Agent SDK hat MCP-First-Class-Integration, OpenAI Agents SDK seit März 2025. LangGraph plus langchain-mcp-adapters ist nur ein Pfad. Wir wählen je nach Projekt — bei reinem Anthropic-Setup oft direkt Claude Agent SDK ohne LangGraph dazwischen. Vergleich der SDKs im Claude Agent SDK vs OpenAI Agents SDK vs LangGraph Post.
Wie debugge ich MCP-Server in der Entwicklung?
FastMCP bringt einen Inspector mit — fastmcp inspect crm_server.py startet eine Web-UI, in der du Tools einzeln aufrufen, Request-/Response-Logs sehen und das Schema verifizieren kannst. Für komplexere Debugging-Szenarien ist mcp-inspector von Anthropic die Standardwahl — funktioniert mit jedem MCP-Server, nicht nur FastMCP.
Was ist mit Authentifizierung bei stdio-Transport?
Stdio-MCP-Server laufen typisch als lokaler Subprozess des Clients — Auth ist implizit über den Prozess-Kontext gegeben. Für Remote-Auth nutzen wir streamable HTTP mit Bearer-Tokens. FastMCP unterstützt beide Transport-Modi nativ.
Wie verbinde ich FastMCP mit ChatGPT Enterprise oder Microsoft Copilot Studio?
ChatGPT Enterprise unterstützt MCP-Connectors seit März 2025. Copilot Studio seit Q4 2025. Beide nehmen den Server über die jeweilige Custom-Connector-Definition entgegen — Setup typisch 30-60 Minuten plus Auth-Brücke. Für komplexere Multi-Server-Setups in Copilot Studio empfehlen wir den Universal MCP Client als Aggregator dazwischen.
Nächster Schritt
Wenn dein Team gerade MCP-Server für interne Systeme baut oder evaluiert: Wir machen einen 45-Minuten-Architektur-Call. Du beschreibst die Backend-Systeme, die du anbinden willst, und den Chatbot-Stack — wir skizzieren FastMCP-Server-Struktur, Auth-Konzept und Festpreis-Sprint, wenn nötig.
Verwandte Themen
→Universal MCP Client: Chatbot trifft 50 Custom-Apps
→Claude Agent SDK vs OpenAI Agents SDK vs LangGraph 2026
→MCP-Server für SAP plus LangGraph Multi-Tool-Agent
→MCP Tool Poisoning: Agent-Pipelines absichern



