Blog • MCP
Nach dem Upgrade auf Claude Code 2.1.305 lädt ein stdio-Server in managed-mcp.json, der eine Variable nur in env nutzt, wieder. Wie schreiben Sie deniedMcpServers?
Die Notiz zu Claude Code 2.1.305 ist ein Satz, und nach dem Upgrade kann ein Server von selbst erscheinen: allowedMcpServers filtert stdio-Server in managed-mcp.json nicht mehr, die ${VAR} nur in env nutzen. Fehlte der Server auf der Allowlist, lädt er. Was ihn aus hält, ist deniedMcpServers, nicht eine weitere Kopie der Allowlist.
Wer MCP-Rechte trägt, steht in dem Artikel zur MCP-Sicherheit. Welcher Protokollschritt Zugangsdaten zum falschen Autorisierungsserver stoppt, steht in dem vorherigen OAuth-Artikel. Dieser Artikel behandelt nur die Änderung in 2.1.305: die Allowlist stoppt einen stdio-Server mit einer Variable nur in env nicht mehr, und das Denylist-JSON muss den Befehl exakt treffen.
- Es geht um einen stdio-Server in managed-mcp.json, dessen ${VAR} nur in env steht.
- Ab 2.1.305 filtert die Allowlist ihn nicht mehr heraus. Fehlte er dort, lädt er nach dem Upgrade.
- Um ihn auszuhalten, muss serverCommand in deniedMcpServers Befehl plus Argumente als Array sein, in derselben Reihenfolge.
- Eine leere Denylist hat eine gültige Form und blockiert nichts. serverName ist keine Sicherheitskontrolle.
Die Entscheidung: ein stdio-Server, der ${VAR} nur in env nutzt, wird nach 2.1.305 nicht mehr von der Allowlist gestoppt. Schreiben Sie in die Denylist ein serverCommand, das mit command und args identisch ist.
Welche Stelle der Allowlist ändert 2.1.305?
Das Changelog sagt: allowedMcpServers filtert stdio-Server in managed-mcp.json nicht mehr, die ${VAR} nur in env nutzen. Einer, den die Allowlist ausließ, lädt nach dem Upgrade. Um ihn auszuhalten, nutzen Sie deniedMcpServers. Das Changelog ist das Claude-Code-Changelog.
Der Organisationsleitfaden zu MCP nennt noch die ältere Regel: Server in managed-mcp.json überspringen die Allowlist, außer eine Definition mit ${VAR}, die weiter geprüft wird. Vor 2.1.259 musste jeder verwaltete Server eine gesetzte Allowlist bestehen. 2.1.305 nimmt eine schmale Scheibe heraus: stdio, und die Variable nur in env. Das Changelog sagt nicht, dass ein ${VAR} in Befehl, Argumenten, URL oder headers ebenfalls frei ist. Der Leitfaden ist der Organisationsleitfaden zu MCP.
Woran sehen Sie, dass die Variable nur in env steht?
Das stdio-Beispiel im Leitfaden hat type, command, args und env. Schreiben Sie kein Geheimnis in einen env-Wert. Zugangsdaten je Nutzer nutzen ${VAR} und werden aus der Umgebung dieses Nutzers gelesen. Die Datei unten lässt die Variable nur in env. Befehl und Argumente sind Literale. Das ist der Fall, den 2.1.305 nennt. Der Befehlspfad ist ein Platzhalter, kein Paket zum Installieren.
{
"mcpServers": {
"notes": {
"type": "stdio",
"command": "/usr/local/bin/notes-server",
"args": ["--stdio"],
"env": {
"NOTES_TOKEN": "${NOTES_TOKEN}"
}
}
}
}
Steht ${VAR} in command, args, der URL oder headers, nimmt das Changelog sie nicht in diese Ausnahme auf. Behandeln Sie diesen Server weiter als der Allowlist-Prüfung im Leitfaden unterliegend, bis das Changelog selbst etwas anderes sagt. Das Denylist-Beispiel hier deckt nur den env-Fall.
Welchen Befehl muss deniedMcpServers treffen?
Im Leitfaden trifft serverCommand den Befehl und die Argumente, die einen stdio-Server starten, und der Treffer muss exakt sein. Der command oben plus args ist dieses Array. Ein Argument weniger, eines mehr oder eine andere Reihenfolge trifft nicht. serverName ist nur ein Etikett. Der Leitfaden sagt, ein serverName-Eintrag in einer der beiden Listen sei keine Sicherheitskontrolle, weil ein Nutzer jedem Server denselben Namen geben kann.
{
"deniedMcpServers": [
{
"serverCommand": ["/usr/local/bin/notes-server", "--stdio"]
}
]
}
Die Denylist gilt auch für verwaltete Server, und die eigenen deniedMcpServers eines Nutzers fließen ein, sodass ein Nutzer einen verwalteten Server für sich blockieren kann. Ist die Allowlist ein leeres Array, sagt der Leitfaden, es seien keine Server erlaubt außer denen, die die Allowlist-Prüfung überspringen. Nach 2.1.305 ist dieser stdio-Server mit einer Variable nur in env einer, der überspringt, also hält ihn eine leere Allowlist nicht draußen.
Welches Schema legt die Form dieser Denylist fest?
Nutzen Sie JSON Schema , um die Typen festzulegen. deniedMcpServers muss ein Array sein. Jedes serverCommand muss ein Array aus Zeichenketten sein. Ein leeres Array ist eine gültige Form. Es beweist nicht, dass dieser Server stoppt. Was ihn stoppt, ist die App-Regel: das Array muss mit command plus args identisch sein.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["deniedMcpServers"],
"properties": {
"deniedMcpServers": {
"type": "array",
"items": {
"type": "object",
"required": ["serverCommand"],
"properties": {
"serverCommand": {
"type": "array",
"items": { "type": "string" }
}
}
}
}
}
}
| Was der Eintrag zeigt | Schema | Wenn dieser Server aus bleiben soll |
|---|---|---|
| serverCommand ist eine einzige Zeichenkette | Scheitert. Dieses Feld braucht ein Array aus Zeichenketten. | Teilen Sie es zuerst in Befehl und Argument. |
| Ein Argument ist eine Zahl | Scheitert. Jeder Eintrag im Array ist eine Zeichenkette. | Ändern Sie es in dieselbe Zeichenkette wie in args. |
| deniedMcpServers ist ein leeres Array, die Form stimmt | Besteht. Ein leeres Array ist ein Array. | Ergänzen Sie das serverCommand, das command und args trifft. Eine leere Liste blockiert nichts. |
Welcher der drei Schritte vor dem Laden stoppt ihn wirklich?
Der Leitfaden schreibt die Prüfungen vor dem Laden als drei Schritte und führt sie erneut aus, wenn ein Nutzer einen Server neu verbindet oder einen deaktivierten in /mcp wieder einschaltet. Prozessinterne Server vom Typ sdk überspringen alle drei. Nach einem Denylist-Treffer setzt nichts ihn außer Kraft.
| Schritt | Dieser Server nur mit env |
|---|---|
| Die Listen zusammenführen | Allowlist- und Denylist-Einträge aus jedem Einstellungsbereich werden zusammengeführt. Ist allowManagedMcpServersOnly true, bleibt nur die verwaltete Allowlist. Die Denylist fließt immer aus jedem Bereich zusammen. |
| Zuerst die Denylist prüfen | Ein exakter serverCommand-Treffer stoppt ihn. Danach kann die Allowlist ihn nicht zurückholen. |
| Dann die Allowlist prüfen | Nach 2.1.305 überspringt dieser stdio-Server mit einer Variable nur in env diesen Schritt. Ihn von der Allowlist wegzulassen stoppt ihn nicht mehr. |
Wie prüfen Sie diese Denylist in JSONNote?
- 1Die richtige Operation wählen
Öffnen Sie JSON Schema. Stellen Sie Betrieb auf Überprüfen Sie mit Schema. Denylist ins erste Feld, das Schema oben ins zweite. serverCommand muss ein Array aus Zeichenketten sein.
- 2Vier ungültige Dokumente prüfen
Setzen Sie serverCommand auf eine Zeichenkette, löschen Sie deniedMcpServers, setzen Sie ein Argument auf eine Zahl, oder machen Sie deniedMcpServers zu einem Objekt. Alle vier scheitern. Die Denylist oben besteht. Bestehen heißt nur richtige Form.
- 3Die leere Liste mit diesem Befehl vergleichen
Öffnen Sie JSON Vergleiche Diff. Die Denylist oben ins erste Feld. Im zweiten deniedMcpServers zu einem leeren Array ändern. Beide bestehen das Schema. Was diesen Server stoppt, ist dieses serverCommand, nicht das leere Array.
Häufige Fragen
Ersetzt derselbe Befehl auf der Allowlist die Denylist?
Nein. Nach 2.1.305 überspringt dieser Server die Allowlist. Ob der Befehl auf der Allowlist steht, entscheidet nicht mehr, ob er lädt. Zum Stoppen muss ein Denylist-Eintrag treffen. Nach einem Denylist-Treffer holt die Allowlist ihn nicht zurück.
Reicht ein serverName notes?
Nein. Der Leitfaden sagt, serverName sei das Etikett, das ein Nutzer vergibt, und Platzhalter werden nicht expandiert. Ein Nutzer kann jeden Server gleich benennen. Um diesen stdio-Server zu stoppen, nutzen Sie serverCommand, identisch mit command und args.
Lädt er auch, wenn der Befehl ${VAR} enthält?
Das Changelog nimmt diesen Fall nicht in die Ausnahme auf. Es nennt nur stdio und eine Variable nur in env. Steht ${VAR} auch in Befehl, Argumenten, URL oder headers, behandeln Sie ihn weiter als die Allowlist-Prüfung im Organisationsleitfaden. Trifft dieser Server die Allowlist nicht, nehmen Sie nicht an, dass 2.1.305 ihn lädt.
Können die eigenen Einstellungen eines Nutzers den von der Organisation verteilten Server blockieren?
Ja. Der Leitfaden sagt, deniedMcpServers gelte auch für Server in managed-mcp.json, und die eigene Denylist eines Nutzers fließt ein. Ein Nutzer kann einen Server für sich blockieren. Die Allowlist ersetzt diesen Schritt nicht.
Soll der env-Block den Token-Wert speichern?
Nein. Der Leitfaden sagt, jeder auf der Maschine könne managed-mcp.json lesen, also schreiben Sie keinen API-Key und keine anderen Zugangsdaten in env. Zugangsdaten je Nutzer nutzen ${VAR} und werden aus der Umgebung dieses Nutzers gelesen. Die Denylist enthält auch kein Token, nur Befehl und Argumente.
Fazit
2.1.305 nimmt nur einen Fall aus: einen stdio-Server in managed-mcp.json, dessen ${VAR} nur in env steht. Die Allowlist filtert ihn nicht mehr heraus. Das Changelog nimmt eine Variable in Befehl, Argumenten, URL oder headers nicht mit aus.
Die Entscheidung: um ihn auszuhalten, in deniedMcpServers ein serverCommand schreiben, das mit command und args identisch ist; eine leere Allowlist hält ihn nicht draußen; serverName reicht nicht; den Token-Wert nicht in env speichern.
Als Nächstes: das Denylist-Array mit dem Schema festlegen, dann mit Diff das leere Array gegen dieses serverCommand sehen.