Startseite / Artikel / Stateless MCP: Skalierung von Servern ohne Sessions oder Handshakes

Stateless MCP: Skalierung von Servern ohne Sessions oder Handshakes

Wie ein staatloses Model Context Protocol Sessions und Handshakes beendet, sowie wie _meta-, mehrrundige Anfragen, Routing-Header, Caching und Aufgaben es weiterhin nutzbar halten.

1919 Wörter

Ein Model Context Protocol-Server, der auf einem einzigen Rechner einwandfrei funktioniert, kann bereits dann versagen, sobald man drei Kopien hinter einem Load Balancer betreibt, denn jede Instanz erinnert sich nur an die Sessions, die sie selbst erstellt hat. Der Übergang des Protokolls zu einem stateless-Kern zielt gezielt auf dieses Problem ab. Dieser Artikel erklärt, welche Veränderungen einsetzen, wenn Sessions sowie der Initialisierungs-Handshake wegfallen, wie Anfragen stattdessen ihren eigenen Kontext mitführen und wie mehrfache Interaktionen, headerbasiertes Routing, cachebare Listen sowie Hintergrundaufgaben in das neue Modell passen, damit Sie beurteilen können, welche Auswirkungen dies auf die von Ihnen betriebenen Server und Gateways hat.

Hinweis zur Zeitplanung: Das hier beschriebene stateless-Design gehört zur Revision 2026 des Protokolls. Details wie genaue Methodennamen, Header-Names und Ergebnistypen können sich weiterhin ändern, daher sollten Sie diese vor der Verwendung im Code gegen die aktuelle MCP-Spezifikation überprüfen. Falls Sie einen Überblick über die Grundlagen benötigen, wie MCP-Klienten Tools entdecken und aufrufen, behandelt der Blogbeitrag zur Art und Weise, wie das Model Context Protocol es Agenten ermöglicht, Tools zu entdecken und aufzurufen, dieses Thema.

Was „State“ hier bedeutet

Ein System ist zustandsbehaftet, wenn es zwischen den Anfragen etwas speichern muss, um die nächste Anfrage bearbeiten zu können. Eine Bestellung für Essen ist ein gutes alltägliches Beispiel: Sie geht von „angenommen“ über „zubereitet“ zu „unterwegs zur Lieferung“ bis hin zu „geliefert“, und der Dienst muss den Stand jeder Bestellung verfolgen, damit er jederzeit auf die Frage „Wo ist mein Essen?“ antworten kann.

Frühere Versionen von MCP funktionierten auf der Verbindungs Ebene genauso. Wenn ein Client (die KI-Anwendung) sich zum ersten Mal mit einem Server verband, führten beide eine Initialisierungsabfrage durch. Der Server gab anschließend einen Sitzungsidentifikator aus, zum Beispiel abc123, und der Client fügte diesen jedem folgenden Antrag hinzu, damit der Server jede Anfrage mit dem früheren Verlauf des Gesprächs in Verbindung bringen konnte, einschließlich der von beiden Seiten ausgehandelten Funktionalitäten.

Warum Sitzungen bei horizontaler Skalierung zusammenbrechen

Mit einer einzigen Serverinstanz und geringem Traffic ist dieses Design völlig ausreichend. Probleme entstehen, wenn die Belastung zunimmt und weitere Instanzen hinter einem Load Balancer hinzugefügt werden:

  1. Der Client eines Benutzers sendet seine erste Anfrage, beispielsweise nach der Liste der Tools. Der Load Balancer leitet sie an Server 1 weiter, der die Session abc123 erstellt.
  2. Derselbe Client sendet eine zweite Anfrage, beispielsweise zur Abfrage des Wetterdatens. Dieses Mal wählt der Load Balancer Server 2 aus.
  3. Server 2 hat noch nie von abc123 gehört. Er besitzt keinen Teil des In-Memory-Zustands von Server 1, weshalb die Anfrage fehlschlägt.

Stateful-Systeme verfügen über zwei gängige Lösungsansätze. Sticky Sessions binden jeden Client an eine bestimmte Instanz, was die Lastverteilung beeinträchtigt und den Failover erschwert. Als Alternative speichert ein gemeinsamer Speicher wie Redis die Sessiondaten, die jede Instanz lesen kann. Das funktioniert zwar, erfordert aber zusätzliche Infrastruktur zur Verwaltung, Absicherung und Bereitstellung sowie eine Netzwerkabfrage bei jedem Aufruf – alles allein, um die Protokollverwaltung aufrechtzuerhalten.

Das stateless-Modell

Die Überarbeitung von 2026 wählt einen anderen Weg: Sie macht MCP zu einem statelessen Request-Response-Protokoll und schafft die Sessions ab. Jeder Anfrage steht für sich und hängt nicht von dem ab, was der Server aus einer vorherigen Anfrage in Erinnerung hat. Da es auf dem Server kein Client-spezifisches Speicher ist, kann jede Instanz jede Anfrage beantworten, und das Skalieren erfolgt einfach durch Hinzufügen weiterer Instanzen hinter einem gewöhnlichen Load Balancer.

Das bedeutet nicht, dass Ihre Anwendung überhaupt keinen Zustand haben darf. Ein Tool, das einen Warenkorb oder die Bearbeitung eines langen Dokuments verwalten muss, benötigt dennoch irgendwo Daten. Der Unterschied besteht darin, dass ein solcher Zustand zu expliziten Anwendungsdaten wird, die an einem von Ihnen gewählten Ort gespeichert und über Identifikatoren in der Anfrage referenziert werden, anstatt zu implizitem Protokollzustand, der mit einer Verbindung verbunden ist.

Wie eine Anfrage ihren eigenen Kontext mitführt

Auch ohne Handshake oder Session-ID muss der Server wissen, welche Protokollversion der Client verwendet, wer der Client ist und was er kann. Die Antwort darauf ist, dass jede Anfrage diese Informationen mit sich bringt.

Das _meta-Objekt

Die Anfragedaten enthalten ein optionales _meta-Objekt für diese Metadaten. Es kann Folgendes enthalten:

  • Die Protokollversion, damit der Server weiß, wie die Nachricht interpretiert werden soll.
  • Die Identität des Clients, wie zum Beispiel der Name und die Version einer Anwendung wie MyAIApp v1.0.
  • Die Fähigkeiten des Clients, damit der Server weiß, welche Funktionen er in seiner Antwort verwenden kann.
  • Weil der Kontext im Anfrageinhalt enthalten ist, kann der Server ihn sofort verarbeiten, ohne in einer Sitzungstabelle nachschauen zu müssen. Der Nachteil ist ein etwas größeres Payload bei jeder Anfrage, was im Vergleich zu den Kosten eines gemeinsamen Sitzungsspeichers in der Regel unbedeutend ist.

    Mehrfachinteraktionen ohne offene Verbindung

    Zustandsbasierte Designs erleichtern den Austausch: Wenn der Server weitere Informationen benötigt, kann er diese über die bereits geöffnete Verbindung anfordern. Nehmen wir einen Benutzer, der einen Flug nach Delhi buchen möchte, aber den Datum vergisst. Ein zustandsbasiertes Server kann einfach nach dem Datum fragen und auf derselben Verbindung auf die Antwort warten.

    Ein stateless-Protokoll kann Verbindungen zu diesem Zweck nicht offen halten, daher definiert MCP stattdessen einen strukturierten mehrstufigen Ablauf:

    1. Wenn ein Server eine Anfrage erhält, bei der wesentliche Parameter fehlen, gibt er statt eines Fehlers oder Wartens ein spezielles input required-Ergebnis zurück.
    2. Die Clientanwendung bittet den Benutzer um die fehlenden Angaben.
    3. Der Client legt die Antworten in ein input responses-Objekt und sendet eine neue, vollständig unabhängige Anfrage, die der Server bearbeiten kann.

    Weil die zweite Anfrage alles enthält, was benötigt wird, kann sie auf jeder Serverinstanz landen. Der Server muss sich nicht daran erinnern, eine Anfrage gestellt zu haben; der Client setzt den Vorgang fort. Falls der Server die beiden Anfragen korrelieren muss (zum Beispiel, um teure Arbeiten zu vermeiden), kann er einen undurchsichtigen Token zurückgeben, den der Client wieder senden soll, anstatt versteckte Speicherinhalte beizubehalten.

    Routing über Header statt über den Inhalt

    Der stateless-Ansatz eröffnet außerdem Möglichkeiten zur Verbesserung der Leistung und Betriebseffizienz. Zwei Veränderungen sind besonders hervorzuheben: Routing auf Basis von Header sowie cachebare Ergebnislisten.

    Protokolldetails in HTTP-Header

    Zuvor musste die Infrastruktur vor einem MCP-Server, wie beispielsweise ein API-Gateway, eine Webanwendungs-Firewall oder ein Load Balancer, den JSON-Body jeder Anfrage analysieren, um herauszufinden, welche Methode oder welches Tool aufgerufen wurde. Die Analyse der Body am Edge verbraucht Rechenleistung, führt zu Verzögerungen und ist in vielen Gateways schwierig zu konfigurieren.

    Nach den neuen Regeln müssen HTTP-Anfragen wichtige Protokollinformationen in den Headern angeben:

    • MCP-Method, beispielsweise tools/call;
    • MCP-Name, der Name des spezifischen Tools, das aufgerufen wird.

    Ein Gateway kann diese Header lesen und den Datenverkehr leiten, mit einer Bandbreitengrenze versehen oder blockieren, ohne den Payload zu berühren. Dadurch lassen sich gängige Richtlinien einfach umsetzen – beispielsweise das Versenden teurer Tools in einen speziellen Pool von Instanzen, die Anwendung einer strengeren Bandbreitengrenze für ein bestimmtes Tool oder das vollständige Blockieren eines Tools während eines Incidents. Wie immer bei Headers sollte der Server dennoch überprüfen, ob sie mit dem Inhalt übereinstimmen, damit ein Client eine Richtlinie nicht umgehen kann, indem er irreführende Header sendet.

    Cachierbare Tool- und Prompt-Listen

    Kunden stellen den Servern ständig dieselben Fragen: Welche Tools sind verfügbar, welche Prompts werden unterstützt. Bei Tausenden von Nutzern kann ein Server einen erheblichen Teil seiner Kapazität damit verbringen, auf diese identischen Anfragen zu antworten.

    Die Listen der Tools und Anfragen ändern sich nur selten, weshalb die neue Version es ermöglicht, die Ergebnisse der Listen zu cachen. Ein Client kann die Liste der Tools einmal abrufen, sie im Speicher speichern und bei späteren Anfragen erneut verwenden, anstatt erneut nachzufragen. Derselbe Mechanismus ermöglicht es einer gemeinsam genutzten Infrastruktur, wie beispielsweise einem Gateway oder einem HTTP-Cache vor den Servern, wiederholte Anfragen nach Listen für viele Clients gleichzeitig zu beantworten. Auf jeden Fall erreichen den Server deutlich weniger Anfragen. Wie bei jedem Cache muss es auch hier eine Möglichkeit geben, ihn zu ungültig zu machen, wenn eine Neuveröffentlichung die Liste ändert – daher sollte man eher auf Ablaufzeiten oder Versionierung setzen anstatt einen dauerhaften Cache zu verwenden.

    Lange laufende Aufgaben mit Hintergrundprozessen

    Einige Tools antworten in Millisekunden, wie beispielsweise bei der Wetterabfrage. Andere tun das nicht: Die Analyse von 10.000 Dokumenten durch einen Assistenten kann zwanzig Minuten in Anspruch nehmen. Im herkömmlichen Request-Response-Zyklus müsste der Client die Verbindung die ganze Zeit über offen halten, wodurch Ressourcen auf beiden Seiten blockiert werden und die Benutzeroberfläche untätig warten bleibt.

    Um dies zu bewältigen, beinhaltet die Überarbeitung von 2026 ein neu gestaltetes Tasks-Framework:

    1. Erstellung. Wenn ein Client ein ressourcenintensives Tool auslöst, antwortet der Server umgehend mit einem Task-Identifikator, beispielsweise task_abc123, und die ursprüngliche Anfrage endet.
    2. Hintergrundausführung. Der Server führt die Analyse im Hintergrund durch, während der Benutzer weiterhin andere Teile der Anwendung nutzen kann.
  • Fortschrittsüberprüfungen. Zu jedem Zeitpunkt kann der Client den Status und die Ergebnisse der Aufgabe über einen Task Get-Aufruf anfordern.
  • Aktualisierte Eingaben. Wenn die Aufgabe während der Ausführung weitere Informationen benötigt, liefert der Client diese über Task Update.
  • Es handelt sich um das bekannte asynchrone Aufgabemuster aus Web APIs, das auf MCP angewandt wird. Dadurch bleiben Anwendungen unabhängig von der Schwierigkeit der Aufgabe reaktiv. Bei einer Mehr-Instanz-Einsatzweise muss man bedenken, dass der Status der Aufgabe an einem Ort gespeichert werden muss, den jede Instanz erreichen kann – schließlich kann der Task Get-Aufruf bei einem anderen Server ankommen als dem, der die Aufgabe erstellt hat. Das Protokoll benötigt keinen gemeinsamen Sitzungszustand mehr, doch die Verwaltung eines dauerhaften Aufgabenspeichers bleibt weiterhin Ihre Verantwortung.

    Was das für Ihre Server bedeutet

    Falls Sie MCP-Server betreiben oder entwickeln, sieht die praktische Checkliste wie folgt aus:

    • Entfernen Sie versteckte Speicherbereiche pro Verbindung. Alles, was ein Tool zwischen den Aufrufen benötigt, sollte in explizitem Speicher gespeichert werden, der durch von dem Client übermittelte Identifikatoren referenziert wird.
    • Lesen Sie den Kontext aus jeder Anfrage ab. Nehmen Sie die Protokollversion, die Identität sowie die Fähigkeiten des Clients aus _meta auf, nicht aus einer Sitzung.
    • Entwerfen Sie Tools so, dass sie fragen statt warten. Geben Sie bei fehlenden Parametern ein Ergebnis zurück, für das Eingaben erforderlich sind, und erwarten Sie die Antworten in einer neuen Anfrage.
    • Nutzen Sie die Routing-Header am Edge. Konfigurieren Sie Gateways, um nach MCP-Method und MCP-Name zu routen und Beschränkungen vorzunehmen, sowie diese am Server im Vergleich zum Anfrageinhalt zu überprüfen.
  • Cachelisten und Planung der Invalidation. Es werden Möglichkeiten bereitgestellt, damit Clients und Gateways Listen mit Tools und Anfragen cachen können, wobei es einen klaren Weg gibt, diese nach Deployments zu aktualisieren.
  • Langsame Tools in Aufgaben verschieben. Es wird schnell eine Task-ID zurückgegeben, und der Status der Aufgabe wird in einem von allen Instanzen geteilten Speicher aufbewahrt.
  • Kernpunkte

    • Durch den stateless Ansatz wird MCPs sessionsbasiertes Design durch unabhängige Request-Response-Aufrufe ersetzt, wodurch kein Bedarf mehr an Sticky Sessions oder einem gemeinsamen Session-Speicher besteht, um Skalierbarkeit zu erreichen.
    • Handshake- und Session-IDs sind nicht mehr notwendig; jede Anfrage enthält ihre Protokollversion, die Identität des Clients sowie seine Fähigkeiten im Feld _meta.
    • Fehlende Informationen werden durch ein Ergebnis mit input required sowie eine nachfolgende Anfrage, die input responses enthält, behandelt – anstelle einer offenen Verbindung.
    • MCP-Method- und MCP-Name-Header ermöglichen es Gateways, den Datenverkehr zu leiten, zu rate-limiten und zu blockieren, ohne JSON-Körper analysieren zu müssen.
    • Stabile Listen von Tools, Prompts und Ressourcen können in Cache gespeichert werden, wodurch eine wiederholte Belastung der Server vermieden wird.
    • Lange laufende Tools geben sofort eine Task-ID zurück, und die Clients folgen mit Task Get und Task Update.
    • Statelessness verschiebt den Zustand anstatt ihn zu beseitigen: Anwendungsdaten und Fortschritt der Aufgaben benötigen weiterhin einen dauerhaften Speicherort, den jede Instanz erreichen kann. Überprüfen Sie die genauen Namen gegenüber der aktuellen Spezifikation, bevor Sie darauf aufbauen.

    Verwandte Literatur