Die beiden Arten, wie MCP-Server versagen, und eine Schutzschicht, um dies zu verhindern
MCP-Server versagen aufgrund allzu umfassender Token und tools, die keine Aufgaben berücksichtigen. Begrenzte Token, Überprüfungen der Zielgruppe, sauber gehandhabte Fehler sowie Limits für Tools bilden eine Schutzschicht.
Quellen: MCP Servers Fail in Two Ways, and Both Are Preventable. Here’s the Guardrail Layer.
Die meisten MCP-Server versagen nicht durch Abstürze. Sie versagen dadurch, dass sie mehr Vertrauen gewähren, als die Aufgabe jemals erfordert – und zwar an zwei Stellen: bei den Berechtigungen, die sie zuweisen, sowie bei der Schnittstelle, die sie bereitstellen. Ein intelligenteres Modell wird das nicht beheben. Eine Schutzschicht zwischen dem Agenten und dem Tool wird es hingegen tun, und die folgenden Abschnitte zeigen mit Code, was eine solche Schicht enthält.
Eine Aufräumarbeit, die niemand angefordert hat
Ein Benutzer bittet einen Agenten, eine Produktionsdatenbank in eine Prüfumgebung zu kopieren. Beim Bearbeiten der Anfrage entscheidet der Agent, dass ein Aufräumschritt sinnvoll wäre, und löscht zunächst einige alte Testdaten. Das hat niemand verlangt. Wenn der MCP-Server die eigenen Anmeldeinformationen des Benutzers weiterleitet und dieser über Admin-Rechte verfügt, erfolgt die Löschung, und die Produktionsdaten sind verschwunden.
AWS führt genau dieses Szenario in seinen Richtlinien zur MCP-Verwaltung an, um zu erklären, warum Scope-Tokens nicht übersprungen werden dürfen.
Der Server ist eine Vertrauensgrenze
Menschen beschreiben einen MCP-Server in der Regel genauso wie jede Art von Integrationstool: als etwas, das einen Agenten mit einem System verbindet, wobei nur wenige Tools bereitgestellt werden und die Aufgabe erledigt ist. Tatsächlich ist er der einzige Punkt, an dem die Entscheidung des Modells zum Handeln zu einem echten Nebeneffekt wird, indem echte Infrastruktur und echte Anmeldeinformationen verwendet werden. Alle Schritte davor sind lediglich logisches Denken. Der Server ist der Punkt, an dem das logische Denken Konsequenzen hat.
Daher ist der Server – egal ob absichtlich oder nicht – eine Vertrauensgrenze. Betrachtet man Produktivserver aus dieser Perspektive, lassen sich ihre Fehler in zwei Gruppen einteilen.
Fehlerklasse eins: zu viele Berechtigungen
Die Datenbank-Thematik stellt den allgemeinen Fall dar. AWSs Leitlinien zur Verwaltung nennen die Lösung: Jeder nachgelagerte Aufruf sollte einen absichtlich begrenzten Token enthalten, der speziell für diesen Aufruf generiert wird – niemals die Anmeldeinformationen, mit denen der Agent gestartet wurde. Zudem soll die Audience-Angabe des Tokens überprüft werden, damit ein für einen MCP-Server erstellter Token nicht auf einem anderen Server erneut verwendet werden kann.
Nur wenige Teams setzen dies früh um, da es mehr Einrichtungsarbeit erfordert als das Weiterleiten des Tokens des Aufrufers. Doch genau das macht den Unterschied zwischen einem fehlerhaften, aber sicher abgebrochenen Tool-Aufruf und einem, der tatsächlich in der Produktion eingesetzt wird.
Fehlerklasse zwei: eine schlechte Schnittstelle
Die zweite Gruppe ist subtiler. Es kommt zu keinem dramatischen Vorfall. Die Zuverlässigkeit nimmt einfach ab, und es ist schwierig, den Grund dafür herauszufinden. Microsofts Entwicklungsrichtlinien für Azure MCP weisen auf die zugrunde liegende Gewohnheit hin: Server werden wie REST-APIs konzipiert, wobei jede Operation als eigenständiges Tool bereitgestellt wird, obwohl die Gestaltung eigentlich danach ausgerichtet sein sollte, was der Agent erreichen möchte. Die dazugehörige Illustration macht diesen Punkt gut verständlich. Anstelle von vier Tools mit den Namen create_ticket, add_comment, assign_ticket und notify_user erledigt ein einziges Tool namens file_support_request alle vier Schritte intern.
Die Anleitung weist auf zwei weitere Symptome dieser Gewohnheit hin. Beschreibungen können Dinge versprechen, die das Tool nicht erfüllt, wodurch der Agent Texten vertraut, die der Code niemals einhält. Zudem können Fehlermeldungen nutzlos sein (“Error”) oder zu aufschlussreich: Stack-Traces, interne Dateipfade oder die Bestätigung, dass ein bestimmter Benutzer in der Datenbank vorhanden ist – was allein schon Enumeration-Angriffe ermöglicht.
Eine Asymmetrie bei der Richtung des Misstrauens
Betrachten Sie, wie viel Ingenieursarbeit in die endgültige Antwort eines Agents fließt: Validierung der strukturierten Ausgabe, Schutzmechanismen, Wiederholungsversuche sowie ÜberprüfungsSchritte. Die Ausgabe des Modells gilt als verdächtig – und zu Recht.
Betrachten Sie nun die Schicht zur Aufrufung von Tools unter dieser Antwort. Das Token des Aufrufers gelangt direkt weiter. Die Liste der Tools erweitert sich, ohne dass jemand überprüft, ob das Modell noch in der Lage ist, damit zu arbeiten. Die Beschreibung eines Tools wird unverändert akzeptiert, und es gibt keinen Test, der zeigt, dass ein Agent das Tool korrekt verwendet. Es wird viel Energie in das Zweifeln an dem investiert, was das Modell sagt, während kaum Energie darauf verwendet wird, zu prüfen, was es tatsächlich tut.
Dieses unausgeglichenen Misstrauen ist der eigentliche Mangel bei beiden Ansätzen. Weder eine intelligentere Berechtigungslogik noch bessere Tool-Bezeichnungen allein werden dieses Problem lösen. Was benötigt wird, ist eine Schicht, die jeden Tool-Aufruf – und nicht nur jede Modellantwort – überprüft, bevor ihr Vertrauen gewährt wird.
Die Schicht erstellen
Die Grundeinheit hier ist der Tool-Aufruf. Lassen Sie keine rohe Anfrage direkt zum Backend gelangen – verpacken Sie sie zunächst.
from dataclasses import dataclass
from datetime import datetime, timedelta
from typing import Optional
@dataclass
class ScopedToken:
audience: str # which MCP server this token is valid for
permissions: list[str] # e.g. ["read", "create"] - never assume "all"
issued_at: datetime
expires_at: datetime
source_user: str # who originally triggered this, for audit
Jedes Feld in diesem Wrapper existiert dafür, dass die nächste Schicht beurteilen kann, inwieweit der Aufruf vertrauenswürdig ist. Jetzt kommen die Steuerelemente.
Definieren Sie den Geltungsbereich des Tokens vor dem Ausführen der Tool
Wiederverwenden Sie die vom Aufrufer übermittelten Anmeldeinformationen nicht für nachfolgende Aktionen. Erstellen Sie ein engeres Token, das ausschließlich das umfasst, was das Tool ausführen wird.
def issue_scoped_token(user_token: ScopedToken, tool_name: str,
required_permissions: list[str]) -> ScopedToken:
# Never grant more than the tool declares it needs
granted = [p for p in required_permissions if p in user_token.permissions]
if set(required_permissions) - set(granted):
raise PermissionError(
f"{tool_name} requires {required_permissions}, "
f"caller only has {user_token.permissions}"
)
return ScopedToken(
audience=tool_name,
permissions=granted,
issued_at=datetime.utcnow(),
expires_at=datetime.utcnow() + timedelta(minutes=5),
source_user=user_token.source_user,
)
Das ist der Mechanismus, der dafür sorgt, dass das Datenbank-Szenario sicher fehlschlägt. Eine Anfrage, die auf Lesen und Erstellen beschränkt ist, kann einfach kein Löschvorgang durchführen, unabhängig von der Entscheidung des Modells.
Überprüfen Sie die zugrunde liegende Benutzerrolle bei jeder Aufrufung
Ein Token, das für ein bestimmtes Tool erstellt wurde, sollte von allen anderen Tools abgelehnt werden.
def enforce_audience(token: ScopedToken, expected_tool: str) -> None:
if token.audience != expected_tool:
raise PermissionError(
f"Token issued for '{token.audience}' cannot be used on '{expected_tool}'"
)
Formen Sie das Werkzeug an die Aufgabe an
Dies befolgt das Muster file_support_request aus Azures Leitfaden:
def file_support_request(customer_email: str, issue_type: str, description: str) -> dict:
ticket = create_ticket(issue_type, description)
add_comment(ticket.id, f"Filed by {customer_email}")
assign_ticket(ticket.id, team=route_by_type(issue_type))
notify_user(customer_email, ticket.id)
return {
"ticket_id": ticket.id,
"status": "open",
"assigned_team": ticket.team,
}
Ein einzelner Anruf enthält eine klare Absicht, sodass der Agent niemals selbst die Reihenfolge von vier Operationen richtig einhalten muss.
Fehler bereinigen, bevor der Agent sie sieht
Die vollständigen Details werden auf dem Server aufgezeichnet, und dem Agenten wird nur das zur Verfügung gestellt, was er zur Wiederherstellung benötigt.
def safe_error(internal_message: str, request_id: str) -> dict:
# internal_message goes to your logs, never to the model
log.error(internal_message, extra={"request_id": request_id})
return {
"content": [{
"type": "text",
"text": f"Unable to complete the request. Request ID: {request_id}. "
f"Try again or contact support."
}],
"isError": True,
}
Maximalanzahl der Tools pro Server begrenzen
Erfahren Sie die Grenze, bevor es in der Produktion zu Problemen kommt. Microsoft gibt eine Zahl an: mehr als 10 bis 15 Tools pro Server, aufgeteilt nach Domänen, und man sollte keinen einzelnen Server weiter ausbauen.
MAX_TOOLS_PER_SERVER = 15
def register_tool(server, tool):
if len(server.tools) >= MAX_TOOLS_PER_SERVER:
raise ValueError(
f"{server.name} already has {len(server.tools)} tools. "
f"Split into a domain-specific server instead of adding more."
)
server.tools.append(tool)
Drei schnelle Überprüfungen auf einem bestehenden Server
Keine dieser Überprüfungen erfordert einen Neubau.
Überprüfen Sie den Umfang des Audit-Tokens, nicht nur dessen Vorhandensein. Holen Sie sich zehn aktuelle Aufrufe der Tools und vergleichen Sie die Berechtigungen, die jedes Token hatte, mit dem, was das Tool benötigte. Wenn sich die beiden meist unterscheiden, werden breitere Tokens als nötig weitergegeben – das ist vermutlich der aktuelle Zustand.
Berechnen Sie die Anzahl der Tokens für Ihre eigenen Tools. Die Richtlinien von AWS schätzen, dass bereits allein für Beschreibungen 5.000 bis 10.000 Tokens pro Aufruf benötigt werden, sobald ein Server mehr als 20 Tools hat. Zählen Sie Ihre Tools. Ein Server, der weit darüber hinausgeht und weder filtert noch aufteilt, leidet unter einem Kontextüberschuss, den keine Modifikation des Modells beheben kann.
Probieren Sie einen auf Agentenebene ausgerichteten Test, der vermutlich noch nicht durchgeführt wurde. Wählen Sie die drei am häufigsten genutzten Tools aus und prüfen Sie mithilfe eines echten Agents – und nicht eines Unit-Tests –, ob dieser aus einer alltäglichen Anfrage in natürlicher Sprache das richtige Tool auswählt. Microsofts Anleitung bezeichnet dies als die Schicht, die fast jeder übersieht. Das Bestehen von Unit- und Protokolltests ohne Durchführung dieses Tests lässt unklar, ob die Tools tatsächlich funktionieren.
Wie es zum Rest passt
Nichts davon ersetzt die bestehenden Arbeiten zur Zuverlässigkeit, sondern ergänzt sie. Begrenzte Token folgen demselben Prinzip wie die Validierung von Eingaben an jeder Vertrauensgrenze. Eine Obergrenze für die Anzahl der Tools sowie ein auf Aufgaben ausgerichtetes Design spiegeln die Disziplin des API-Versionierens und des Interface-Designs wider – nur für eine Oberfläche, die von einem Modell gelesen wird und nicht von einem menschlichen Entwickler. Jeder MCP-Server ist ein weiterer Ort, an dem das System entscheidet, inwieweit es einem Aufrufer vertrauen kann, weshalb er genauso sorgfältig behandelt werden muss wie die anderen.
Teams adoptieren MCP, weil es Agenten mehr Reichweite bietet: einen standardisierten Zugang zu echten Systemen anstelle von hundert individuellen Integrationen. Das Problem ist jedoch, dass ein Modell einen schlecht abgegrenzten Aufruf genauso zuverlässig ausführt wie einen gut abgegrenzten, da es keinen Unterschied wahrnimmt. Nur die Schutzschicht erkennt diesen Unterschied.
Genehmigungsfehler und Schnittstellenfehler scheinen unzusammenhängend zu sein – der eine betrifft den Zugriff, der andere das Design. Beide entstehen aus einer unüberlegten Annahme heraus, dass ein Tool-Aufruf bereits das Vertrauen genießt, das ihm in Wirklichkeit niemand gewährt hat. Die meisten KI-Systeme richten ihren Verdacht auf die Ausgabeseite. Auch die Tool-Aufruf-Seite verdient dies.
Das lässt nur eine Frage offen, die an jeden genutzten MCP-Server gestellt werden kann: Was verhindert derzeit, dass ein Agent auf einen Aufruf mit übermäßigem Vertrauen reagiert, und würde ein Alarm ausgelöst, falls dies bereits der Fall wäre?
Kurze Antworten
Was ist das Token-Scope-Prinzip bei MCP? Es bedeutet, jedem Tool-Aufruf zu diesem Zweck ein eigenes, eingeschränktes Token zuzuweisen und die ursprünglichen Anmeldeinformationen des Aufrufers nicht weiterzuleiten. AWSs Leitlinien empfehlen dies, damit halluzinierte oder unbeabsichtigte Aktionen nicht einfach deshalb erfolgreich werden können, weil die zugrunde liegenden Anmeldeinformationen dies zuließen.
Wie viele Tools sollte ein MCP-Server bereitstellen? Laut den Richtlinien von Azure liegen die Empfehlungen bei 10 bis 15 als Faustregel, danach sollte der Server nach Domänen aufgeteilt werden. Danach wählen die Agenten deutlich seltener das richtige Tool, und laut den Richtlinien von AWS liegt die Kostenbelastung durch eine lange Liste an Tools bei 5.000 bis 10.000 Tokens pro Aufruf allein für die Beschreibungen, wenn es mehr als 20 Tools gibt.
Wie unterscheidet sich das auf Aufgaben ausgerichtete Tool-Design vom System-API-Design? Beim System-API-Design wird jede Backend-Operation zu einem eigenen Tool, ähnlich wie bei einer REST-API. Beim auf Aufgaben ausgerichteten Design wird das, was der Benutzer erreichen möchte, als ein einziges Tool bereitgestellt, das die einzelnen Schritte intern abwickelt. Ein Beispiel von Microsoft ist ein einziges Tool „file_support_request“ anstelle von vier Ticketsystem-Operationen.
Warum sollten MCP-Fehlermeldungen gesäubert werden? Stack-Traces, interne Pfade oder Hinweise darauf, dass ein bestimmtes Datensatz existiert, liefern Angreifern Informationen, die sie nicht erhalten sollten – was zumindest eine Enumerationsschwäche darstellt. Ein sichererer Ansatz besteht darin, die vollständigen Details in Server-seitige Logs zu schreiben und dem Agenten nur das zurückzugeben, was er zur Wiederherstellung benötigt, zusammen mit einer Korrelations-ID.
Fangen Unit-Tests diese Probleme auf? Nein. Unit-Tests beziehen sich ausschließlich auf die Logik eines Tools, während Protokolltests die MCP-Konformität überprüfen – doch keines davon beweist, dass ein Agent das Tool in einer realistischen Situation finden, auswählen und korrekt verwenden kann. Dafür ist eine dritte Testschicht erforderlich, die von einem echten Agenten gesteuert wird – die jedoch von den meisten Teams weggelassen wird.
Verwandte Literatur
- MCP-Infrastruktur selbst aufbauen oder kaufen: Ein Entscheidungshilfe für SaaS-Teams — Abwägung zwischen einem eigenen MCP-Server und einer verwalteten Plattform: tatsächliche Arbeitslast, Authentifizierung, Grad der Kontrolle, Einschränkungen, ein hybrider Ansatz sowie fünf Fragen, die zuerst geklärt werden sollten.
- WebMCP, servicebasiertes MCP oder einfache Browsernutzung: Wo Agentenwerkzeuge hingehören — Eine kritische Betrachtung von WebMCP: Seitenwerkzeuge gegenüber servicebasiertem MCP und herkömmlichen Browser-Agenten, mit Schwerpunkt auf Sessions, OAuth CIMD, Entdeckung, lokalem Zustand und Eigentumsverhältnissen.