Deinen MCP-Server ändern ohne die Nutzer zu brechen
Dein Server ist veröffentlicht und Du willst ein Tool umbauen. In 10 Schritten machst Du die Oberfläche sichtbar, prüfst Änderungen automatisch und rollst um, ohne dass fremde Setups still kaputtgehen.
Beim ersten Veröffentlichen ist alles einfach. Du baust Tools, Du schiebst den Server raus, Leute binden ihn ein. Interessant wird es bei Version zwei. Ein Tool heißt unpassend, ein Parameter fehlt, eine Antwort soll strukturierter werden. Und ab jetzt hängt an jeder Änderung jemand dran, den Du nicht kennst und nicht fragen kannst.
Der Unterschied zu einer normalen Bibliothek: Deine Nutzer sind nicht nur Entwickler, sondern auch Sprachmodelle. Wenn ein Modell ein Tool bisher richtig aufgerufen hat und nach Deinem Update daneben greift, gibt es keinen Compiler-Fehler. Es gibt eine Antwort, die einfach schlechter ist. Genau das macht kaputte MCP-Änderungen so schwer zu bemerken.
Diese Anleitung zeigt Dir, wie Du Deine Oberfläche sichtbar machst, Änderungen automatisch prüfst und sauber umstellst.
Schritt 1: Klär, was aus Nutzersicht überhaupt Dein Vertrag ist
Dein Vertrag ist nicht Dein Code. Er ist genau das, was ein fremder Client beim Verbinden zu sehen bekommt: die Liste Deiner Tools mit Name, Beschreibung und Eingabe-Schema, dazu Deine Server-Angaben. Alles darunter darfst Du beliebig umbauen.
Nimm Dir fünf Minuten und schreib diese Oberfläche einmal als Liste auf. Pro Tool: Wie heißt es, welche Felder sind Pflicht, welche optional, was kommt zurück, und was bedeutet es fachlich. Diese Liste ist ab jetzt Dein Bezugspunkt.
Die letzte Spalte, die fachliche Bedeutung, ist die, die alle vergessen. Sie steht in keinem Schema und bricht trotzdem am härtesten.
Schritt 2: Mach die Beschreibung zum Teil der API
Bei einer klassischen Bibliothek ist ein Kommentar Kosmetik. Bei MCP ist die Beschreibung eines Tools funktional, denn das Modell entscheidet aus ihr heraus, ob es das Tool überhaupt aufruft.
Formulier eine Beschreibung um, und Du hast das Routing-Verhalten verändert, obwohl kein Schema angefasst wurde. Ein Tool, das vorher zuverlässig gewählt wurde, wird plötzlich übersprungen, oder ein anderes zieht die Aufrufe an sich.
Behandle Beschreibungen deshalb wie Code. Sie gehören in den Review, nicht in ein schnelles Aufräum-Commit nebenbei.
Schritt 3: Frier die Oberfläche als Datei ein
Dein Server kann seine eigene Tool-Liste ausgeben. Genau die schreibst Du in eine Datei und legst sie zu Deinem Code ins Repo, zum Beispiel als mcp-surface.json.
Ab jetzt ist Dein Vertrag nicht mehr eine Vorstellung im Kopf, sondern eine versionierte Datei. Jede Änderung an Deinen Tools erzeugt eine Änderung an dieser Datei, und die siehst Du im Diff, bevor irgendjemand sie merkt.
Das ist der eine Schritt, der das ganze Thema von Disziplin auf Mechanik umstellt. Ohne ihn bleiben alle folgenden Schritte gute Vorsätze.
Schritt 4: Lass den Diff Deinen Build anhalten
Bau einen Prüfschritt, der beim Testen die aktuelle Tool-Liste erzeugt und mit der eingecheckten Datei vergleicht. Weichen sie ab, bricht der Lauf ab.
Wichtig ist die Fehlermeldung. Sie soll nicht "Datei unterschiedlich" sagen, sondern was sich geändert hat und ob das für Nutzer harmlos oder heikel ist. Also: neues Tool dazu, Feld von optional auf Pflicht, Tool verschwunden.
Der Abbruch ist kein Verbot. Du darfst die Datei jederzeit aktualisieren. Du sollst nur nicht versehentlich dran vorbeilaufen.
Schritt 5: Merk Dir die vier Änderungen, die immer brechen
Erstens, ein Tool umbenennen. Jeder bestehende Aufruf zeigt ins Leere.
Zweitens, ein neues Pflichtfeld einführen. Alle Aufrufe, die es nicht mitschicken, fallen durch die Schema-Prüfung.
Drittens, ein bisher optionales Feld zur Pflicht machen. Derselbe Effekt, nur weniger offensichtlich.
Viertens, die Bedeutung bei gleichem Namen ändern. Ein Feld limit meinte gestern Zeilen und heute Seiten. Schema identisch, Ergebnisse falsch, und niemand bekommt einen Fehler. Das ist der Fall, der Dich am längsten verfolgt.
Schritt 6: Und die, die sicher sind
Ein neues Tool hinzufügen ist unkritisch, solange es bestehende nicht verdrängt.
Ein neues optionales Feld mit sinnvollem Standardwert ist unkritisch, denn alte Aufrufe funktionieren unverändert weiter.
Ein Ergebnis um ein zusätzliches Feld erweitern ist meistens unkritisch, solange die bisherigen Felder mit gleicher Bedeutung bleiben.
Alles, was aus Weglassen oder Umdeuten besteht, gehört in Schritt 5. Alles, was aus Ergänzen besteht, ist hier zuhause. Diese Trennlinie ist einfacher zu merken als jede Regelliste.
Schritt 7: Bau daneben statt umzubiegen
Du willst search_docs in find_documents umbenennen und die Parameter aufräumen. Der teure Weg ist, es in einem Rutsch zu tun.
Der ruhige Weg: Du legst das neue Tool zusätzlich an. Beide laufen parallel, intern rufen sie denselben Code. Das alte bleibt funktionsfähig, das neue ist der empfohlene Weg.
Damit verschiebst Du den Schmerz von Deinem Release-Tag auf einen Zeitpunkt, den Du selbst wählst. Und Du behältst die Möglichkeit, das alte Tool erst dann abzuschalten, wenn Du siehst, dass es keiner mehr benutzt.
Schritt 8: Kündige das Abschalten dort an, wo es gelesen wird
Ein Hinweis im Changelog erreicht Menschen, die Changelogs lesen. Das sind wenige, und Sprachmodelle sind nicht dabei.
Der Ort, der wirklich ankommt, ist die Beschreibung des alten Tools. Ein Satz reicht: dass dieses Tool ersetzt wurde, wie der Nachfolger heißt und ab wann es wegfällt. Modelle lesen diese Beschreibung bei jedem Verbinden, Entwickler sehen sie beim Debuggen.
Setz ein konkretes Datum statt "demnächst". Ohne Datum passiert nichts, und Du schleppst das alte Tool zwei Jahre mit.
Schritt 9: Pfleg die Versionsnummer, die Du ohnehin mitschickst
Beim Verbindungsaufbau meldet Dein Server seine Angaben, darunter eine Version. Viele setzen die einmal auf 1.0.0 und fassen sie nie wieder an.
Nutz sie stattdessen als Signal. Erhöh die dritte Stelle bei internen Korrekturen, die zweite bei Ergänzungen aus Schritt 6, die erste bei allem aus Schritt 5. Damit kann jemand, der Deinen Server einbindet, ohne Nachfrage sehen, wie riskant ein Update für ihn ist.
Das kostet Dich nichts und ist die einzige maschinenlesbare Warnung, die Du überhaupt hast.
Schritt 10: Wenn sich zur Laufzeit etwas ändert, sag Bescheid
Es gibt Server, deren Tool-Liste sich im Betrieb ändert, etwa weil ein Nutzer ein Modul freischaltet. Für diesen Fall sieht das Protokoll eine Benachrichtigung vor, mit der der Server dem Client mitteilt, dass sich die Liste geändert hat.
Wenn Deine Liste dynamisch ist, schick sie. Sonst arbeitet der Client mit einem Stand weiter, den es nicht mehr gibt, und ruft Tools auf, die verschwunden sind.
Wenn Deine Liste beim Start feststeht, brauchst Du das nicht. Dann ist Dein Release-Prozess die Stelle, an der die Änderung ankommt, und dafür hast Du die Schritte 3 bis 8.
Was als nächstes
Wenn Du an dieser Stelle stehst, hast Du einen laufenden Server mit echten Nutzern. Der nächste sinnvolle Ausbau ist Zugriffskontrolle, denn ab dem Moment, wo fremde Leute Dein Werkzeug einbinden, willst Du wissen wer. Das steht in MCP Auth.
Und wenn Du gerade von der anderen Seite kommst, also selbst fremde Server einbindest und wissen willst, worauf Du dabei achtest: das Playbook Fremde MCP-Server sicher prüfen ist die Gegenrichtung zu diesem hier.
Quellen
Die Angaben zu Tool-Definition, Eingabe-Schema und der Benachrichtigung bei geänderter Tool-Liste stammen aus der MCP-Spezifikation, Abschnitt Tools: https://modelcontextprotocol.io/specification/2025-06-18/server/tools
Die Server-Angaben beim Verbindungsaufbau inklusive Versionsfeld stehen im Abschnitt Lifecycle: https://modelcontextprotocol.io/specification/2025-06-18/basic/lifecycle