netmiko-mcp
claude-project — netmiko MCP-Server + Skill
Ein fertig kopierbares Projekt, das einem KI-Agenten schreibgeschützten Zugriff auf Router, Switches und Firewalls über SSH ermöglicht, durch das Model Context Protocol.
Es enthält zwei Komponenten und die Verbindung zwischen ihnen:
mcps/mcp_server_netmiko.py— ein eigenständiger MCP-Server. Zehn Tools, jeder Befehl gegen eine vom Betreiber definierte Erlaubnis-/Verbotsliste validiert, Ausgabe mitntc-templatesin JSON geparst und eine ausfallsichere Prüfspur jedes Versuchs..claude/skills/netmiko/SKILL.md— das Skill, das dem Agenten beibringt, wann er diese Tools einsetzen soll, wie die plattformspezifischen CLI-Dialekte aussehen und wie man eine Ablehnung liest.
Hier wird nichts auf ein Gerät geschrieben. Die Erlaubnisliste ist standardmäßig verweigernd — eine leere Liste erlaubt nichts — und die Verbotsseite hat immer Vorrang vor der Erlaubnisseite.
Alles, was passiert, wird in einer Prüfspur festgehalten, und netmiko.query_audit_trail macht es im Gespräch abfragbar: "alles, was auf SW-CORE-01 gemacht wurde, nach Datum", "die letzten 6 Aktionen", "welche Befehle diese Woche verweigert wurden". Da dieses Projekt keine Benutzeroberfläche hat, ist dieses Tool der einzige Weg, sie zu lesen.
Autoren und Herkunft
Dieses Projekt stammt von Ed Scrimaglia — edgardo.scrimaglia@gmail.com, Octupus. Server, Skill, Konfigurationsmodell und Dokumentation sind seine Arbeit, geschrieben für den Niko-Agenten und hier als eigenständiges Projekt verpackt.
Es begann als Fork, und dieser Ursprung wird anerkannt, nicht versteckt: der Ausgangspunkt war die Arbeit von Kirk Byers, und das Projekt ist weit darüber hinausgewachsen. Was jetzt hier ist — das auf der Quelle der Wahrheit basierende Inventar, die Anmeldeinformationsauflösung, die drei Bereitstellungsvarianten, die Ausgabeseitierung, die Prüfspur, das Skill und diese Dokumentation — stammt nicht aus dem Upstream.
Die beiden Upstream-Projekte von Kirk Byers:
Netmiko — die Multi-Vendor-SSH-Bibliothek, die die eigentliche Kommunikation mit den Geräten übernimmt.
netmiko_mcp — der MCP-Server, von dem dieser abgezweigt wurde. Ein Teil davon ist weitgehend so erhalten geblieben, wie er war: der Sicherheitskern (Befehlsvalidierung, Glob-Handling, die Erlaubnis-/Verbotsasymmetrie), absichtlich als originalgetreuer Port beibehalten, damit Upstream-Patches immer noch eingespielt werden können. Das war eine technische Entscheidung, keine Einschränkung der übrigen Arbeit.
Related MCP server: Network MCP Server
Über Niko
Dieser Server wurde für Niko geschrieben, den Neural Intelligence Knowledge Orchestrator KI-Agenten, der von Ed Scrimaglia bei Octupus entwickelt wurde. Niko bedient eine Reihe von MCP-Servern — den Source-of-Truth-Server, diesen hier, Jira, E-Mails senden, Dateien erstellen und andere —, sodass ein Betreiber eine Frage in natürlicher Sprache stellen und aus der realen Umgebung beantwortet bekommen kann: die SoT für das, was wahr sein sollte, die Geräte selbst für das, was ist.
Innerhalb von Niko läuft dieselbe Datei etwas anders, und das ist wissenswert, weil es einiges im Code erklärt:
Server laufen über HTTP auf Loopback, ein Port pro Server, deklariert in
mcps/mcp_config.jsonmiturl/transport/local/env— dieselbe unten beschriebene Zwei-Achsen-Konfiguration, ausgedrückt in Nikos eigenem Format.Die Installation erfolgt über die App, nicht durch Kopieren von Dateien: der Upload wird validiert, die Abhängigkeiten werden aus dem Code selbst aufgelöst, und eine fehlgeschlagene Installation wird zurückgesetzt, anstatt einen halben Server zurückzulassen.
Jede dieser Integrationen ist ein optionaler Import mit einem Fallback, sodass niko nie installiert sein muss. Es gibt vier, und so verhalten sie sich, wenn der Import fehlschlägt:
Import | Zeile | Eigenständiger Fallback |
| 60 |
|
| 68 |
|
| 436 |
|
| 2709 | eine No-Op, die die Nutzlast unverändert zurückgibt |
Es geht nichts verloren, was außerhalb von Niko wichtig wäre: der nebenläufige Handler löst ein Mehrprozess-Eine-Datei-Problem, das hier nicht auftritt, und das Listenbudget kürzt lange Nutzlasten für einen Agenten, der seine eigene Kontextabrechnung hat. Eine Datei, zwei Zuhause, kein Fork.
Fedele ist Nikos Quelle der Wahrheit, weshalb die SoT-Variablen das FEDELE_-Präfix tragen, selbst wenn sie auf eine NetBox-Instanz verweisen.
Lizenz
Der eigene Code dieses Projekts ist MIT — siehe LICENSE.
Es ist eine abgeleitete Arbeit, daher gelten zwei Lizenzen und beide Dateien werden mitgeliefert:
Lizenz | Datei | |
Code, Dokumentation und Skill dieses Projekts | MIT | |
Aus | Apache-2.0 |
NOTICE enthält die Namensnennung und die Erklärung der Änderungen, die Apache-2.0 §4(b) verlangt. Netmiko ist eine gewöhnliche MIT-Abhängigkeit: importiert, nicht mitgeliefert, nichts zum Weiterverteilen.
Aufbau
claude-project/
├── .mcp.json # declares the server (project scope)
├── .env.example # → copy to .env with the SSH credentials
├── .claude/skills/netmiko/
│ └── SKILL.md # one directory per skill, file named SKILL.md
├── mcps/
│ └── mcp_server_netmiko.py # NOT at the root: the server reads ../.env
├── config/netmiko/
│ ├── commands.yml # allow/deny list — without it, a 16-command fallback applies
│ └── inventory.yml # inventory in netmiko_tools format
├── logs/ # netmiko-mcp.log + netmiko-audit.jsonl
├── mcpr/netmiko/ # created on demand (0700): large outputs
├── LICENSE LICENSE-APACHE-2.0 NOTICE
└── pyproject.tomlZwei nicht verhandelbare Regeln:
Das Skill lebt in
.claude/skills/<name>/SKILL.md. Claude Code liestskills/netmiko.mdnicht: es braucht das Verzeichnis und genau diesen Dateinamen.Der Server lebt in
mcps/, nicht im Stammverzeichnis.PARENT_DIRist das übergeordnete Verzeichnis des Ordners, der die.pyenthält (mcp_server_netmiko.py:62), und dorther kommt die.env. Wenn der Server im Stammverzeichnis wäre, würde die.enveine Ebene über dem Projekt gesucht.
In Betrieb nehmen
uv venv --python 3.12
uv pip install -r <(uv pip compile pyproject.toml) # or: uv sync
cp .env.example .env && $EDITOR .env # SSH credentials
# .mcp.json needs no editing: its paths are project-relative
claude # approve the project serverInnerhalb der Sitzung: /mcp listet die 10 Tools auf, /skills bestätigt, dass das Skill geladen wurde. Erste Überprüfung, ohne das Netzwerk zu berühren:
Welche Befehlspolicy setzt der netmiko MCP durch?
Die drei Varianten
Woher das Inventar kommt und woher die Anmeldeinformationen kommen, sind zwei unabhängige Achsen. Das macht aus einem Server drei Bereitstellungen — und der Grund, warum der Server nie geändert werden muss, um zwischen ihnen zu wechseln: zwei Umgebungsvariablen entscheiden.
Inventar | Anmeldeinformationen | Was Sie brauchen | Wann verwenden | |
A — SoT alles | Fedele | Fedele | API-Token + Fernet-Schlüssel | Die SoT ist maßgeblich und enthält bereits die Geräte-Anmeldeinformationen |
B — SoT-Inventar, lokale Anmeldeinformationen | Fedele oder NetBox |
| API-Token | Sie haben eine SoT, aber nicht deren Anmeldeinformations-Plugin. Der übliche Ausgangspunkt |
C — In sich geschlossen | lokales YAML |
| nichts Externes | Labor, abgeschottet, Demo oder Notlaufmodus, wenn die SoT ausfällt |
netmiko.get_metadata meldet, welche tatsächlich läuft — niemals aus der Konfigurationsdatei annehmen:
{
"inventory": {"backend": "fedele", "scope_filter": {"tag": "lab"}, "available": true},
"credential_source": "env",
"device_types_in_inventory": ["cisco_ios", "huawei_vrp", "…"]
}A — Fedele als Quelle der Wahrheit, inklusive Anmeldeinformationen
Der Agent fragt nach einem Gerät mit Namen; der Server löst Adresse, Plattform und Anmeldeinformationen zur Laufzeit gegen die SoT auf. Nichts über die Umgebung lebt in diesem Projekt: fügen Sie ein Gerät zur SoT hinzu, und es ist beim nächsten Aufruf erreichbar, ohne Datei bearbeiten und ohne Neustart.
// .mcp.json → env
"NETMIKO_MCP_INVENTORY_TYPE": "fedele",
"NETMIKO_MCP_CREDENTIAL_SOURCE": "fedele",
"NETMIKO_MCP_FEDELE_GROUP_SOURCE": "tags", // tags | device_roles | sites
"NETMIKO_MCP_FEDELE_DEVICE_FILTER": "tag=lab", // the scope filter — read the warning
"NETMIKO_MCP_FEDELE_CACHE_TTL": "60"# .env
FEDELE_URL=https://fedele.example.com
FEDELE_TOKEN=<API token>
FEDELE_CREDENTIALS_KEY=<Fernet key of the fedele_credentials plugin>Dateien: keine sind zwingend erforderlich. commands.yml wird empfohlen — ohne sie gilt die integrierte Fallback-Policy. Es ist kein lokales Inventar beteiligt und keine NETMIKO_USERNAME / NETMIKO_PASSWORD; bei credential_source=fedele wird NETMIKO_SECRET ignoriert — das Enable-Passwort kommt ebenfalls von der SoT.
Wie die Anmeldeinformationssuche funktioniert, drei Schritte:
GET dcim/devices/?name=<name> → device.id
GET plugins/credentials/devicecredentials/?device=<id> → credential id
GET plugins/credentials/networkcredentials/<id>/ → username + encrypted password
decrypted locally with the Fernet keyWissenswertes, bevor Sie diese Variante wählen:
Der Fernet-Schlüssel ist die gesamte Sicherheitsgrenze. Er entschlüsselt Gerätepasswörter im Speicher des Servers. Behandeln Sie ihn wie die Passwörter selbst.
Ohne
FEDELE_CREDENTIALS_KEYstartet der Server trotzdem, und jedes Tool gibt denselbenStartup Errorzurück, der die fehlende Variable nennt. Er scheitert lautstark, nicht leise.Setzen Sie den Bereichsfilter. Ohne
NETMIKO_MCP_FEDELE_DEVICE_FILTERist das Inventar die gesamte Umgebung, die die SoT kennt, was auch die gesamte Menge der Geräte ist, die der Agent erreichen kann. Der Server protokolliert eine Warnung, wenn er fehlt; der Filter akzeptiert Abfragesyntax,tag=lab&status=active.Ein Gerät ohne
primary_ip, ohneplatformoder dessen Plattform kein Netmikodevice_typeist, wird vom Inventar ausgeschlossen — SoTs inventarisieren auch Kameras, Badge-Leser und Gehäuse. Ausschlüsse werden gezählt und gemeldet, sodass der Agent nie behauptet "das sind alle Geräte" über einer Teilmenge.Es gibt einen Schutzschalter: nach einem Transportfehler oder einem 5xx hört der Client für 30 s auf, die SoT aufzurufen. Ein Gruppenbefehl gegen 40 Geräte bei ausgefallener SoT scheitert einmal, nicht vierzigmal.
B — SoT für das Inventar, Anmeldeinformationen in der .env
Identisch zu A mit einer umgedrehten Variable:
"NETMIKO_MCP_CREDENTIAL_SOURCE": "env",# .env
FEDELE_URL=https://sot.example.com
FEDELE_TOKEN=<API token>
NETMIKO_USERNAME=<service account>
NETMIKO_PASSWORD=<password>
NETMIKO_SECRET=<enable password, if any device asks for it>Sie erhalten das dynamische Inventar — der Teil, der sich selbst bezahlt macht — ohne das Anmeldeinformations-Plugin und ohne den Fernet-Schlüssel. Ein Dienstkonto wird für jedes Gerät verwendet.
NetBox oder jede NetBox-förmige SoT
Das Inventar-Backend spricht den NetBox-REST-Dialekt, daher funktioniert NetBox selbst in dieser Variante unverändert:
Was das Backend aufruft | Was es liest |
| die Geräteliste, gefiltert durch den Bereichsfilter und paginiert |
| welches auch immer |
| der SSH-Host, Maske entfernt |
| der Netmiko |
Zeigen Sie FEDELE_URL auf die NetBox-Instanz (/api wird angehängt, wenn Sie es weglassen) und FEDELE_TOKEN auf ein NetBox-API-Token — der Client authentifiziert sich mit dem Authorization: Token …-Header, den NetBox erwartet. Die Variablen behalten das FEDELE_-Präfix; das ist ein Benennungs-Erbe, keine Produktanforderung.
Die eine Anforderung, die NetBox standardmäßig nicht erfüllt: platform.name muss exakt ein Netmiko device_type sein — cisco_ios, arista_eos, huawei_vrp, juniper_junos. Eine Plattform namens "Cisco IOS 15.2" ist kein device_type, daher wird jedes Gerät, das sie trägt, vom Inventar ausgeschlossen. Benennen Sie entweder die Plattformen in NetBox um oder akzeptieren Sie die Ausschlüsse, die gemeldet werden.
Anmeldeinformationen sind der Teil, den NetBox nicht abdeckt: die plugins/credentials/…-Endpunkte gehören zu Fedeles Plugin. Mit einfachem NetBox ist Variante A nicht verfügbar — bleiben Sie bei B.
C — In sich geschlossen: gar keine SoT
Alles lebt in diesem Projekt. Es wird nie ein externer Dienst kontaktiert.
// .mcp.json → env
"NETMIKO_MCP_INVENTORY_TYPE": "yaml",
"NETMIKO_MCP_CREDENTIAL_SOURCE": "env",
"NETMIKO_MCP_INVENTORY_FILE": "/abs/path/claude-project/config/netmiko/inventory.yml"# .env
NETMIKO_USERNAME=<service account>
NETMIKO_PASSWORD=<password>
NETMIKO_SECRET=<enable password, if any device asks for it>Dateien: inventory.yml ist hier erforderlich – es ist der einzige Ort, an dem die Geräte existieren. commands.yml bleibt empfohlen, nicht erforderlich. Das Inventar hat das Format von netmiko_tools – eine flache Zuordnung von Name zu Verbindungsdaten, plus Gruppenschlüssel:
CORE-RTR-01:
device_type: cisco_xr # must be a Netmiko device_type, verbatim
host: 192.0.2.11
CORE-SW-01:
device_type: arista_eos
host: 192.0.2.21
core: # a group is a list of device names
- CORE-RTR-01
- CORE-SW-01Die mitgelieferte Datei dieses Projekts enthält Beispieldaten: 12 fiktive Geräte in den RFC-5737-Dokumentationsbereichen, 7 Gruppen und ausgewählte Plattformen, sodass jeder CLI-Dialekt, den die Zulassungsliste erwähnt, vertreten ist. Ersetzen Sie diese durch Ihre eigenen Bestände.
Dies ist die Geschmacksrichtung, mit der dieses Projekt ausgeliefert wird, und es ist auch der Degradierungsmodus: Wenn die SoT (Source of Truth) ausfällt, versetzen zwei Variablen und ein Neustart eine Bereitstellung der Geschmacksrichtung A oder B hierher. Es lohnt sich, dies zu üben, bevor Sie es brauchen.
Der Preis dafür ist, dass die Datei veraltet. scripts/export_inventory.py im übergeordneten Repository generiert sie aus der SoT neu; führen Sie es regelmäßig aus. Ein Backup-Inventar mit Adressen von vor sechs Monaten ist schlimmer als gar kein Backup, weil Sie es erst während des Betriebs merken.
Was in allen drei gleich bleibt
Die Befehlsrichtlinie, das Prüfprotokoll (Audit Trail), die Seitenausgabe und die Werkzeugoberfläche ändern sich nicht zwischen den Geschmacksrichtungen. Die agentenseitige Schnittstelle ist identisch, weshalb die Fähigkeit (Skill) keine variante pro Geschmacksrichtung benötigt.
commands.yml ist empfohlen, nicht erforderlich
Der Server läuft auch ohne sie. Wenn die Datei fehlt, verweigert er nicht alles und startet nicht mit einer Fehlermeldung: Eine eingebaute Fallback-Liste von 16 schreibgeschützten Befehlen übernimmt – show version, show ip interface brief, display version und deren Junos/VRP-Äquivalente. Das ist bewusst so gewählt. Eine leere Richtlinie würde jeden Befehl verweigern, während der Server sich selbst als gesund meldet, was für einen Operator so aussieht, als hätte „das Gerät verweigert" statt „niemand hat eine Richtlinie geschrieben". Der Fallback wird beim Start angekündigt, netmiko.get_command_policy meldet policy_source: "fallback", und jeder protokollierte Versuch trägt die Quelle.
Die Datei ist also eine Richtlinienentscheidung, kein Installationsschritt: Der Fallback ermöglicht es Ihnen, den Server beim ersten Versuch zu starten, und Sie schreiben commands.yml, wenn Sie die eigene Richtlinie des Bestands statt einer konservativen Voreinstellung wünschen. Was Sie nicht tun können, ist eine Richtlinie zu haben, die Sie nicht gewählt haben, ohne es zu wissen – der Server sagt jedes Mal, welche in Kraft ist, wenn er gefragt wird.
Die .mcp.json-Datei
.mcp.json im Projektstamm deklariert die MCP-Server für dieses Projekt.
Claude Code bittet um Zustimmung, wenn es die Datei zum ersten Mal sieht, und die Datei soll eingecheckt werden: So erhält das gesamte Team denselben Server.
Für dieselbe Serverdefinition gibt es zwei weitere Gültigkeitsbereiche:
Bereich | Speicherort | Wer sieht ihn |
|
| alle, die das Projekt öffnen (nach Zustimmung) |
|
| jedes Projekt dieses Benutzers, auf diesem Rechner |
|
| nur dieser Benutzer, nur in diesem Projekt |
claude mcp add --scope project netmiko -- /pfad/zu/python /pfad/zu/server.py
schreibt den project-Eintrag für Sie; das manuelle Bearbeiten der JSON ist gleichwertig.
Aufbau der Datei
{
"mcpServers": { // ← the top-level key. Not "servers", not "mcp".
"netmiko": { // ← the server name; it becomes the tool prefix
... // mcp__netmiko__<tool>
}
}
}Der Servername ist nicht nur kosmetisch: Claude Code stellt jedes Werkzeug als
mcp__<server-name>__<tool-name> bereit. Mit dem Namen netmiko und dem Werkzeug
netmiko.get_metadata, das der Server registriert, heißt das Werkzeug, das Claude tatsächlich sieht,
mcp__netmiko__netmiko.get_metadata. Führen Sie /mcp aus, um die genauen Namen zu lesen,
bevor Sie sie in eine allowed-tools-Liste oder eine Berechtigungsregel eintragen.
Feldreferenz
Feld | Transport | Bedeutung |
| beide |
|
| stdio | Das auszuführende Programm. Absoluter Pfad – kein Arbeitsverzeichnis voraussetzen |
| stdio | Argumentliste, jedes Element getrennt |
| stdio | Umgebung für den Kindprozess. Wird über die geerbte Umgebung gelegt |
| http / sse | Vollständige Endpunkt-URL, inklusive Pfad |
| http / sse | Zusätzliche Anforderungsheader, typischerweise |
Werte unterstützen Umgebungserweiterung: ${VAR} und ${VAR:-default}. Nützlich, um
einen Token aus der eingecheckten Datei herauszuhalten:
"headers": { "Authorization": "Bearer ${NETMIKO_MCP_TOKEN}" }Transport 1 – stdio (der in diesem Projekt verwendete)
Claude Code startet den Server als Kindprozess und kommuniziert über seine stdin/stdout per JSON-RPC. Es lauscht nichts auf einem Port, nichts ist aus dem Netzwerk erreichbar, und die Prozesslebensdauer entspricht der Sitzung. Dies ist die richtige Voreinstellung für einen Server, der SSH-Anmeldeinformationen speichert.
{
"mcpServers": {
"netmiko": {
"type": "stdio",
"command": "${CLAUDE_PROJECT_DIR:-.}/.venv/bin/python",
"args": ["${CLAUDE_PROJECT_DIR:-.}/mcps/mcp_server_netmiko.py"],
"env": {
"NETMIKO_MCP_INVENTORY_TYPE": "yaml",
"NETMIKO_MCP_INVENTORY_FILE": "${CLAUDE_PROJECT_DIR:-.}/config/netmiko/inventory.yml",
"NETMIKO_MCP_COMMAND_FILE": "${CLAUDE_PROJECT_DIR:-.}/config/netmiko/commands.yml",
"NETMIKO_MCP_CREDENTIAL_SOURCE": "env",
"NETMIKO_MCP_SAVE_OUTPUT_DIR": "${CLAUDE_PROJECT_DIR:-.}/mcpr/netmiko",
"NETMIKO_MCP_AUDIT_LOG_FILE": "${CLAUDE_PROJECT_DIR:-.}/logs/netmiko-audit.jsonl",
"LOG_FILE": "${CLAUDE_PROJECT_DIR:-.}/logs/netmiko-mcp.log",
"LOG_LEVEL": "INFO"
}
}
}
}Zwei Dinge, die Probleme bereiten:
Keine hartcodierten Pfade, und das Arbeitsverzeichnis ist nicht verlässlich.
${CLAUDE_PROJECT_DIR:-.}sorgt dafür, dass die Datei wie besehen eingecheckt werden kann; der nächste Abschnitt erzählt die ganze Geschichte, denn die offensichtliche Lesart ist falsch.Der Server darf nicht auf stdout schreiben. stdout ist der Protokollkanal, und eine einzige falsche Zeile dort unterbricht die Sitzung. Protokollierung erfolgt auf stderr plus die rotierende Datei unter
LOG_FILE(5 MB × 3, erstellt mit0600– beiDEBUGenthält diese Datei die Geräteausgabe). Innerhalb von Niko wird dieselbe Variable vonMCPLoggingbehandelt.
Woher ${CLAUDE_PROJECT_DIR:-.} kommt
Zwei verschiedene Dinge in einer Zeichenkette: eine Syntax und eine Variable.
Die Syntax. ${VAR} und ${VAR:-default} ist die POSIX-Parametersubstitution
("verwende VAR; wenn es nicht gesetzt oder leer ist, verwende default"), aber es ist keine Shell beteiligt
– eine JSON-Datei durchläuft nie eine. Claude Code implementiert die Erweiterung
selbst, wenn es die Datei liest, in command, args, env, url und headers.
Es ist eine Konvention dieses Clients, nicht Teil der MCP-Spezifikation: Ein anderer
Client implementiert sie möglicherweise nicht (siehe Nicht-Claude-Agenten, wo
die Pfade dann literal sein müssen), und VS Code hat seine eigene Schreibweise,
${workspaceFolder}.
Die Variable. CLAUDE_PROJECT_DIR wird von Claude Code auf das Projektstammverzeichnis
gesetzt, denselben Wert, den Hooks erhalten. Sie ist stabil – das Gewähren zusätzlicher Arbeitsverzeichnisse
während einer Sitzung mit --add-dir verschiebt sie nicht.
Der Teil, der kontraintuitiv ist, und der Grund, warum :-. nicht nur Dekoration ist:
Claude Code setzt diese Variable in der Umgebung des gestarteten Servers, nicht in seiner eigenen.
Die Erweiterung erfolgt jedoch vor dem Start, in der Umgebung von Claude Code –
wo die Variable nicht existiert. Ein bloßes ${CLAUDE_PROJECT_DIR} würde daher zu nichts expandieren
und /config/netmiko/inventory.yml hinterlassen, einen absoluten Pfad zum Wurzelverzeichnis des Dateisystems.
In einer projektspezifischen .mcp.json ist der Standardwert also kein Fallback für einen
Randfall: es ist der Wert, der jedes Mal verwendet wird. Was im Prozess ankommt, ist
./config/netmiko/inventory.yml. Die einzige Ausnahme ist eine MCP-Konfiguration, die von einem
Plugin bereitgestellt wird – dort ersetzt Claude Code die Variable direkt und es wird kein Standard benötigt.
Das zwingt dem Server die Hand auf. Ein relativer Wert würde gegen das Arbeitsverzeichnis des
Kindprozesses aufgelöst, und das Arbeitsverzeichnis ist die Wahl des Clients, nicht des Projekts.
Daher resolve_project_path(): Jede relative Pfadeinstellung wird an PARENT_DIR verankert – dem
Elternverzeichnis von mcps/, derselben Wurzel, von der auch .env stammt – wenn die Einstellungen geladen werden.
Eine Sitzung, die von irgendwo gestartet wird, findet config/netmiko/, und validate_startup() benennt
die absolute Datei, wenn eine fehlt. Ein ~ bedeutet immer das Home-Verzeichnis des Operators, niemals eine Datei innerhalb des Projekts.
Die Variable ist dennoch nützlich, wie in der Dokumentation vorgesehen, wenn sie innerhalb des Servers gelesen wird (os.environ["CLAUDE_PROJECT_DIR"]), wo sie gesetzt ist. Dieser Server benötigt sie nicht: PARENT_DIR leitet sich von __file__ ab und hängt daher von keinem Client ab – derselbe Grund, warum der HTTP-Transport, bei dem niemand diese Variable setzt, keinen Sonderfall benötigt.
Quelle: Claude Code – MCP, Abschnitte Add a local stdio server und Environment variable expansion in .mcp.json.
Transport 2 – HTTP (streamable HTTP)
Claude Code unterstützt ihn, ebenso wie jeder andere MCP-Client. Es ist der Transport, der verwendet werden soll, wenn der Server woanders läuft: einem anderen Host, einem Container, einem Dienst, der von mehreren Agenten gemeinsam genutzt wird, oder einem Agenten, der nicht Claude ist.
Die Serverdatei ruft immer mcp.run(transport="stdio") unter ihrer __main__-Schutzbedingung auf, sodass HTTP stattdessen über die FastMCP-CLI bedient wird – keine Codeänderung:
.venv/bin/fastmcp run mcps/mcp_server_netmiko.py \
--transport http --host 127.0.0.1 --port 8123
# endpoint: http://127.0.0.1:8123/mcp/Die NETMIKO_MCP_*-Variablen sind nicht mehr Teil der Client-Konfiguration: Der Serverprozess wird von Ihnen gestartet, daher gehören sie zu seiner Umgebung (ein Shell-Export, eine systemd-Unit, ein environment:-Block eines Containers).
Clientseite:
{
"mcpServers": {
"netmiko": {
"type": "http",
"url": "http://127.0.0.1:8123/mcp/",
"headers": {
"Authorization": "Bearer ${NETMIKO_MCP_TOKEN}"
}
}
}
}Oder äquivalent: claude mcp add --transport http netmiko http://127.0.0.1:8123/mcp/.
--transport sse und "type": "sse" funktionieren ebenfalls; SSE ist der ältere entfernte Transport und wird für Clients beibehalten, die noch nicht auf streamable HTTP umgestiegen sind.
Sicherheit. Die FastMCP-CLI stellt dies ohne Authentifizierung bereit: Jeder, der den Port erreicht, kann show-Befehle gegen jedes Gerät im Inventar ausführen, unter Verwendung der Anmeldeinformationen in der Serverumgebung. Binden Sie für einen lokalen Test an
127.0.0.1, und stellen Sie es für alles gemeinsam Genutzte hinter einen Reverse Proxy, der TLS terminiert und denAuthorization-Header überprüft. Derheaders-Block oben ist das, was der Client sendet; der Proxy muss es überprüfen.
Nicht-Claude-Agenten
Das hier gezeigte mcpServers-Objekt ist die De-facto-Form: Claude Code, Claude Desktop, Cursor und Windsurf lesen alle dieselben drei Felder für stdio (command / args / env) und dieselben zwei für entfernte Verbindungen (url / headers). Das Kopieren eines Eintrags zwischen ihnen funktioniert normalerweise ohne Änderungen.
Bekannte Unterschiede, die es wert sind, vor dem Kopieren überprüft zu werden:
VS Code verwendet
mcp.jsonmit einem Schlüssel"servers"auf oberster Ebene statt"mcpServers", und es verlangt, dass"type"explizit angegeben wird.Einige Clients implementieren keine
${VAR}-Erweiterung; dort muss der Wert literal sein, was ein Argument für den HTTP-Transport plus einen Proxy ist, anstatt einen Token in eine eingecheckte Datei einzufügen.Ein Agent ohne Konfigurationsdatei kann dennoch direkt mit dem HTTP-Endpunkt sprechen – die URL und der
Authorization-Header sind der gesamte Vertrag.
Der env-Block
Die NETMIKO_MCP_*-Einträge gewinnen gegenüber jeder YAML-Konfigurationsdatei. Sie werden explizit gesetzt, weil es außerhalb von Niko keine NikoPaths gibt, sodass die Standardwerte auf ~/commands.yml und ~/.netmiko_mcp_tmp zurückfallen.
Jeder Pfad hier kann relativ zum Projektstamm angegeben werden: Der Server verankert relative Werte beim Laden der Einstellungen in PARENT_DIR, sodass das Arbeitsverzeichnis des gestarteten Prozesses nie entscheidet, wo das Inventar oder das Prüfprotokoll liegt. Ein absoluter Pfad oder ein ~ wird so übernommen, wie er geschrieben ist.
Variable | Default | Zweck |
|
|
|
| (Netmiko-Tools-Suche) | Inventarpfad, wenn der Typ |
|
|
|
|
| Was eine Gruppe definiert: |
| (keine) | Bereichsfilter, |
|
| SoT-Auflösungs-Cache, in Sekunden |
|
| Erlaubnis-/Verbotsliste |
|
| Aktiviert Pipes in Befehlen |
| (keine) | OpenSSH |
|
| Gleichzeitige Verbindungen bei Gruppenbefehlen |
|
| Puffer für große Ausgaben |
|
| Zeilenanzahl, ab der die Ausgabe gespeichert statt inline zurückgegeben wird |
| (siehe übergeordnete README) | Prüfpfad (JSON, Fail-Closed). Bitten Sie den Agenten, ihn mit |
|
| Pfad zu einer YAML-Konfigurationsdatei, die dieselben Einstellungen enthält |
|
| Betriebsprotokoll: stderr immer, plus diese rotierende Datei (5 MB × 3, |
Anmeldedaten werden hier nicht gesetzt. NETMIKO_USERNAME, NETMIKO_PASSWORD,
NETMIKO_SECRET und die FEDELE_*-Variablen werden aus
<Projektstamm>/.env gelesen, sodass sie niemals in einer committeten JSON-Datei landen.
Rangfolge: Was im env-Block steht, gewinnt stillschweigend gegenüber der .env – definieren Sie
jede Variable genau an einer Stelle.
Jede andere Variable ist in der README des übergeordneten Repositorys dokumentiert.
Überprüfen, ob es funktioniert
claude mcp list # netmiko: ✓ connectedInnerhalb der Sitzung listet /mcp die Tools auf und /skills bestätigt, dass die Fähigkeit
geladen wurde. Fragen Sie, welche Richtlinie in Kraft ist, und netmiko.get_command_policy gibt den Namen der Datei an, die gelesen wird – oder meldet "fallback", was bedeutet, dass die Datei nie gefunden wurde und die 16 integrierten Befehle ausgeführt werden.
Autor: Ed Scrimaglia edgardo.scrimaglia@gmail.com – letzte Aktualisierung: 18.08.2026.
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 gradedqualityDmaintenanceProvides AI assistants with direct access to multi-vendor network devices for tasks like configuration management, health checks, and topology discovery through 35 specialized tools. It enables natural language control over platforms including Cisco, Juniper, and Nokia using SSH, NETCONF, and SNMP protocols.11MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to interact with Cisco IOS-XE network devices over SSH using structured tools. Provides read and write capabilities for network management with built-in validation and security.
- AlicenseNot gradedqualityDmaintenanceEnables read-only querying and diagnostics of Fortigate firewalls via SSH, providing security analysis, traffic monitoring, and configuration inspection through natural language.MIT
- AlicenseAqualityCmaintenanceBridges AI agents with network infrastructure, enabling secure read-only access to multiple vendor routers via SSH for natural language queries and troubleshooting.581MIT
Related MCP Connectors
Let AI operate servers without SSH. Choose actions, approve risky changes, and audit every step.
Read-only CVE intelligence, remediation playbooks, and agent setup guides. Not a scanner.
Read-only bank access for your AI agent. Connects Claude, ChatGPT, Cursor, Gemini, Codex.
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/escrimaglia/netmiko-sot_mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server