MCP Engineering

Transport und Resilienz: Grenzen unter Störung

Ein Timeout beweist nur, dass keine Antwort ankam. Wer daraus „nicht ausgeführt“ macht und automatisch wiederholt, verwandelt eine kurze Netzstörung in eine doppelte Rückzahlung. Resilienz beginnt mit ehrlichen Zuständen, nicht mit mehr Retries.

Lehrtext · 11 Abschnitte · zuletzt geprüft: 2026-09-05

Transport ist eine Vertrauens- und Fehlergrenze

MCP trennt fachliche Nachrichten von ihrem Transport. Für die Implementierung ist die Transportwahl trotzdem folgenreich: Sie bestimmt, wer den Server startet, wie Identität nachgewiesen wird, welche Netzkomponenten zwischen Client und Server liegen und welche Fehler unabhängig voneinander auftreten können. Ein lokaler Kindprozess über stdio erbt einen Betriebskontext. Ein geteilter HTTP-Dienst muss diesen Kontext ausdrücklich herstellen und gegen andere Nutzer abschirmen.

Resilienz heißt nicht, jede Störung mit Wiederholung zu beantworten. Zuerst muss das System unterscheiden: Ist die Nachricht technisch ungültig, ist die Fachoperation gescheitert, kam nur die Antwort nicht an, oder ist eine ganze Fähigkeit derzeit nicht verfügbar? Diese Zustände verlangen andere Reaktionen. Wer sie in „Fehler“ zusammenfasst, erzeugt Schleifen, Doppelwirkungen und irreführende Nutzertexte. Der wichtigste Entwurfsgegenstand ist deshalb die Bedeutung unter Unterbrechung.

LeitfrageWas weiß jede Seite nach Verbindungsabbruch sicher — und welchen Fachzustand muss sie erst wieder feststellen?

stdio begrenzt Reichweite, nicht Prozessrechte

Bei stdio startet der Host den MCP-Server gewöhnlich als Kindprozess und tauscht JSON-RPC-Nachrichten über Standard-Ein- und -Ausgabe aus. Es gibt keinen lauschenden Netzwerkport. Das vereinfacht Distribution für persönliche Werkzeuge und kann die erreichbare Angriffsfläche verkleinern. Der Prozess läuft aber typischerweise mit den Rechten des angemeldeten Nutzers. Er kann lokale Dateien, Umgebungswerte und erreichbare Dienste so weit sehen, wie Betriebssystem und Sandbox es erlauben.

Eigenschaft
Betriebliche Folge
Host startet Prozess
Lebensdauer und Versionierung hängen an der lokalen Installation
Nutzerrechte geerbt
Jeder Server ist ausgeführter Code im persönlichen Vertrauensbereich
Kein Listener
Keine eingehende Netzfreigabe, aber ausgehender Zugriff bleibt möglich
Lokale Credentials
Widerruf, Rotation und Audit müssen auf vielen Geräten funktionieren

Für einen Entwicklerprototyp kann dieses Modell passend sein. Für Hunderte Nutzer ist es nicht automatisch die einfachste Lösung: Verteilung, Updates, Provenienz, lokale Secrets und Diagnose vervielfachen sich. Entscheide anhand des Besitzmodells. Ein persönliches Dateisystemwerkzeug kann lokal bleiben; eine zentrale Buchungsfunktion mit organisationsweiter Policy braucht meist einen geteilten Dienst und explizite Nutzeridentität.

Merksatz„Lokal“ beantwortet die Frage nach Erreichbarkeit, nicht nach Vertrauenswürdigkeit oder minimalen Rechten.

HTTP macht Identität und Zustandslosigkeit explizit

Ein HTTP-Server ist unabhängig vom Host betreibbar, zentral aktualisierbar und horizontal skalierbar. Dafür braucht er Authentifizierung, Autorisierung, TLS-Terminierung, Rate Limits und beobachtbare Betriebsgrenzen. Die Revision 2026-07-28 ist im Core stateless: Es gibt keinen Initialisierungs-Handshake und keine Protokollsession. Version und Client-Capabilities stehen pro Request in _meta; der Server verarbeitet den Request aus diesen Angaben, seiner Autorisierung und expliziten Fachparametern.

``json { "jsonrpc": "2.0", "id": 42, "method": "tools/call", "params": { "_meta": { "protocolVersion": "2026-07-28", "clientCapabilities": {} }, "name": "reindex_catalog", "arguments": { "catalogId": "eu" } } } ``

Speichert ein Worker trotzdem „die letzte Version“ oder „den aktuellen Tenant“, kollidiert das mit freiem Routing und parallelen Clients. Sticky Sessions kaschieren diesen Fehler nur und machen Knotenausfall sichtbar. Fachzustand über mehrere Requests bekommt einen opaken Handle; Zugriff wird bei jedem Call erneut autorisiert. Dann darf der Load-Balancer jeden gesunden Worker wählen.

Trade-offZustandslose Protokollverarbeitung vereinfacht Skalierung, verlangt aber explizite Persistenz für jeden wirklich benötigten Fachzustand.

Lokales HTTP bleibt ein echter Netzwerkendpunkt

Desktop-Anwendungen starten manchmal einen HTTP-Server auf demselben Rechner. Bindet er an 0.0.0.0, ist er nicht nur lokal, sondern über alle passenden Interfaces erreichbar. Bindung an Loopback reduziert diese Reichweite, schützt jedoch nicht automatisch vor anderem lokalem Code oder einer Webseite, die der Nutzer im Browser geöffnet hat. Der Server muss die erwartete Herkunft prüfen und einen echten Authentifizierungsmechanismus verlangen.

Nur an Loopback bindenErwartete Origin-Werte prüfenClient authentifizierenJeden fachlichen Zugriff autorisierenFehlversuche begrenzen und protokollieren

Ein zufälliger Port ist kein Secret. Portscans und Browseranfragen können ihn finden; auch der Prozesskontext des Nutzers beweist nicht, wer einen Request ausgelöst hat. Vermeide weitreichende Langzeittokens in URL, Log oder frei lesbarer Konfiguration. Wenn der lokale HTTP-Modus keinen klaren Nutzen gegenüber stdio bietet, ist der kleinere Transport oft leichter zu härten. Wenn Browser- oder Mehrprozessintegration ihn verlangt, behandle ihn wie jede andere privilegierte API.

PrüfregelNetzwerkposition ist keine Identität, und Loopback ist keine Autorisierung.

Proxys verändern Streams, Fristen und Beobachtbarkeit

Zwischen Client und Server liegen häufig Reverse-Proxy, Load-Balancer, WAF oder Service Mesh. Jede Schicht kann Antworten puffern, Idle-Verbindungen schließen, maximale Requestdauer erzwingen oder Header verändern. Ein lokal erfolgreicher Stream beweist daher wenig über Produktion. Prüfe die gesamte Strecke mit realistischen Dauern und Datenmengen. Konfiguriere Timeouts bewusst von außen nach innen und beobachte, welche Komponente tatsächlich beendet hat.

Symptom
Mögliche Grenze
Erste Daten kommen erst am Ende
Response-Buffering im Proxy
Abbruch immer nach 60 Sekunden
Idle- oder Request-Timeout einer Zwischeninstanz
Nur große Ergebnisse scheitern
Body-, Buffer- oder Speichergrenze
Einzelne Replikate verlieren Events
Prozesslokaler Event-Bus bei verteilten Streams

Keep-alives oder kleine Fortschrittsdaten können Idle-Timeouts vermeiden, machen die Fachoperation aber nicht transaktional. Auch ein korrekt konfigurierter Stream kann durch Netzwechsel, Deploy oder Clientabbruch enden. Plane deshalb immer den Zustand nach dem Streamverlust: Kann der Client erneut lesen, einen Status abfragen oder den Subscription-Stream neu öffnen? Gibt es keine Replay-Garantie, darf er keine lückenlose Historie vortäuschen.

MerksatzEine stabile Verbindung verbessert Latenz; Korrektheit darf trotzdem nicht von ihrer Unsterblichkeit abhängen.

Lege für jede Grenze einen Besitzer der Frist fest. Der Client begrenzt seine Wartezeit aus Sicht der Nutzerinteraktion. Der Gateway schützt Verbindungen und Kapazität. Der Server begrenzt interne Arbeit, und ein Downstream hat nochmals eigene Fristen. Sind alle Werte zufällig gleich, bleibt bei einem Abbruch keine Zeit für eine kontrollierte Fehlerantwort oder Aufräumarbeit. Üblicherweise endet die innerste Operation zuerst, dann der Server und zuletzt die äußere Nutzerfrist. Die konkreten Zahlen hängen vom Dienst ab; entscheidend ist ihre begründete Staffelung. Übertrage außerdem die verbleibende Deadline, nicht bei jedem Hop eine neue volle Frist. Sonst kann eine kurze Nutzerfrist hinter mehreren Retries zu minutenlanger Hintergrundarbeit wachsen. Metriken sollten die beendende Schicht und die verbrauchte Zeit ausweisen. So erkennst du, ob eine Optimierung am Tool, am Proxy oder am Retry-Verhalten nötig ist, statt überall pauschal größere Timeouts einzutragen.

Langläufer werden zu adressierbaren Vorgängen

Dauert eine Reindizierung mehrere Minuten, ist eine einzige offene Response ein fragiler Eigentümer ihres Ergebnisses. Besser ist häufig ein zweistufiger Vertrag: Das wirkende Tool akzeptiert einen Vorgangsschlüssel, startet oder erkennt die Arbeit und liefert einen opaken Jobhandle. Ein lesender Folgeaufruf berichtet Status und Ergebnis. Abbruch, Ablauf und Aufbewahrung sind dann Eigenschaften des Vorgangs, nicht des TCP-Flows.

Absicht mit Idempotency-Key sendenVorgang erstellen oder bestehenden erkennenJobhandle zurückgebenStatus mit Handle lesenErgebnis oder kompensierbaren Fehler abschließen

Diese Form kostet Persistenz und einen zusätzlichen Aufruf. Dafür kann ein Client nach Unterbrechung feststellen, was geschah, statt blind neu zu starten. Der Handle ist keine Berechtigung: Authentifizierte Server binden ihn an Principal und Tenant. Ohne Authentifizierung wirkt er als Bearer Token und braucht ausreichend Entropie, kurze Lebensdauer und geringe Offenlegung. Definiere außerdem, ob Cancellation nur das Warten beendet oder den Hintergrundjob fachlich abbrechen soll.

EntwurfszielDer Vorgang überlebt die Verbindung; seine Wirkung bleibt einmalig und sein Zustand später feststellbar.

Fehlerkanäle richten sich nach dem nächsten Akteur

JSON-RPC-Fehler und Tool-Ausführungsfehler haben verschiedene Adressaten. Eine unbekannte Methode, syntaktisch ungültige Nachricht oder Schemaabweichung muss der Client technisch korrigieren. Ein belegter Raum, überschrittenes Fachlimit oder nicht lieferbarer Artikel ist dagegen eine gültig angeforderte Operation mit fachlichem Fehlschlag. Diese Information gehört in das Tool-Ergebnis, damit Modell oder Nutzer eine Alternative wählen kann.

JSON-RPC-Fehler
Nachricht oder Aufruf technisch nicht verarbeitbar; Client reagiert
Tool-Ausführungsfehler
Aufruf gültig, Fachziel nicht erreicht; Modell oder Nutzer reagiert
Transportabbruch
Ausgang möglicherweise unbekannt; Status- und Wiederholungslogik reagiert

Ein fachlicher Fehler soll handlungsleitend sein: Was scheiterte, welche zulässige Änderung hilft, und ist Wiederholung sinnvoll? Er darf keine Stacktraces, internen Hostnamen oder Daten fremder Mandanten offenlegen. Markiere einen Fehlschlag nicht als Erfolg mit booked: false, wenn Auswertungen und Hosts Erfolg und Fehler unterscheiden sollen. Ebenso wenig gehört eine korrigierbare Fachentscheidung in einen generischen Protokollfehler, den das Modell nie sinnvoll sieht.

Kurzcheck

Ein gültiger Tool-Aufruf findet den Raum, aber er ist belegt. Wer kann den nächsten Schritt wählen?

  • Modell oder Nutzer; der Fehlschlag gehört handlungsleitend in das Tool-Ergebnis.
  • Nur der JSON-RPC-Parser; er muss die Nachricht als ungültig ablehnen.
  • Der Transport; er soll dieselbe Nachricht bis zum Erfolg wiederholen.

Treffer. Richtig. Der Vertrag war technisch gültig, nur das Fachziel ist gescheitert.

Timeout und Cancellation lassen Fachwirkung offen

Ein Client-Timeout beweist nur, dass innerhalb seiner Frist keine Antwort ankam. Der Server kann den Request nie gesehen, gerade verarbeitet oder bereits vollständig ausgeführt haben. Sendet der Client anschließend notifications/cancelled, erhält der Server ein kooperatives Stoppsignal. Der Empfänger soll Arbeit beenden, Ressourcen freigeben und für diesen Request keine weitere Nachricht senden. Das Signal rollt bereits angenommene Zahlungen, Uploads oder Migrationen jedoch nicht automatisch zurück.

Schreibe deshalb nach Timeout nicht „wurde nicht ausgeführt“ in Modellkontext oder UI. Der ehrliche Zustand lautet „Ausgang unbekannt“, ergänzt um Vorgangsschlüssel und Statuspfad. Diese Formulierung wirkt weniger bequem, verhindert aber gefährliche Folgeschlüsse. Kann eine Außenschnittstelle nicht abgefragt werden, braucht der interne Prozess einen Abgleich oder eine Kompensation. Eine fehlende Response bleibt sonst dauerhaft mehrdeutig.

KorrektheitsgrenzeCancellation beendet die zulässige Nachrichtenfolge; Idempotenz und Status klären die bereits mögliche Fachwirkung.

Teste besonders die Race-Grenzen: Cancellation unmittelbar vor und nach dem Commit, Antwortverlust nach erfolgreichem Commit und doppelter Request während der ersten Ausführung. Logs müssen unterscheiden, ob der Server den Auftrag annahm, eine Wirkung bestätigte und ein Result senden konnte. Nur dann lässt sich ein Incident rekonstruieren, ohne aus Transporttelemetrie eine fachliche Wahrheit abzuleiten.

Wiederholung braucht Schlüssel, Budget und Klassifikation

Retries sind bei kurzzeitigen Transportfehlern nützlich, aber nur begrenzt. Ein wirkendes Tool erhält einen vom Aufrufer stabil wiederverwendeten Idempotency-Key. Der Server speichert dazu Status und Ergebnis atomar genug, dass zwei parallele Zustellungen nicht zweimal wirken. Der Schlüssel bezeichnet dieselbe Absicht; er darf nicht für veränderte Parameter wiederverwendet werden. Der Server sollte solche Konflikte sichtbar ablehnen.

  • Wiederholbar: kurzzeitiger Verbindungsfehler vor bekannter Annahme, mit Backoff und Jitter.
  • Status zuerst: Timeout nach möglicher Annahme einer wirkenden Operation.
  • Nicht wiederholen: ungültiges Schema, fehlende Berechtigung oder stabiler Fachkonflikt.
  • Budget erschöpft: Fähigkeit vorübergehend aus der aktiven Auswahl nehmen und im Hintergrund prüfen.

Ein Retry-Budget begrenzt Versuche pro Request, Server und Zeitfenster. Exponentieller Backoff mit Jitter verhindert, dass viele Hosts einen erholenden Dienst gleichzeitig überlasten. Budgets gelten auch für MRTR-Runden und Statusabfragen: Endlosschleifen verbrauchen Kontext und Geld, selbst wenn jeder einzelne Aufruf billig ist. Metriken sollten Erstversuch, Retry, deduplizierte Wiederholung und endgültigen Fehlschlag getrennt zählen.

PreisSichere Wiederholung erfordert Speicher und Ablaufregeln; unsichere Wiederholung verlagert den Preis in reale Doppelwirkung.

Der Idempotency-Speicher braucht selbst einen Vertrag. Speichere neben dem Schlüssel einen Fingerabdruck der normalisierten Argumente, den Bearbeitungsstatus und das kanonische Ergebnis. Trifft derselbe Schlüssel mit anderen Argumenten ein, ist das ein Konflikt und kein Cachetreffer. Läuft die erste Ausführung noch, dürfen parallele Requests nicht beide die Wirkung starten; sie warten begrenzt, erhalten den aktuellen Status oder denselben Jobhandle. Die Aufbewahrungsfrist muss mindestens das realistische Wiederholungsfenster abdecken und zu den Fachregeln passen. Bei Zahlungen kann sie deutlich länger sein als bei einer temporären Analyse. Lösche den Eintrag nicht unmittelbar nach dem ersten erfolgreichen Response, denn gerade ein verloren gegangenes Resultat löst den späteren Retry aus. Achte zugleich auf Mandantentrennung: Derselbe vom Client gewählte Schlüssel zweier Nutzer darf niemals denselben Vorgang bezeichnen. Gute Telemetrie zählt neue, laufende, deduplizierte und konfligierende Schlüssel getrennt, ohne den Schlüssel selbst als frei durchsuchbares Secret zu behandeln.

Teilausfälle bleiben lokal und sichtbar

Ein Host kann Fähigkeiten mehrerer Server aggregieren. Fällt einer davon aus, sollen die übrigen weiter funktionieren. Ein dauerhaft angebotenes, aber totes Tool lockt das Modell in Timeouts und wiederholte Fehlentscheidungen. Entferne seine Fähigkeiten nach einer definierten Schwelle aus der aktiven Auswahl oder markiere sie eindeutig als nicht verfügbar. Prüfe die Erholung mit begrenzten Hintergrundversuchen und füge die Fähigkeiten erst nach belastbarem Erfolg wieder hinzu.

EIN AGENT DARF NUR IN EINER KONTROLLIERTEN SCHLEIFE HANDELNZiel + GrenzenPlanenTool handelnBeobachtenFortschritt prüfenKein Fortschritt oder Limit erreicht → Strategie wechseln, eskalieren oder beenden.
Ein ausgefallenes Tool in der Auswahl erzeugt bei jedem Planungsschritt neue Kosten und weitere Fehlversuche.

server/discover hilft, aktuelle Serverfähigkeiten explizit zu erfassen; es ersetzt keine Health-Policy. Discovery-Erfolg bedeutet, dass der Server antwortete, nicht dass jedes Backend gesund ist. Umgekehrt darf ein einzelner Toolfehler nicht sofort den ganzen Server sperren. Definiere Zustände wie verfügbar, degradiert, offen und prüfbereit sowie Schwellen für Übergänge. Zeige Nutzern die konkrete Lücke, statt die gesamte Sitzung zu beenden oder still eine andere, wirkende Fähigkeit zu wählen.

BetriebsregelEntferne erwiesen tote Optionen aus der Modellentscheidung, aber automatisiere ihre kontrollierte Rückkehr.

Eine Circuit-Breaker-Policy braucht genug Kontext, um nicht gesunde Fähigkeiten mitzusperren. Gruppiere nach Server, Backend oder konkretem Tool entsprechend der gemeinsamen Fehlerursache. Fünf Timeouts eines einzelnen langsamen Exports dürfen nicht zwingend schnelle Lese-Tools desselben Servers entfernen. Authentifizierungsfehler eines Tenants sind wiederum kein globaler Serverausfall. Verwende Mindeststichprobe und Zeitfenster, damit ein einzelner Zufallsfehler keinen Zustandswechsel auslöst. Im offenen Zustand wird die Fähigkeit nicht dem Modell angeboten; ein kleiner, kontrollierter Prüfverkehr entscheidet über die Rückkehr. Diese Zustände gehören in Metriken und Nutzerhinweise. Ohne Sichtbarkeit wirkt das Entfernen wie eine zufällig verschwundene Funktion. Ohne Begrenzung wirkt die Erholung wie eine neue Lastspitze. Der Host muss schließlich auch seinen Kontext bereinigen: Eine veraltete Toolbeschreibung im bereits aufgebauten Prompt darf das Modell nicht weiter zu einer Fähigkeit planen lassen, die die aktive Policy gerade ausgeschlossen hat.

Die Produktionsprobe verbindet alle Grenzen

Transport und Identität festlegenStateless Routing unter mehreren Replikaten prüfenProxy- und Streamabbrüche injizierenStatus und Idempotenz bei Wirkung testenFehlerkanäle und Retry-Budget beobachtenTeilausfall und automatische Erholung nachweisen

Eine belastbare Abnahme enthält keine reine Happy-Path-Demo. Starte zwei Nutzer parallel, verteile ihre Requests auf verschiedene Replikate und kappe die Verbindung an den gefährlichsten Stellen. Wiederhole denselben wirkenden Auftrag gleichzeitig. Lass einen Backenddienst langsam und einen ganzen MCP-Server unerreichbar werden. Prüfe danach Fachzustand, sichtbare Toolmenge, Logs, Metriken und Nutzertext. Jede Schicht soll die Unsicherheit benennen, die sie wirklich kennt.

  • Transport: minimale Reichweite, authentifizierte Gegenstelle und dokumentierte Proxygrenzen.
  • Zustand: kein impliziter Connection- oder Workerbesitz.
  • Wirkung: Idempotency-Key, Status und gegebenenfalls Kompensation.
  • Fehler: technischer und fachlicher Kanal mit richtigen Adressaten.
  • Resilienz: begrenzte Retries, lokale Degradation und automatische Erholung.
AusblickDas nächste Modul betrachtet den Host und Client als Orchestrator dieser Verträge: Discovery, Policy, Nutzerinteraktion und Kontextaufbereitung. Nimm dafür besonders die ehrliche Unterscheidung zwischen technischem Fehlschlag, fachlichem Ergebnis und unbekannter Wirkung mit.

Jetzt anwenden

Diesen Stoff gibt es als Modul mit bewerteten Entscheidungs-Checks — dieselbe Einführung, danach die Übungen.

Zum Modul →
Quellen & Aktualität7 Primärquellen · zuletzt geprüft:
  1. 01modelcontextprotocol.io/specification/2026-07-28/architecture
  2. 02modelcontextprotocol.io/specification/2026-07-28/basic/index
  3. 03modelcontextprotocol.io/specification/2026-07-28/basic/versioning
  4. 04modelcontextprotocol.io/specification/2026-07-…ilities/cancellation
  5. 05modelcontextprotocol.io/specification/2026-07-28/server/discover
  6. 06modelcontextprotocol.io/specification/2026-07-28/server/tools
  7. 07jsonrpc.org/specification