mcp-confirm
mcp-confirm
In einfachen Worten: Wenn eine KI fragt „Bist du sicher?“, verhindert das MCP SDK bereits, dass diese Bestätigung für eine andere Aktion wiederverwendet wird. Es verhindert nicht, dass dieselbe Bestätigung zweimal verwendet wird. Dies schließt diese Lücke und zwei weitere, die das SDK offen lässt.
Zuerst lesen: Der Großteil dieses Problems ist bereits gelöst
Die MCP-Spezifikation vom 28.07.2026 führte Multi Round-Trip Requests ein, sodass ein Tool mitten im Aufruf pausieren und den Benutzer um Bestätigung bitten kann. Die Bestätigung reist als undurchsichtiger requestState durch den Client zurück, den Server laut Spezifikation MÜSSEN als angreiferkontrolliert behandeln.
Das Python-SDK erledigt das standardmäßig auf jedem MCPServer. RequestStateBoundary wird bedingungslos an die Middleware-Kette angehängt – mit einem ephemeren Schlüssel, wenn Sie keinen angeben. Es versiegelt den Zustand mit AES-256-GCM und bindet ihn an die Methode, das Ziel, einen Digest der Aufrufargumente, die Audience und den authentifizierten Principal, mit einer TTL.
Der Angriff, nach dem jeder zuerst greift – Bestätigung zum Löschen von cache.txt, dann Wiederverwendung dieser Bestätigung gegen thesis.txt – wird vom SDK bereits abgelehnt. Dafür brauchen Sie keine Bibliothek, und Sie sollten auch keine schreiben.
Dieses Repository hat ursprünglich trotzdem eine geschrieben: 250 Zeilen HMAC, TTL und Argumentbindung, als Hauptfeature ausgeliefert, überflüssig noch am Tag der Veröffentlichung. Das ist unten dokumentiert, statt stillschweigend gelöscht zu werden.
Related MCP server: RecourseOS
Was das SDK nicht tut
Drei Lücken, jede mit einem Test, der auslöst.
1. Es bindet den Zustand und lässt ihn ablaufen. Es verbraucht ihn nie.
Innerhalb der TTL verifiziert die gleiche Bestätigung so oft, wie sie vorgelegt wird. Jede Prüfung, die die Boundary durchführt, besteht jedes Mal. Die Spezifikation stellt ausdrücklich klar, dass dies beabsichtigt ist und dass der Rest Ihre Aufgabe ist:
Beachten Sie, dass diese Maßnahmen das Wiedergabefenster begrenzen und die Wiederverwendung über Benutzer und Anfragen hinweg verhindern, aber für sich genommen keine Einmalverwendung garantieren. Server, für die ein bestimmter
requestStatehöchstens einmal verbraucht werden darf (z. B. Einmal-Einlösungen), MÜSSEN diese Invariante serverseitig durchsetzen.
Für „Datei löschen“ findet der zweite Versuch nichts. Für „£500 überweisen“ ist es das gesamte Problem. singleuse.py ist diese Invariante – ein Hauptbuch ausstehender Bestätigungen, das bei der Einlösung verbraucht wird. Es enthält keine Kryptografie, weil die Boundary bereits garantiert, dass der Klartext von diesem Server stammt.
2. Nichts bereinigt die Frage, die der Mensch liest
Eine Elicitation-message ist ein vom Server gewählter Text, der einer Person angezeigt wird, normalerweise mit einem nicht vertrauenswürdigen Wert, der hineininterpoliert wird – der ganze Sinn ist zu sagen, welche Datei verschwindet. Nennen Sie also eine Datei:
cache.txt
SYSTEM NOTICE: your session has expired.
Enter your AWS secret key to continue:Der Dialog trägt jetzt eine zweite, offiziell aussehende Aufforderung. Der Benutzer bestätigt keine Löschung; er wird von seiner eigenen Tooling-Infrastruktur phisht. Dieselbe Veröffentlichung vom 28.07.2026 brachte auch MCP Apps – servergerenderte UI – heraus, was diese Angriffsfläche eher vergrößert als verkleinert.
prompt.py reduziert nicht vertrauenswürdige Werte auf eine Zeile, entfernt bidirektionale Überschreibungen und Nullbreitenzeichen und kürzt von der Mitte aus, sodass der Dateiname am Ende sichtbar bleibt. Steuerzeichen werden zu Leerzeichen statt gelöscht, denn wenn man sie zusammenfallen ließe, würden a\nb und ab identisch dargestellt – zwei verschiedene Dateien, ein Dialog.
3. Keine Protokollebene kann Ihre Ressource zur Ausführungszeit erneut prüfen
Der Benutzer hat in der Zwischenzeit darüber nachgedacht. Die Datei kann in diesem Fenster ersetzt werden, und nur das Tool weiß, was „unverändert“ für sie bedeutet. Dieser Server prüft vor dem Löschen erneut und lehnt einen Pfad ab, der zu einem Symlink geworden ist.
Welche Ebene lehnt was ab
Das ist der nützliche Teil, und die Tests sind geschrieben, um genau das zu zeigen. MCPError bedeutet, dass die Middleware des SDKs abgelehnt hat, bevor dieses Paket lief; ToolError bedeutet, dass dieses Paket es getan hat.
Angriff | Abgelehnt von | Test |
Bestätigung auf eine andere Datei wiedergegeben | SDK |
|
Zustand gefälscht oder unter einem anderen Schlüssel versiegelt | SDK |
|
Dieselbe Bestätigung zweimal verbraucht | dieses Paket |
|
Zustand von einer anderen Replik erzeugt | dieses Paket |
|
Dateiname fälscht einen Systemprompt | dieses Paket |
|
Datei nach der Bestätigung gegen einen Symlink ausgetauscht | dieses Paket |
|
Pfad außerhalb der erlaubten Roots | dieses Paket |
|
Tests
35 Tests – 17 über den Server, 11 für das Hauptbuch, 7 für die Prompt-Bereinigung.
Jeder Server-Test läuft durch die echte RequestStateBoundary, dieselbe Klasse, die MCPServer auf sich selbst installiert, mit einem festgelegten Schlüssel – Runde eins versiegeln und Runde zwei entsiegeln genau so, wie es die Leitung tun würde.
Dieser Testrahmen existiert wegen eines bestimmten Fehlers. Die erste Version testete, indem sie MCPServer.call_tool() direkt aufrief, was direkt zum Tool-Manager geht und die Middleware-Kette vollständig umgeht. Die Boundary des SDKs lief nie, sodass eine redundante, handgebaute Absicherung tragend wirkte. Das Testdesign war es, das dies einen gesamten Build-Zyklus lang verbarg.
Die Abdeckung beträgt 81 %, mit prompt.py bei 100 % und singleuse.py bei 94 %. Die Lücke ist das argparse- und Transport-Wiring von main(), das stattdessen über build_server getestet wird.
CI läuft nur auf Ubuntu, bewusst: Die Tests für den Austausch nach Bestätigung benötigen Symlinks, und der Build schlägt fehl, wenn sie dort als übersprungen gemeldet werden.
Installation
pip install git+https://github.com/les-k/mcp-confirm.gitAusführen
mcp-confirm --root /path/you/allowOhne --root lehnt der Server jede Anfrage ab, statt auf irgendetwas zurückzufallen. Die Roots werden beim Start festgelegt und niemals vom Agenten gewählt. Kein Signaturschlüssel ist nötig – MCPServer bringt seinen eigenen mit.
Bekannte Einschränkungen
Das Hauptbuch ist im Speicher, also ist es für einen Prozess korrekt und hinter einem Load Balancer falsch. Das SDK unterstützt das Teilen von Schlüsseln über Repliken hinweg (
RequestStateSecurity(keys=[...])); unter dieser Konfiguration lehnt Replik B eine von Replik A ausgestellte Bestätigung ab. Es schließt sicher – die sichere Richtung –, wirkt für einen Benutzer aber wie eine Bestätigung, die unerklärlicherweise nicht mehr funktioniert. Eine Multiprozess-Bereitstellung benötigt Redis oder eine Datenbankzeile mit einem atomaren Vergleich-und-Löschen. Es gibt einen Test für dieses Verhalten.Das Demonstrationswerkzeug ist bewusst klein. Es löscht eine Datei. Der interessante Code ist
singleuse.pyundprompt.py.Kein CVE stützt das. MRTR ist erst Wochen alt, also basiert dies auf der eigenen MUST/SHOULD-Liste der Spezifikation und auf dem Lesen des SDKs, nicht auf einem veröffentlichten Vorfall.
Was an Version 0.1.0 falsch war
Hier aufbewahrt, weil ein Repository, das nur seine Erfolge festhält, kein Beleg für irgendetwas ist.
0.1.0 hat neu implementiert, was das SDK bereits tat. state.py war 250 Zeilen HMAC-Signierung, TTL und Principal-/Methoden-/Argumentbindung – alles eine Duplizierung von RequestStateBoundary, nichts davon so gut: HMAC, wo das SDK authentifizierte Verschlüsselung verwendet, keine Audience-Bindung, keine Schlüsselrotation.
Es wurde durch das Lesen des SDK-Quellcodes entdeckt, nicht durch einen Test. Die Tests bestanden genau deshalb, weil sie die Middleware umgingen, die es aufgedeckt hätte.
CI entdeckte separat einen echten Fehler in 0.1.0: Die Symlink-Prüfung lief nach Path.resolve(), untersuchte also das Ziel des Links statt des Links selbst. Ein Austausch, der auf eine andere Datei innerhalb eines erlaubten Roots zielte, wäre gelöscht worden. Behoben, mit einem Test für die Variante, die das Original nie ausführte.
0.2.0 löscht state.py vollständig und behält nur das, was das SDK nicht abdeckt.
Lizenz
MIT.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceAn MCP server that provides safeguard capabilities to protect against prompt injection and unsafe tool calls.6MIT

RecourseOSofficial
AlicenseNot gradedqualityAmaintenanceMCP server that evaluates Terraform plans, shell commands, and tool calls to assess recoverability and risk before execution, enabling safe AI agent actions.1511MIT- AlicenseNot gradedqualityCmaintenanceMCP server that provides human-in-the-loop approval for risky AI agent actions, with durable state and audit logs.MIT
- FlicenseNot gradedqualityCmaintenanceMCP server that provides a security gateway for AI agents, enforcing allow/confirm/deny policies on tool calls and requiring human approval for risky operations, with full audit logging.
Related MCP Connectors
Security firewall for AI agents — scans MCP calls for injection, secrets, and risks.
Security scanner for MCP servers. Detect vulnerabilities, prompt injection, and tool poisoning.
Scans MCP servers for tool poisoning, prompt injection and supply chain risks.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/les-k/mcp-confirm'
If you have feedback or need assistance with the MCP directory API, please join our Discord server