Fareed Khan baut in seinem Artikel über die 11 Schichten eines production-grade MCP-Servers einen fiktiven, aber bis ins Detail ausgearbeiteten Production-MCP-Server „Atlas-MCP“: Postgres Row-Level Security für die Tenant-Isolation, OAuth 2.1, eine Policy-Engine mit Default-Deny, Approval Gates für destruktive Operationen, Circuit Breaker, Redis Token Bucket, zweistufiges Caching, Observability. Es liest sich wie ein Katalog von allem, was schwierig wird, sobald ein Agent kein Spielzeug mehr ist. Fast alles trifft. Ein Vorbehalt hat mich dazu gebracht, diese Notiz zu schreiben.
Was ich übernehme
- Default-Deny überall. Unbekannte Policy-Bedingungen schlagen geschlossen fehl (fail closed); eine leere Outbound-Allowlist bedeutet null ausgehende Requests. Der richtige Default für Agenten: Prompt Injection umgeht nicht, was physisch verboten ist — statt nur durch eine Zeile im Prompt.
- Approval Gate als Control Surface. Ein destruktives Tool wird nicht ausgeführt, sondern erzeugt einen Pending-Eintrag mit TTL; ein Mensch genehmigt, beide Ausgänge landen im Audit-Log. Der Autor vergleicht das mit der Bestätigung von Änderungen in Claude Code — der Vergleich sitzt: Bestätigung ist keine Zeremonie, sondern die Kontrollfläche.
- Audit mit
args_hashstatt Rohargumenten — Korrelation von Ereignissen, ohne PII zu horten. - Strukturierte Fehler (
code/retryable/hint): „Agents cannot recover from Python tracebacks.“ An eigenen Agenten geprüft — sie erholen sich nicht.
Wo ich widerspreche
Der Artikel setzt einen dedizierten MCP-Server als obligatorischen Kontrollpunkt voraus und vergleicht ihn kein einziges Mal mit der Alternative: Der Agent ruft CLI/API direkt auf. Für das Szenario des Artikels — Multi-Tenant-SaaS, fremde Nutzer, Write-Operationen — ist die Wahl richtig: Dort ist der MCP-Server der einzige Ort, an dem RLS, Auth und Rate Limits zusammenleben. Ich habe aber den gegenteiligen Production-Fall vor Augen: einen Read-only-Kubernetes-Debugging-Agenten, dessen Autor mit einem MCP-Wrapper begann und ihn bewusst zugunsten von Bash + curl + Skills aufgab. Das Argument ist einfach: Ein MCP-Tool wie query(query: string) typisiert die Art des Aufrufs, aber den Request-Body — den MetricsQL-String, den kubectl-Filter — schreibt weiterhin das LLM. Typisierung beseitigt das Hauptrisiko nicht. Die Read/Write-Trennung kam dort aus einer Allow/Deny-Liste für das Bash-Tool plus GET-only curl — ohne eine einzige MCP-Schicht.
Mein eigenes Setup funktioniert genauso: Wiederkehrende Prozeduren leben in Skills; MCP ist nur dort angebunden, wo ich dauerhaften typisierten Zugriff auf einen externen Dienst brauche (ein lokales LLM auf einer separaten Maschine). Die Arbeitsregel: Die Schichten aus dem Artikel sind Eigenschaften des Deployment-Kontexts, nicht des Protokolls. Multi-Tenant, Write-Operationen, fremde Daten — die meisten dieser Schichten sind Pflicht, und sie gehören an einen Ort. Ein einzelner Entwickler, read-only, eine CLI, die das Modell aus dem Pretraining kennt — da reicht ein Harness: Allowlist, GET-only, ein Bestätigungs-Gate.
Noch ein Grund, den Artikel mit dem Bleistift zu lesen: die Zahlen. „Eine dreistufige Tool-Hierarchie senkt fehlerhafte Tool-Aufrufe um ~40 %“ stützt sich auf eine externe Fallstudie und ist im Kern nicht überprüfbar. Als Größenordnung — vielleicht; als Benchmark — nein.
Fazit
Als Katalog der schwierigen Probleme produktiver Agentensysteme ist der Artikel ausgezeichnet. Ihn als Checkliste für jeden Agenten zu lesen wäre der Fehler. Schichten schaltet der Blast Radius ein, nicht die Mode.