DANIEL KIRCHNER
Alle Artikel
28. März 20267 min Lesezeit

MCP-Server: Das Model Context Protocol in der Praxis

MCPKILangChainPythonFastAPILLM

Ein Modell schreibt guten Text. Mehr nicht, von allein. Es kommt nicht an Ihre Datenbank, schickt keine Mail, ruft keine interne API auf. Für einen Chatbot auf einer Wissensplattform heißt das: ohne Hilfe weiß das Modell nichts über die eigenen Inhalte, es rät.

MCP ist die Hilfe, in Form eines offenen Standards. Statt dass jede Integration mit jedem LLM neu verdrahtet wird, bekommt das Modell eine gemeinsame Schnittstelle zu Tools und Datenquellen. Das Modell entscheidet, wann es welches Tool ruft. Der Server entscheidet, was das Tool zurückgibt.

Drei Teile, kein Zauber

Ein MCP-Server besteht aus:

  • Tool-Definitionen: welche Funktionen das Modell sieht
  • Transport: stdio oder HTTP/SSE, wie das Modell mit dem Server spricht
  • Implementierung: was passiert, wenn ein Tool wirklich läuft
  • Kein Teil davon ist LLM-spezifisch. Das ist der Punkt.

    Der Server aus dem Gesundheitsprojekt

    Für die Gesundheitsplattform mit über 500 Video- und PDF-Inhalten habe ich einen MCP-Server gebaut, der dem Chatbot Zugriff auf die Wissensdatenbank gibt, statt jede mögliche Quelle in den Prompt zu stopfen.

    from mcp.server import Server
    from mcp.types import Tool, TextContent
    
    server = Server("health-knowledge")
    
    @server.tool()
    async def search_knowledge(
        query: str,
        category: str | None = None,
    ) -> list[TextContent]:
        """Durchsucht die Wissensdatenbank nach relevanten Inhalten."""
        results = await vector_store.similarity_search(
            query=query,
            filter={"category": category} if category else None,
            k=5,
        )
        return [
            TextContent(
                type="text",
                text=f"**{r.metadata['title']}**\n{r.page_content}"
            )
            for r in results
        ]
    
    @server.tool()
    async def get_article_details(article_id: str) -> list[TextContent]:
        """Holt die vollständigen Details eines Wissensartikels."""
        article = await db.get_article(article_id)
        return [TextContent(type="text", text=article.to_markdown())]
    

    Zwei Tools. Suche und Detail. Der Chatbot ruft search_knowledge, bekommt die Top-5-Treffer, ruft bei Bedarf get_article_details für die volle Fassung. Der Server läuft unabhängig vom Client. Ob Claude, ein eigener LangChain-Agent oder ein anderes Modell fragt, ist ihm egal.

    MCP gegen klassisches Function Calling

    AspektFunction CallingMCP
    Standardpro Anbieter (OpenAI, Anthropic)offener Standard
    TransportHTTP/RESTstdio, HTTP/SSE
    Discoverymanuell verdrahtetautomatische Tool-Discovery
    Wiederverwendungpro Integration neuein Server, viele Clients

    Function Calling gibt es länger, ist aber pro Provider anders verdrahtet. MCP ist offen, hat automatische Tool-Discovery und lässt sich über stdio genauso wie über HTTP/SSE betreiben. Der praktische Unterschied: ein Server, den ich einmal baue, läuft hinter jedem MCP-fähigen Client. Bei Function Calling baut man die Integration pro Provider neu.

    Zugriff ist keine Nebensache

    Ein Tool, das auf die Wissensdatenbank zugreift, braucht dieselbe Zugriffskontrolle wie jede andere interne API. Der MCP-Server läuft oft mit weiterreichenden Rechten als der Chat selbst, weil er direkt auf Datenbank oder Dateisystem zugreift. Wer den Server nur mit dem Argument „das Modell entscheidet ja selbst, was es abfragt" ohne eigene Autorisierung baut, überlässt die Zugriffskontrolle einer Textvorhersage. Der Tenant-Kontext gehört in den Serveraufruf, nicht in den Prompt, aus demselben Grund wie beim Retrieval-Filter in einem RAG-System.

    Was in der Praxis bricht

    Tool-Beschreibungen sind die Schnittstelle, nicht Dokumentation, und das wird regelmäßig unterschätzt. Das Modell entscheidet allein anhand des Texts, ob und wann es ein Tool ruft. Eine schwache Beschreibung heißt: das Tool wird zu selten oder zur falschen Zeit gerufen. Ich schreibe deshalb Beispiele mit in die Beschreibung, nicht nur eine Zeile Zweck.

    Fehler müssen außerdem interpretierbar sein. Die Datenbank ist down, die Suche liefert nichts. Ein MCP-Server, der dann eine Exception wirft, hilft dem Modell nicht. Er muss eine Antwort liefern, die das Modell als „keine Ergebnisse" oder „Fehler, bitte anders fragen" verstehen kann.

    Ohne Logging ist ein Tool-Call schlicht ein blinder Fleck: welches Tool, mit welchen Argumenten, wie lange, welches Ergebnis. Jeder Call gehört mit Metadaten geloggt, Zeitstempel, Tool-Name, Eingabe, Anzahl der Treffer, Latenz. Fehlt das, lässt sich eine schlechte Antwort später nicht rekonstruieren, und das wird zum Problem, sobald jemand fragt, warum der Bot etwas Falsches gesagt hat.

    Und Rate Limits gehören in den Server, nicht ins Modell. Ein Agent, der in einer Schleife dasselbe Tool zehnmal pro Sekunde ruft, weil ein Zwischenergebnis nicht zum Weiterarbeiten reicht, ist kein Sonderfall, sondern der Normalfall bei komplexeren Agenten-Abläufen. Ein einfaches Limit pro Tool und pro Session verhindert, dass eine Modell-Schleife zur Kostenexplosion oder zum Datenbank-Vorfall wird.

    Wann sich das lohnt

    Wenn der Chatbot an interne Quellen soll, die nicht im Trainingskorpus stehen. Wenn dieselbe Tool-Integration mehr als ein LLM bedienen soll. Wenn ein Agent aktiv etwas verändern soll, nicht nur reden. Für eine Demo mit einer Handvoll Fragen lohnt der Aufwand nicht. Für ein System, das produktiv über Monate läuft, schon.

    Ein Server mit dem offiziellen Python-SDK ist in wenigen Tagen gebaut. Die Arbeit danach, Tool-Beschreibungen schärfen, Fehlerfälle abdecken, Logging aufsetzen, dauert länger als die erste Version.

    Wann sich der Aufwand nicht lohnt

    Ein einzelner interner Endpunkt, den nur ein Client je aufrufen wird, braucht keinen eigenen Server mit Discovery und Transport-Layer. Ein direkter Funktionsaufruf reicht. MCP zahlt sich aus, sobald mehr als ein Client dieselben Tools braucht, oder sobald das Tool-Set wächst und Discovery den Unterschied macht zwischen einer Konfigurationsdatei pro Client und einer gemeinsamen Definition. Vorher ist es zusätzliche Infrastruktur für ein Problem, das noch nicht existiert.

    Praxis: der Gesundheits-Chatbot. Wer den Bestand vor dem Rollout lesen will: Architektur-Reviews. Technische Leitung auf Zeit: Interim CTO. Die Leistung dahinter sitzt unter KI-Engineering.

    Wenn das in den Betrieb soll: der LLM-Readiness-Check prüft an Tag 3 unter anderem, ob Tool-Calls sich nachvollziehen lassen.

    Der Standard selbst ist noch jung. Was er löst, ist nicht neu: Systeme brauchen seit jeher eine saubere Schnittstelle zu ihren Daten. MCP macht daraus eine gemeinsame Sprache, statt dass jedes Team seine eigene neu erfindet.

    Verwandte Artikel

    DSGVO und Data Residency, wenn ein LLM im Spiel ist

    Wo läuft das Modell, wo liegen die Embeddings, wo die Logs? Die technische Liste, die eine Datenschutzprüfung für KI-Systeme erst möglich macht.

    Artikel lesen

    Der EU AI Act aus der Sicht dessen, der das System baut

    Nachvollziehbarkeit, menschliche Aufsicht, Dokumentation: was ein Ingenieur zum AI Act beitragen kann, und wo die juristische Einordnung anfängt.

    Artikel lesen

    Termin

    30 Minuten. Wenn der Use-Case nicht in den Betrieb kann, sage ich das.