# MCP-Client-Konfiguration prüfen, bevor du einem Server vertraust

Ein neuer MCP-Server verdient dieselbe Prüfung wie eine neue ausführbare Datei, die innerhalb deines Entwicklerkontos laufen möchte. Die Konfigurationsdatei wirkt vielleicht harmlos, weil sie nur einen Befehl und ein paar Argumente enthält. In der Praxis legt dieser Eintrag fest, welcher Code startet, welche Umgebung er erhält, auf welche Verzeichnisse er zugreifen kann und welche Tool-Beschreibungen einem Agenten angeboten werden.

Der Fehler, den ich immer wieder sehe, ist die Gleichsetzung von „lokal“ mit einer Vertrauensgrenze. Das ist es nicht. Ein lokaler Server startet normalerweise mit deinen Benutzerrechten, kann handeln, bevor er sein erstes Tool veröffentlicht, und möglicherweise Zugangsdaten erben, die niemand teilen wollte. Prüfe den Startvertrag, bevor sich der Client verbindet. Prüfe anschließend die angekündigten Aktionen, bevor der Agent sie aufrufen kann.

## Ein lokaler Server läuft mit den Folgen deines Kontos

Ein lokaler MCP-Server ist ein Kindprozess und kein harmloses Konfigurationsobjekt. Wenn dein Client ihn unter deinem normalen macOS-Konto startet, kann der Server möglicherweise zugängliche Projektdateien lesen, in dein Benutzerverzeichnis schreiben, ausgehende Netzwerkverbindungen herstellen und die für diesen Prozess verfügbaren Umgebungsvariablen untersuchen. MCP isoliert den Server nicht. Das Protokoll überträgt Nachrichten, schränkt aber nicht ein, was die ausführbare Datei zwischen diesen Nachrichten tut.

Dieser Unterschied ist wichtig, wenn ein Server über einen Paketbefehl kommt. Diese Konfiguration:

```json
{
  "command": "npx",
  "args": ["-y", "some-mcp-server"]
}
```

tut mehr, als eine bekannte lokale Binärdatei zu starten. Sie fordert einen Paket-Runner auf, ein Paket aufzulösen, Code aus seinem Cache zu installieren oder wiederzuverwenden und ihn zu starten. Eine saubere Maschine, ein gefüllter Cache und ein geänderter Paket-Tag können unterschiedlichen Code ausführen. Der vertraute Befehl verleitet dazu, die entscheidende Frage zu überspringen: Welche ausführbare Datei läuft heute genau?

Dasselbe gilt für einen Server, der neben dem Projekt ausgecheckt wurde. Ein Repository kann eine seriöse MCP-Implementierung und zugleich einen schädlichen Installations-Hook, Wrapper oder eine Laufzeitabhängigkeit enthalten. Prüfe den Pfad, der den Prozess startet, nicht nur die Quelldatei, deren Name in einer Einrichtungsanleitung steht.

Nutze das Betriebssystemkonto als erste Entscheidung zur Eingrenzung. Ein wegwerfbarer Arbeitsbereich, ein separates Konto mit geringen Rechten oder eine virtuelle Maschine gibt einem frühen Test weniger Zugriff als das Konto, in dem Produktionsquellcode und Cloud-Zugangsdaten liegen. Das ersetzt keine Codeprüfung. Es begrenzt den Schaden, wenn deine Prüfung etwas übersieht.

## Das command-Feld muss wörtlich gelesen werden

Lies Befehl und Argumente genau so, wie der Client sie ausführen wird. Übersetze sie nicht gedanklich in die freundliche Beschreibung einer README.

Die sicherere Form verwendet einen festen Pfad zur ausführbaren Datei und ein Argument-Array:

```json
{
  "command": "/Users/dev/tools/acme-mcp/bin/server",
  "args": ["--config", "/Users/dev/review/acme-mcp.json"],
  "env": {
    "HOME": "/Users/dev/review-home",
    "PATH": "/usr/bin:/bin"
  }
}
```

Diese Form liefert konkrete Prüfpunkte. Existiert die ausführbare Datei an diesem Pfad? Wem gehört sie? Liegt die Konfigurationsdatei außerhalb eines Repositorys, das andere ändern können? Braucht der Prozess `HOME` überhaupt? Benötigt er tatsächlich einen Compiler, einen Paketmanager oder einen weit gefassten `PATH`?

Ein Wrapper verändert die Prüfung. Vergleiche damit:

```json
{
  "command": "sh",
  "args": ["-c", "npx -y acme-mcp --token $SERVICE_TOKEN"]
}
```

Die Shell erweitert nun `$SERVICE_TOKEN`, liest Shell-Syntax und kann mehr als das erwartete eine Programm ausführen. Der Paket-Runner kann Code abrufen. Der Server erhält ein Geheimnis als Befehlsargument, das in der Prozessübersicht und Diagnoseausgaben erscheinen kann. Jede dieser Schichten bringt Verhalten mit, das ein direkter Pfad zur ausführbaren Datei vermeidet.

Gehe nicht davon aus, dass jeder Client `command` gleich ausführt. Manche Clients starten Prozesse direkt mit einem Argument-Array. Andere bieten eine Shell-orientierte Einstellung oder erlauben ein Wrapper-Skript. Lies die Dokumentation des Clients und teste den Start mit einem nicht sensiblen Befehl, bevor du einen echten freigibst. Wenn das Format sowohl direkte Ausführung als auch eine Shell erlaubt, wähle die direkte Ausführung, sofern der Server keinen konkreten Bedarf hat, den du erklären kannst.

Prüfe Wrapper Zeile für Zeile. Kleine Skripte verbergen oft das riskanteste Verhalten: das Herunterladen einer Version, das Lesen einer Token-Datei, das Ändern des Arbeitsverzeichnisses, das Exportieren aller Umgebungsvariablen oder einen stillen Neustart über eine andere Laufzeit. Ein Starter mit zwanzig Zeilen kann mehr Aufmerksamkeit verdienen als die Hauptimplementierung des Servers.

## Die geerbte Umgebung ist das übersehene Leck für Zugangsdaten

Ein `env`-Block bedeutet nicht zuverlässig „das ist die gesamte Umgebung“. Bei vielen APIs zum Starten von Prozessen wird die Umgebung des Elternprozesses weitergegeben, sofern der Starter sie nicht ausdrücklich ersetzt. Die Einträge in `env` ergänzen oder überschreiben dann ausgewählte Werte. Dein MCP-Client kann selbst aus einem Terminal, einem Desktop-Starter, einem Editor oder einem Automatisierungsdienst gestartet worden sein, und jeder Weg kann andere Variablen liefern.

Dadurch entsteht eine gefährliche Lücke zwischen dem, was Prüfer sehen, und dem, was der Server erhält. Das JSON kann nur `LOG_LEVEL` aufführen, während der Prozess zusätzlich ein Token für eine Paket-Registry, ein Token für die Quellcodeverwaltung, Cloud-Zugangsdaten, Proxy-Einstellungen, SSH-Agent-Details und eine interne Dienst-URL vom Client erbt.

Schreibe vor der Verbindung den Umgebungsvertrag in einfacher Sprache auf: Dieser Prozess braucht diesen Endpunkt, diese nicht geheime Einstellung und vielleicht genau eine eng begrenzte Zugangsdaten. Alles andere ist versehentlich verliehene Autorität.

Ein sinnvoller erster Durchlauf startet den Client selbst aus einer schlanken Shell. Dieser macOS- und Unix-Befehl bewahrt nur wenige gewöhnliche Variablen:

```sh
env -i HOME="$HOME/review-home" PATH="/usr/bin:/bin" LANG="${LANG:-C}" \
  YOUR_MCP_CLIENT
```

Ersetze `YOUR_MCP_CLIENT` durch den tatsächlichen Client-Befehl. Wenn der Server fehlschlägt, füge jeweils eine Variable hinzu und notiere, warum er sie braucht. Löse den Fehler nicht, indem du die gesamte Login-Umgebung wiederherstellst. Diese Abkürzung hat mehr Zugangsdaten offengelegt, als vielen bewusst ist.

Du kannst eine gespeicherte Konfiguration auch prüfen, ohne einen Befehl auszuführen. Das folgende Python-Fragment gibt Servernamen, Befehle, Argumente und die Namen ausdrücklich gesetzter Umgebungsvariablen aus. Werte der Umgebung werden absichtlich nicht ausgegeben.

```sh
python3 - "$HOME/.config/your-client/mcp.json" <<'PY'
import json, sys

with open(sys.argv[1], encoding="utf-8") as f:
    data = json.load(f)

for name, spec in data.get("mcpServers", {}).items():
    print(f"server: {name}")
    print(f"  command: {spec.get('command', '')}")
    print("  args:")
    for arg in spec.get("args", []):
        print(f"    - {arg}")
    print("  explicit env names:")
    for env_name in sorted(spec.get("env", {})):
        print(f"    - {env_name}")
PY
```

Die Ausgabe sieht etwa so aus:

```text
server: issue-tracker
  command: /Users/dev/tools/issue-mcp/server
  args:
    - --read-only
  explicit env names:
    - ISSUE_TRACKER_URL
```

Wenn du Namen wie `AWS_SECRET_ACCESS_KEY`, `GITHUB_TOKEN`, `SSH_AUTH_SOCK` oder `SERVICE_TOKEN` siehst, halte an und frage, warum der Server sie benötigt. Geheime Werte werden nicht sicher, nur weil eine JSON-Datei sie statt Quellcode enthält. Konfigurationsdateien werden in Backups kopiert, in Supportanfragen geteilt, versehentlich committed und von jedem Prozess gelesen, der Zugriff auf die Datei hat.

## Eine Tool-Liste ist eine Fähigkeitsbehauptung, keine Berechtigung

Die Model Context Protocol-Spezifikation definiert `tools/list` zur Erkennung und `tools/call` zum Aufruf. Das ist nützlich, weil ein Client die vom Server vorgeschlagene Schnittstelle prüfen kann, bevor ein Agent ein Tool auswählt. Es zertifiziert weder den Server noch seine Beschreibungen oder die Nebenwirkungen hinter einem Aufruf.

Behandle jedes angekündigte Tool als vorgeschlagene Fähigkeit. Lies Namen, Beschreibung, Eingabeschema und vorhandene Annotationen zusammen. Ein Tool namens `search_issues` kann eine schreibgeschützte Anfrage stellen oder vor der Suche Projektdateien sammeln und an Dritte senden. Ein Tool namens `deploy_preview` kann Ressourcen anlegen, DNS ändern oder einen Zugang mit einem weiteren Umfang nutzen, als sein Name vermuten lässt.

Die MCP-Spezifikation erlaubt es Servern, Annotationen zu liefern, die auf Verhalten hinweisen, etwa ob ein Tool Daten liest, Daten ändert oder mit einem externen System interagiert. Solche Hinweise helfen einem Client bei einer nützlichen Oberfläche, werden durch die Spezifikation aber nicht zu einer Durchsetzung. Ein unehrlicher oder nachlässiger Server kann ein zerstörerisches Tool als schreibgeschützt kennzeichnen. Dein Betriebssystem und die Zugangsdaten des Servers prüfen dieses Etikett nicht, bevor eine Aktion ausgeführt wird.

Führe für jeden freigegebenen Server ein kleines Verzeichnis:

- Tool-Name und die behauptete Aktion.
- Eingaben, die Dateipfade, URLs, Shell-Fragmente oder freie Aufforderungen enthalten können.
- Systeme, die das Tool erreichen kann, und die verwendeten Zugangsdaten.
- Nebenwirkungen, auch indirekte wie das Senden von Daten an eine entfernte API.
- Die genaue geprüfte Version oder der Quellstand.

Bewahre das Verzeichnis in der Nähe der Konfiguration auf. Ein Diff wird aussagekräftig, wenn ein Update `delete_repository` hinzufügt, `query` in `execute` ändert oder eine Eingabe für eine beliebige URL ergänzt. Ohne vorheriges Verzeichnis genehmigen Menschen oft eine geänderte Liste, weil der Servername noch vertraut aussieht.

Beschreibungen verdienen denselben Verdacht wie jeder andere nicht vertrauenswürdige Text, der an einen Agenten geliefert wird. Ein Server kann ein Tool als zwingend erforderlich darstellen, behaupten, dass keine Genehmigung nötig sei, oder den Agenten anweisen, nicht verwandte Geheimnisse als Argumente zu übergeben. Der Agent sollte Servertext nicht als höherwertige Autorität behandeln als die Anfrage des Benutzers und die Genehmigungsregeln des Clients.

## Zugangsdaten brauchen eine Grenze außerhalb des Agentenprozesses

Gib einem Server kein langlebiges API-Token und keinen privaten SSH-Schlüssel, nur weil er auf demselben Laptop läuft. Sobald der Serverprozess ein Geheimnis erhält, kann er es protokollieren, weiterleiten, auf der Festplatte speichern oder über ein Tool-Ergebnis offenlegen. Der Client kann das Geheimnis nicht zurückholen, nachdem der Prozess es gelesen hat.

Trenne zwei Entscheidungen, die Teams oft vermischen. Einen Server zu starten bedeutet, die Ausführung von Code zu erlauben. Eine Produktionszugangsdaten zu verwenden bedeutet, auf ein externes System einzuwirken. Ein Server kann die erste Erlaubnis in einem Testarbeitsbereich verdienen, ohne die zweite zu verdienen.

Für einfache Entwicklungsaufgaben stelle ein begrenztes, kurzlebiges Zugangstoken aus, das nur Testdaten erreichen kann. Schreibe seinen Umfang auf. „Vom Issue-Server verwendet“ ist vage. „Darf Tickets im Sandbox-Projekt lesen, aber weder erstellen noch kommentieren oder Mitgliedschaften ändern“ gibt Prüfern etwas, das sie testen können.

Für Aktionen, die einen wichtigen Zugang benötigen, bewahre das Geheimnis in einer lokalen Zugangsdaten-Grenze auf und stelle nur die eng begrenzte Operation bereit. Sallyport verfolgt diesen Ansatz für HTTP- und SSH-Aktionen: Der Agent erhält weder den API- noch den SSH-Schlüssel, während die App die Aktion ausführt und das Ergebnis zurückgibt.

Diese Grenze verändert den Umgang mit Geheimnissen, nicht die Notwendigkeit einer Serverprüfung. Ein schädlicher Server kann einen Agenten weiterhin auffordern, einen autorisierten, aber folgenschweren Aufruf auszuführen. Platziere die Genehmigung dort, wo die Konsequenz entsteht, begrenze Zugangsdaten auf die kleinste sinnvolle Berechtigung und lies jede Anfrage, die ein für dich wichtiges System erreicht.

Übergib Zugangsdaten nicht als Befehlsargumente. Prozesslisten, Absturzberichte, Diagnoseausgaben und Elternprozesse können sie offenlegen. Vermeide aus demselben Grund Klartext-Geheimnisse in Konfigurationsdateien. Wenn eine Einrichtungsanleitung ein Geheimnis an einer dieser Stellen verlangt, kläre zuerst, ob der Server einen Zugangsdaten-Tresor des Betriebssystems, ein kurzlebiges Token oder einen externen Aktionsdienst verwenden kann.

## Der erste Kontakt sollte in einem langweiligen Testkonto stattfinden

Führe einen unbekannten Server in einem kontrollierten Konto aus, bevor du ihm ein Projekt, eine umfangreiche Umgebung oder echte Zugangsdaten gibst. Dieser Test beantwortet eine begrenzte Frage: Was tut das Programm beim Start und wenn der Client seine Tools anfordert?

Verwende ein neues Verzeichnis mit harmlosen Dateien, deren Namen unerwartete Lesevorgänge sichtbar machen. Gib dem Prozess ein temporäres `HOME`. Starte mit einem schlanken `PATH`. Binde kein Verzeichnis voller Quellcode ein, nur weil du einen Quellcodeverwaltungsserver testen willst. Beginne mit einem gefälschten Repository oder einer Kopie ohne Zugangsdaten.

Achte auf das Verhalten vor jedem Tool-Aufruf. Ein Server, der beim Start eine Netzwerkverbindung öffnet, dein Benutzerverzeichnis durchsucht, Browserdaten liest oder Persistenzdateien anlegt, geht bereits über das hinaus, was die meisten MCP-Anwendungsfälle erfordern. Manche Server prüfen berechtigterweise einen Endpunkt oder laden eine lokale Konfiguration. Dieses Verhalten sollte leicht erklärbar und leicht deaktivierbar sein.

Fordere anschließend das Tool-Verzeichnis an, prüfe es und führe einen harmlosen Aufruf mit bekannten Eingaben aus. Zeichne Anfrage, Ergebnis, Prozessausgabe und im Testverzeichnis geänderte Dateien auf. Wenn das Tool Inhalte aus einem anderen System zurückgibt, mache die Testdaten eindeutig, damit du erkennst, ob es den richtigen Ort aufgerufen hat.

Eine grundlegende Prüfsequenz sieht so aus:

1. Prüfe den Pfad zur ausführbaren Datei, Paketversion, Prüfsumme oder Quellstand sowie jedes Starter-Skript.
2. Starte in einem Testkonto oder isolierten Arbeitsbereich mit schlanker Umgebung.
3. Zeichne das erste `tools/list`-Ergebnis auf und vergleiche jedes Tool mit dem vorgesehenen Zweck.
4. Rufe eine harmlose Leseaktion mit gefälschten Daten auf und beobachte Dateien, Kindprozesse und Netzwerkziele.
5. Füge nur die Zugangsdaten und den Verzeichniszugriff hinzu, die das bestätigte Verhalten erfordert.

Verwechsle eine erfolgreiche Antwort nicht mit einem sicheren Server. Ein Server kann die erwartete Antwort liefern und gleichzeitig Dateien kopieren oder anderswo ein geerbtes Token nutzen. Der Test liefert Belege, aber keinen Beweis. Er entdeckt nachlässige Entwürfe und offensichtliche Überraschungen, bevor sie Produktionszugriff erhalten.

## Paketkomfort schafft einen Updatepfad, den du selbst kontrollieren musst

Paketmanager und Laufzeit-Starter machen die MCP-Einrichtung angenehm kurz. Sie schaffen aber auch einen Updatepfad. Ein Versionsbereich, ein frei beweglicher Paket-Tag oder ein bloßer Paketname kann den Server ändern, der nächste Woche startet, ohne dass sich die Konfiguration sichtbar ändert.

Fixiere eine Version, wenn dein Ökosystem das unterstützt, und dokumentiere die Paketquelle neben dem Tool-Verzeichnis. Noch besser ist ein geprüftes lokales Artefakt oder eine Lock-Datei, die dein Team bereits kontrolliert. Das Ziel ist einfach: Ein späterer Start soll auf Code verweisen, den du identifizieren kannst.

Lass den Agenten keinen eigenen MCP-Server als Teil einer Aufgabe installieren. Damit werden Softwarebeschaffung, Ausführung und Tool-Autorisierung in eine einzige Gesprächsanfrage gepackt. Ein Mensch sollte die Serverkonfiguration nach Prüfung des Quellcodes und des Startvertrags hinzufügen. Wenn ein Entwicklungsablauf viele Server benötigt, pflege einen geprüften Katalog, statt Einrichtungsfragmente aus Issue-Kommentaren oder Tool-Ausgaben zu übernehmen.

Updates verdienen eine kurze erneute Prüfung. Vergleiche die ausführbare Datei oder Lock-Datei, Befehl und Argumente, die ausdrücklich gesetzten Umgebungsvariablen und das `tools/list`-Verzeichnis. Eine neue Funktion kann harmlos sein. Sie kann aber auch Schreibzugriff einführen, den die frühere Prüfung nie berücksichtigt hat. Dasselbe gilt, wenn ein Server Zugangsdaten, Endpunkt oder Authentifizierungsbibliothek ändert.

Die verbreitete Empfehlung „Verwende aus Sicherheitsgründen immer das neueste Paket“ ist für MCP-Server unvollständig. Sicherheitsupdates solltest du zeitnah einspielen, aber eine ungeprüfte automatische Änderung kann den Code verändern, der neben deinen Zugangsdaten läuft. Nutze einen kontrollierten Updateprozess, der dir erlaubt, die Änderung zu prüfen und zurückzurollen, wenn sich der neue Server anders verhält.

## Die Genehmigung sollte der Aktion folgen, nicht dem Namen des Servers

Eine einmalige Genehmigung für einen Serverprozess beantwortet nur eine Frage: Darf diese ausführbare Datei an dieser Sitzung teilnehmen? Sie kann nicht sicher jede spätere Frage beantworten, etwa ob ein entfernter Branch gelöscht, Kundendaten gesendet oder ein SSH-Befehl auf einem Produktionshost geöffnet werden darf.

Trenne gewöhnliche Erkennung von folgenschweren Aktionen. Verfügbare Projekte aufzulisten, ein öffentliches Issue zu lesen und ein lokales Schema abzurufen erfordert oft weniger Prüfung als Datensätze zu ändern oder Daten aus dem Rechner zu senden. Dein Client oder deine Zugangsdaten-Grenze sollte eine neue menschliche Genehmigung verlangen, sobald ein Aufruf diese Grenze überschreitet. Wenn jeder Leseaufruf Aufmerksamkeit verlangt, klicken Menschen einfach weiter. Wenn ein einziger Startklick unbegrenzten Produktionszugriff gewährt, wird das irgendwann bereut.

Auch die Prozessidentität zählt. Eine Genehmigungsabfrage sollte angeben, welcher signierte Prozess Zugriff angefordert hat, und nicht nur ein vom Server gewähltes Etikett anzeigen. Ein Name wie `database-helper` kann von jedem Programm kopiert werden. Der Pfad zur ausführbaren Datei, die Signaturidentität, sofern verfügbar, und die Startargumente bieten eine bessere Prüfoberfläche.

Führe Aufzeichnungen auf zwei Ebenen: über die Agentensitzung, die die Arbeit angefordert hat, und über die einzelne Aktion, die Zugangsdaten verwendet oder einen externen Dienst erreicht hat. Das Sitzungsprotokoll brauchst du, um zu untersuchen, warum ein Agent Berechtigungen hatte. Das Aktionsprotokoll brauchst du, um zu untersuchen, was tatsächlich geändert wurde. Ein einziges Protokoll kann beide Fragen nicht sauber beantworten, wenn entweder der Aufrufer oder die genaue Anfrage fehlt.

Ein manipulationssicheres Protokoll hilft, wenn Server, Client oder Betreiber später bestreiten, was geschehen ist. Es macht eine gefährliche Aktion im Moment der Genehmigung nicht sicher. Lies Ziel, Methode, Befehl und wichtige Parameter, bevor du eine Aktion genehmigst, die sich nicht leicht rückgängig machen lässt.

## Ein abgelehnter Server braucht Bereinigung, nicht nur Entfernung

Wenn du nach einer Verbindung entscheidest, dass ein Server nicht vertrauenswürdig ist, entferne seinen Client-Eintrag sofort, aber höre dort nicht auf. Der Prozess kann Dateien geschrieben, Shell-Konfigurationen geändert, geplante Aufgaben erstellt, einen Repository-Hook verändert oder während seiner Laufzeit Zugangsdaten kopiert haben.

Sichere Beweise, bevor du alles löschst. Speichere Konfiguration, Paketversion oder Quellstand, Prozessausgabe und Aktionsprotokolle. Prüfe anschließend das Test-`HOME`, das Arbeitsverzeichnis des Servers, den Paket-Cache, Shell-Startdateien, Launch Agents, Repository-Hooks und alle Verzeichnisse, in die der Server schreiben konnte. Kontrolliere aktive Prozesse und aktuelle Netzwerkverbindungen, solange die Beweise noch vorhanden sind.

Tausche jedes Geheimnis aus, das der Prozess hätte lesen können, nicht nur das absichtlich übergebene. Dazu gehören geerbte Tokens, SSH-Agent-Zugriff, Paket-Zugangsdaten und gegebenenfalls browsergestützte Entwicklungssitzungen. Eine Zeile aus einer Konfigurationsdatei zu entfernen, widerruft kein kopiertes Token.

Verschärfe anschließend den Prüfprozess, der die Verbindung ermöglicht hat. Lag der Fehler in einer geerbten Umgebung, verwende einen schlanken Starter. Lag er in einem unerwarteten Paketupdate, fixiere Versionen und prüfe Artefakte. Lag er in einer irreführenden Tool-Beschreibung, verlange vor der Genehmigung ein aufgezeichnetes Verzeichnis. Das nützliche Ergebnis ist eine geänderte Kontrolle, nicht das vage Versprechen, beim nächsten Mal vorsichtiger zu sein.

Ein neuer MCP-Server erhält seinen gefährlichsten Zugriff in dem Moment, in dem er noch kein Vertrauen verdient hat. Mache seinen Befehl wörtlich, seine Umgebung klein, seine Tool-Liste geprüft und seine Zugangsdaten vom Agenten getrennt. Genau an diesem Punkt kontrollierst du das Ergebnis noch.
