Ein MCP-Tool wird nicht dadurch sicher, dass der Chat vor dem Aufruf höflich um Zustimmung bittet. Diese verbreitete Annahme verlagert eine technische Freigabe in einen Dialog, dessen Ablauf der Server weder kontrollieren noch zuverlässig nachweisen kann. Für Schreibzugriffe brauchst du deshalb einen serverseitigen Zustand zwischen Vorschau und Ausführung.
Die zentrale Regel lautet: Das Modell darf eine Änderung vorbereiten, aber nicht selbst freigeben. Der MCP-Server führt sie erst aus, nachdem ein berechtigter Mensch die konkrete Änderung über einen getrennten Freigabekanal bestätigt hat.
Das Ziel: Aus einem Tool-Aufruf werden drei getrennte Aktionen
MCP steht für Model Context Protocol. Über das Protokoll kann ein KI-Client unter anderem definierte Tools aufrufen. Ein Tool kann Daten lesen oder eine Aktion auslösen. Kritisch wird es, sobald ein Aufruf einen dauerhaften Zustand verändert.
Als durchgehendes Beispiel dient die Änderung einer E-Mail-Adresse in einem Kundenverzeichnis. Das ist technisch überschaubar, zeigt aber das eigentliche Problem: Eine falsche Adresse kann Benachrichtigungen fehlleiten oder nachgelagerte Prozesse beeinflussen.
Der sichere Ablauf besteht aus drei klar getrennten Aktionen:
- Das MCP-Tool prüft die gewünschte Änderung und legt einen unveränderlichen Vorschlag an.
- Ein berechtigter Mensch prüft diesen Vorschlag in einer separaten Freigabeansicht.
- Ein zweiter Tool-Aufruf führt ausschließlich den bereits freigegebenen Vorschlag aus.
Die Freigabe liegt damit als serverseitiger Datensatz vor. Der Chat kann sie weder durch eine geschickt formulierte Eingabe ersetzen noch durch einen selbst gesetzten Parameter vortäuschen.
Zuerst den Schreibzugriff eindeutig abgrenzen
Bevor du Tools implementierst, trennst du lesende und schreibende Aufgaben. Ein Tool wie customer_find sucht einen Datensatz und verändert nichts. customer_email_change_prepare legt nur einen Änderungsvorschlag an. Erst customer_email_change_execute darf die gespeicherte Adresse ändern.
Vermeide ein universelles Tool mit Parametern wie action, resource und payload. Ein solches Werkzeug ist zwar flexibel, erschwert aber Berechtigungen, Freigabetexte und Tests. Ein eng zugeschnittenes Tool kann genau angeben, welche Wirkung es hat.
Für die Einordnung helfen vier Fragen:
- Verändert der Aufruf dauerhaft gespeicherte Daten?
- Löst er externe Folgen aus, etwa eine E-Mail, Veröffentlichung oder Bestellung?
- Kannst du die Änderung vollständig und eindeutig rückgängig machen?
- Kann ein einzelner Aufruf mehrere Datensätze oder Personen betreffen?
Sobald eine dauerhafte oder externe Wirkung möglich ist, sollte der Server eine explizite Freigabe verlangen. Bei besonders weitreichenden Aktionen kann die richtige Entscheidung auch lauten, sie gar nicht über MCP anzubieten.
Das vorbereitende Tool möglichst eng definieren
Das erste Tool nimmt nur die Daten entgegen, die für den Änderungsvorschlag erforderlich sind. Die Identität des aufrufenden Kontos gehört nicht in die Eingabe. Sie muss aus der authentifizierten MCP-Verbindung oder dem serverseitigen Sitzungskontext stammen.
Eine mögliche Eingabe sieht so aus:
{
"customer_id": "cus_184",
"new_email": "redaktion@example.org",
"reason": "Adresse laut Stammdatenkorrektur aktualisieren"
}Der Server führt bei diesem Aufruf noch keine Änderung aus. Er erledigt stattdessen folgende Arbeit:
- Er prüft, ob das aufrufende Konto den Datensatz sehen und eine Änderung vorschlagen darf.
- Er lädt den aktuellen Wert aus der maßgeblichen Datenquelle.
- Er validiert den neuen Wert nach denselben Regeln wie eine normale Bearbeitungsmaske.
- Er erzeugt eine verständliche Differenz zwischen aktuellem und vorgeschlagenem Zustand.
- Er speichert Ziel, alte Daten, neue Daten, Initiator und Ablaufzeit als ausstehende Aktion.
Der gespeicherte Vorschlag sollte nachträglich nicht editierbar sein. Ändert sich die gewünschte E-Mail-Adresse, entsteht ein neuer Vorschlag. Sonst könnte ein Mensch Variante A prüfen, während der Server später Variante B ausführt.
Als Ergebnis erhält der Client eine zufällige Aktions-ID, eine Zusammenfassung und den Pfad zur Freigabeansicht:
{
"action_id": "act_random",
"status": "pending",
"summary": "E-Mail-Adresse für cus_184 ändern",
"approval_path": "/mcp-actions/act_random"
}Die Aktions-ID muss zufällig und nicht erratbar sein. Sie ist trotzdem keine Freigabe. Wer sie kennt, darf die Aktion lediglich referenzieren.
Die Freigabe außerhalb des Modellkontexts einholen
Die Freigabeseite gehört zu deiner Anwendung oder einem internen Verwaltungsbereich. Der Mensch öffnet sie in einer eigenen, authentifizierten Sitzung. Dadurch bleibt die Entscheidung von den Tool-Aufrufen des Modells getrennt.
Auf der Seite sollten mindestens folgende Informationen sichtbar sein:
- der betroffene Datensatz in einer für Menschen verständlichen Bezeichnung,
- der aktuelle und der vorgeschlagene Wert,
- bekannte Folgewirkungen der Änderung,
- der Auslöser beziehungsweise das anfragende Konto,
- Schaltflächen zum Freigeben und Ablehnen.
Eine allgemeine Schaltfläche mit der Beschriftung „Bestätigen“ ist zu ungenau. „E-Mail-Adresse ändern“ beschreibt die Wirkung besser. Bei Veröffentlichungen, Löschungen oder externen Nachrichten muss die Beschriftung entsprechend konkret sein.
Der Freigabe-Endpunkt prüft die menschliche Sitzung, die Berechtigung für den betroffenen Datensatz und den Status der Aktion. Schutzmechanismen gegen unbeabsichtigte Webanfragen, etwa ein CSRF-Schutz, gehören ebenfalls an diese Stelle. Nach der Zustimmung wechselt der gespeicherte Zustand von pending zu approved.
Ein Parameter wie confirmed: true im MCP-Tool ist kein Ersatz dafür. Das Modell kann diesen Wert selbst senden. Gleiches gilt für Sätze wie „Der Nutzer hat zugestimmt“, denn sie sind lediglich Eingabedaten.
Das ausführende Tool akzeptiert nur die Aktions-ID
Das zweite MCP-Tool benötigt keine neue E-Mail-Adresse und keinen frei formulierten Änderungswunsch. Es bekommt nur die ID des gespeicherten Vorschlags:
{
"action_id": "act_random"
}Alle wirksamen Daten lädt der Server aus dem freigegebenen Datensatz. Dadurch kann der Client zwischen Freigabe und Ausführung keine Parameter austauschen.
Vor dem Schreiben prüft der Server erneut:
- Existiert die Aktion und gehört sie zum richtigen Mandanten oder Arbeitsbereich?
- Hat sie den Status approved?
- Ist die Freigabe noch gültig?
- Darf das ausführende Konto die Aktion weiterhin ausführen?
- Entspricht der aktuelle Datensatz noch dem Stand, auf dessen Grundlage die Vorschau erstellt wurde?
- Wurde die Aktion bereits ausgeführt?
Die fünfte Prüfung verhindert eine stille Überschreibung. Wurde die E-Mail-Adresse nach Erstellung der Vorschau anderweitig geändert, ist die Freigabe fachlich veraltet. Der Server bricht ab und verlangt eine neue Vorschau.
Bei einer eigenen Datenbank sollten Änderung und Statuswechsel möglichst in derselben Transaktion erfolgen. Entweder werden sowohl der Kundendatensatz als auch die Aktion aktualisiert oder beides bleibt unverändert. Bei externen Diensten ist das nicht immer möglich. Dann brauchst du eine eindeutige Referenz für den externen Aufruf und einen Status, mit dem sich ein unklarer Ausgang gezielt nachverfolgen lässt.
Wiederholte Aufrufe ohne doppelte Wirkung behandeln
Ein MCP-Client kann einen Aufruf nach einem Timeout wiederholen, obwohl die erste Ausführung erfolgreich war. Das ausführende Tool muss deshalb idempotent sein: Mehrere Aufrufe mit derselben Aktions-ID dürfen dieselbe Änderung nur einmal bewirken.
Nach erfolgreicher Ausführung erhält die Aktion den Status executed sowie einen Ergebnisverweis. Kommt dieselbe Anfrage erneut, führt der Server nichts mehr aus. Er gibt stattdessen das bereits vorhandene Ergebnis zurück.
Für das Beispiel könnte die Antwort so aussehen:
{
"action_id": "act_random",
"status": "executed",
"result": "E-Mail-Adresse wurde aktualisiert"
}Diese Eigenschaft ist besonders wichtig, wenn ein Tool E-Mails sendet, Einträge an Fremdsysteme übermittelt oder andere Aktionen mit externen Folgen auslöst. Ein erneuter HTTP-Aufruf darf nicht automatisch eine erneute fachliche Aktion bedeuten.
Den gesamten Freigabeablauf mit Zuständen modellieren
Ein einzelnes boolesches Feld wie approved reicht für den Lebenszyklus kaum aus. Ein eindeutiger Status macht ungültige Übergänge sichtbar. Für den beschriebenen Ablauf genügen meist diese Zustände:
- pending: Der Vorschlag wartet auf eine Entscheidung.
- approved: Ein berechtigter Mensch hat genau diesen Vorschlag freigegeben.
- rejected: Der Vorschlag wurde abgelehnt.
- executed: Die freigegebene Änderung wurde erfolgreich ausgeführt.
- expired: Der Vorschlag darf wegen seines Alters nicht mehr verwendet werden.
- conflicted: Die zugrunde liegenden Daten haben sich seit der Vorschau geändert.
Definiere zusätzlich erlaubte Übergänge. Aus pending darf beispielsweise approved, rejected oder expired werden. Eine ausgeführte Aktion darf nicht wieder in den freigegebenen Zustand zurückspringen. Für eine erneute Änderung wird ein neuer Vorschlag angelegt.
Mit fachlichen Szenarien statt nur mit Tool-Aufrufen testen
Ein erfolgreicher Einzeltest beweist nur, dass der günstige Weg funktioniert. Für die Freigabelogik sind vor allem die unerwünschten Wege aufschlussreich.
- Ausführung ohne Freigabe: Das Tool muss den Aufruf ablehnen und darf keine Daten verändern.
- Manipulierte Eingabe: Zusätzliche Änderungsdaten beim ausführenden Tool müssen ignoriert oder als ungültig abgewiesen werden.
- Doppelte Ausführung: Der zweite Aufruf liefert das vorhandene Ergebnis zurück.
- Veraltete Vorschau: Hat sich der Quelldatensatz geändert, wird die Ausführung gestoppt.
- Falscher Arbeitsbereich: Eine Aktions-ID aus einem anderen Mandanten darf weder angezeigt noch ausgeführt werden.
- Abgelaufene Freigabe: Eine alte Aktion kann nicht reaktiviert werden.
- Entzogene Berechtigung: Der Server prüft Rechte bei der Ausführung erneut.
- Ablehnung: Eine abgelehnte Aktion bleibt dauerhaft nicht ausführbar.
Teste außerdem den Inhalt der Vorschau. Werden technische IDs gezeigt, obwohl der Mensch eine Kundenbezeichnung benötigt, ist die Freigabe formal vorhanden, aber praktisch fehleranfällig. Eine brauchbare Vorschau beantwortet klar: Was ändert sich, bei welchem Datensatz und mit welchen bekannten Folgen?
Wo dieser Ablauf nicht ausreicht
Der Freigabe-Workflow begrenzt das Risiko eines unkontrollierten Tool-Aufrufs. Er macht eine fachlich ungeeignete Aktion jedoch nicht automatisch vertretbar. Massenlöschungen, Zahlungen, rechtlich bindende Erklärungen oder Änderungen mit schwer überschaubaren Nebenwirkungen benötigen eventuell zusätzliche Freigabestufen oder gehören gar nicht in ein MCP-Tool.
Auch die getrennte Freigabeseite hilft nur, wenn Konten und Berechtigungen sauber verwaltet werden. Nutzt der MCP-Server ein gemeinsames technisches Konto ohne Bezug zu einem Arbeitsbereich oder Verantwortlichen, lässt sich die Aktion später nur eingeschränkt zuordnen.
Prüfe zuletzt, ob das Tool eine Aktion direkt ausführen muss. Häufig ist ein Entwurf die bessere technische Wirkung: Das MCP-Tool erstellt beispielsweise einen Inhaltsentwurf, eine vorbereitete Antwort oder einen Änderungsantrag. Die bestehende Fachanwendung übernimmt anschließend Prüfung und Veröffentlichung.
Fazit: Die Zustimmung muss für den Server beweisbar sein
Ein sicherer Schreibzugriff über MCP entsteht durch einen kontrollierten Zustandswechsel. Das Modell bereitet einen unveränderlichen Vorschlag vor, ein Mensch gibt ihn außerhalb des Modellkontexts frei und der Server führt ausschließlich diesen freigegebenen Vorschlag aus.
Wenn dein ausführendes Tool nur eine Aktions-ID akzeptiert, Berechtigungen und Datenstand erneut prüft und wiederholte Aufrufe ohne doppelte Wirkung behandelt, bleibt die Kontrolle an der richtigen Stelle. Eine freundliche Rückfrage im Chat kann weiterhin sinnvoll sein. Die technische Freigabe ersetzt sie allerdings nicht.
Häufige Fragen
Kurz beantwortet, damit du schneller einschätzen kannst, was für dein Projekt wichtig ist.
Braucht jeder schreibende MCP-Aufruf eine menschliche Freigabe?
Nicht zwingend. Entscheidend sind Wirkung, Reichweite und Umkehrbarkeit. Dauerhafte Änderungen, externe Nachrichten, Veröffentlichungen und Löschungen solltest du grundsätzlich strenger behandeln als leicht rückgängig zu machende Entwürfe.
Warum genügt ein Parameter wie confirmed: true nicht?
Das Modell oder der MCP-Client kann diesen Parameter selbst senden. Eine belastbare Freigabe muss deshalb serverseitig gespeichert und über einen getrennten, authentifizierten menschlichen Zugriff erteilt werden.
Warum werden Vorbereitung und Ausführung auf zwei Tools verteilt?
Die Trennung verhindert, dass frei gelieferte Änderungsdaten unmittelbar eine Wirkung auslösen. Das ausführende Tool verwendet nur den unveränderlichen, bereits geprüften und freigegebenen Vorschlag.
Was passiert, wenn sich der Datensatz nach der Vorschau ändert?
Der Server sollte die Ausführung als Konflikt abbrechen. Anschließend wird auf Basis des aktuellen Datenstands ein neuer Vorschlag erstellt und erneut freigegeben.