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, über das Model Context Protocol.
Es liefert zwei Komponenten und die Verbindung zwischen ihnen:
mcps/mcp_server_netmiko.py— ein eigenständiger MCP-Server. Neun Tools, jeder Befehl gegen eine vom Operator definierte Erlaubnis-/Verbotsliste validiert, die Ausgabe mitntc-templatesin JSON geparst und ein fehlschließender Prüfpfad für jeden Versuch..claude/skills/netmiko/SKILL.md— die Skill, die dem Agenten beibringt, wann er diese Tools einsetzen soll, wie die plattformspezifischen CLI-Dialekte aussehen und wie man eine Verweigerung liest.
Nichts hier schreibt auf ein Gerät. Die Erlaubnisliste ist standardmäßig verweigernd — eine leere erlaubt nichts — und die Verbotsseite gewinnt immer über die Erlaubnisseite.
Autoren und Herkunft
Dieses Projekt wurde von Ed Scrimaglia erstellt — 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 einer Quelle der Wahrheit basierende Inventar, die Auflösung von Anmeldeinformationen, die drei Bereitstellungsvarianten, die Ausgabenseitennummerierung, der Prüfpfad, die 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 abgespalten wurde. Ein Teil davon ist weitgehend so erhalten geblieben, wie er war: der Sicherheitskern (Befehlsvalidierung, Glob-Handhabung, 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.
Ü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-Mail-Versand, Dateierstellung und andere —, sodass ein Operator eine Frage in natürlicher Sprache stellen kann und die Antwort aus der realen Umgebung erhält: 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 einige Dinge 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 dies ist, wozu jede herabgestuft wird, wenn der Import fehlschlägt:
Import | Zeile | Eigenständiger Fallback |
| 60 |
|
| 68 |
|
| 436 |
|
| 2709 | ein No-Op, das 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 Mehrere-Prozesse-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 eingebunden, 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:
Die Skill lebt in
.claude/skills/<name>/SKILL.md. Claude Code liestskills/netmiko.mdnicht: Es braucht das Verzeichnis und diesen genauen 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.
Inbetriebnahme
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 9 Tools auf, /skills bestätigt, dass die 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 modifiziert 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-Key | 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, eine Demo oder herabgestufter Modus, wenn die SoT ausfällt |
netmiko.get_metadata meldet, welche tatsächlich läuft — niemals aus der Konfigurationsdatei ableiten:
{
"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, einschließlich Anmeldeinformationen
Der Agent fragt nach einem Gerät mit Namen; der Server löst Adresse, Plattform und Anmeldeinformationen zum Zeitpunkt des Aufrufs 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 dass eine Datei bearbeitet oder ein Neustart erforderlich ist.
// .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 es gibt keine NETMIKO_USERNAME / NETMIKO_PASSWORD; bei credential_source=fedele wird NETMIKO_SECRET ignoriert — das Enable-Passwort kommt ebenfalls von der SoT.
So funktioniert die Suche nach Anmeldeinformationen, 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-Key ist die gesamte Sicherheitsgrenze. Er entschlüsselt Gerätepasswörter im Arbeitsspeicher 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 still.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 ausgeschlossen vom Inventar — SoTs inventarisieren auch Kameras, Badge-Leser und Chassis. Ausschlüsse werden gezählt und gemeldet, sodass der Agent nie behauptet "das sind alle Geräte" über eine Teilmenge.Es gibt einen Schutzschalter: Nach einem Transportfehler oder einem 5xx-Fehler ruft der Client die SoT 30 s lang nicht mehr auf. Ein Gruppenbefehl gegen 40 Geräte mit ausgefallener SoT schlägt einmal fehl, 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 auszahlt — ohne das Anmeldeinformations-Plugin und ohne den Fernet-Key. 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, aus dem 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: 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 ist das netmiko_tools-Format — 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 Datei, die dieses Projekt ausliefert, enthält Beispieldaten: 12 fiktive Geräte in den RFC 5737-Dokumentationsbereichen, 7 Gruppen und Plattformen, die so ausgewählt wurden, dass jeder in der Zulassungsliste erwähnte CLI-Dialekt vertreten ist. Ersetzen Sie sie durch Ihre eigene Umgebung.
Dies ist die Konfiguration, die dieses Projekt standardmäßig ausliefert, und es ist auch der Degraded Mode: Wenn die SoT ausfällt, verschieben zwei Variablen und ein Neustart ein Flavor-A- oder Flavor-B-Deployment hierher. Es lohnt sich, das zu üben, bevor man es braucht.
Der Preis dafür ist, dass die Datei veraltet. scripts/export_inventory.py im übergeordneten Repository regeneriert sie aus der SoT; führen Sie es regelmäßig aus. Ein Backup-Inventar mit Adressen von vor sechs Monaten ist schlimmer als gar kein Backup, weil man es erst während des Betriebs merkt.
Was in allen drei gleich bleibt
Die Befehlspolicy, der Audit-Trail, das Output-Paging und die Tool-Oberfläche ändern sich nicht zwischen den Flavors. Der agentenseitige Vertrag ist identisch, weshalb die Fähigkeit keine variantenspezifische Anpassung benötigt.
commands.yml ist empfohlen, nicht erforderlich
Der Server läuft auch ohne sie. Wenn die Datei fehlt, verweigert er nicht alles und weigert sich nicht zu starten: Ein eingebauter Fallback von 16 schreibgeschützten Befehlen übernimmt — show version, show ip interface brief, display version und ihre Junos/VRP-Äquivalente. Das ist beabsichtigt. Eine leere Policy würde jeden Befehl verweigern, während der Server sich selbst als gesund meldet, was für einen Operator wie "das Gerät hat verweigert" aussieht, nicht wie "niemand hat eine Policy geschrieben". Der Fallback wird beim Start angekündigt, netmiko.get_command_policy meldet policy_source: "fallback", und jeder geprüfte Versuch trägt die Quelle.
Die Datei ist also eine Policy-Entscheidung, kein Installationsschritt: Der Fallback lässt Sie den Server beim ersten Versuch ausführen, und Sie schreiben commands.yml, wenn Sie die eigene Policy der Umgebung anstelle einer konservativen Vorgabe möchten. Was Sie nicht tun können, ist eine Policy zu haben, die Sie nicht gewählt haben, und es nicht zu wissen — der Server sagt jedes Mal, welche in Kraft ist, wenn er gefragt wird.
Die .mcp.json-Datei
.mcp.json im Projektstammverzeichnis deklariert die MCP-Server für dieses Projekt. Claude Code fragt nach Zustimmung, wenn es die Datei zum ersten Mal sieht, und die Datei soll eingecheckt werden: So erhält das gesamte Team denselben Server.
Zwei andere Bereiche existieren für dieselbe Serverdefinition:
Bereich | Wo es lebt | Wer es sieht |
|
| jeder, der das Projekt öffnet (nach Zustimmung) |
|
| jedes Projekt dieses Benutzers, auf diesem Rechner |
|
| nur dieser Benutzer, nur in diesem Projekt |
claude mcp add --scope project netmiko -- /path/to/python /path/to/server.py schreibt den project-Eintrag für Sie; das manuelle Bearbeiten der JSON ist gleichwertig.
Form 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 kosmetisch: Claude Code stellt jedes Tool als mcp__<server-name>__<tool-name> dar. Mit dem Namen netmiko und dem Tool netmiko.get_metadata, das der Server registriert, ist das Tool, 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 schreiben.
Feldreferenz
Feld | Transport | Bedeutung |
| beide |
|
| stdio | die auszuführende ausführbare Datei. Absoluter Pfad — kein cwd annehmen |
| stdio | Argumentliste, jedes Element getrennt |
| stdio | Umgebung für den Kindprozess. Über die geerbte Umgebung gelegt |
| http / sse | vollständige Endpunkt-URL, einschließlich Pfad |
| http / sse | zusätzliche Anfrage-Header, typischerweise |
Werte unterstützen Umgebungserweiterung: ${VAR} und ${VAR:-default}. Nützlich, um ein Token aus der eingecheckten Datei herauszuhalten:
"headers": { "Authorization": "Bearer ${NETMIKO_MCP_TOKEN}" }Transport 1 — stdio (der von diesem Projekt verwendete)
Claude Code startet den Server als Kindprozess und kommuniziert über JSON-RPC über dessen stdin/stdout. Es lauscht nichts auf einem Port, nichts ist aus dem Netzwerk erreichbar, und die Prozesslebensdauer ist die der Sitzung. Dies ist die richtige Voreinstellung für einen Server, der SSH-Anmeldedaten enthält.
{
"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 beißen:
Keine hartcodierten Pfade, und das Arbeitsverzeichnis ist nicht verlässlich.
${CLAUDE_PROJECT_DIR:-.}ist das, was die Datei so committbar hält; der nächste Abschnitt erzählt die ganze Geschichte, weil die offensichtliche Lesart falsch ist.Der Server darf nicht auf stdout schreiben. stdout ist der Protokollkanal, und eine einzelne fehlgeleitete Zeile dort unterbricht die Sitzung. Logging erfolgt auf stderr plus die rotierende Datei unter
LOG_FILE(5 MB × 3, erstellt0600— beiDEBUGenthält diese Datei Geräteausgaben). Innerhalb von Niko wird dieselbe Variable stattdessen vonMCPLoggingbehandelt.
Woher ${CLAUDE_PROJECT_DIR:-.} kommt
Zwei separate Dinge in einem String: 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 :-. keine Dekoration ist: Claude Code setzt diese Variable in der Umgebung des Servers, den es startet, nicht in seiner eigenen. Die Erweiterung erfolgt jedoch vor dem Start, gegen die Umgebung von Claude Code — wo die Variable nicht existiert. Ein bloßes ${CLAUDE_PROJECT_DIR} würde sich daher zu nichts erweitern 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 den Prozess erreicht, ist ./config/netmiko/inventory.yml. Die eine Ausnahme ist eine MCP-Konfiguration, die von einem Plugin mitgeliefert wird — dort setzt Claude Code die Variable direkt ein und es wird kein Standardwert benötigt.
Das zwingt den Server in die Knie. Ein relativer Wert würde gegen das cwd des Kindprozesses aufgelöst, und das cwd ist die Wahl des Clients, nicht des Projekts. Daher resolve_project_path(): Jede relative Pfadeinstellung wird beim Laden der Einstellungen an PARENT_DIR verankert — das übergeordnete Verzeichnis von mcps/, dieselbe Wurzel, von der die .env kommt. Eine von überall gestartete Sitzung findet config/netmiko/, und validate_startup() nennt die absolute Datei, wenn eine fehlt. Ein ~ bedeutet immer das Home-Verzeichnis des Operators, niemals eine Datei innerhalb des Projekts.
Die Variable ist immer noch nützlich, wie die Dokumentation es vorsieht, wenn sie von 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, wo 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 es, und jeder andere MCP-Client auch. Es ist der Transport, der verwendet werden sollte, wenn der Server woanders läuft: ein anderer Host, ein Container, ein von mehreren Agenten gemeinsam genutzter Dienst oder ein Agent, der nicht Claude ist.
Die Serverdatei ruft immer mcp.run(transport="stdio") unter ihrem __main__-Guard auf, daher wird HTTP stattdessen von der FastMCP-CLI bereitgestellt — 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 Remote-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 Anmeldedaten in der Serverumgebung. Binden Sie für einen lokalen Test an
127.0.0.1, und für alles, was geteilt wird, setzen Sie es hinter einen Reverse-Proxy, der TLS beendet und denAuthorization-Header prü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 Remote (url / headers). Das Kopieren eines Eintrags zwischen ihnen funktioniert normalerweise unverändert.
Bekannte Unterschiede, die es wert sind, vor dem Kopieren überprüft zu werden:
VS Code verwendet
mcp.jsonmit einem"servers"-Schlüssel auf oberster Ebene anstelle von"mcpServers"und erwartet, 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 ein Token in eine eingecheckte Datei einzufügen.Ein Agent ohne Konfigurationsdatei kann trotzdem direkt mit dem HTTP-Endpunkt sprechen — die URL und der
Authorization-Header sind der gesamte Vertrag.
Der env-Block
Die NETMIKO_MCP_*-Einträge haben Vorrang vor jeder YAML-Konfigurationsdatei. Sie werden explizit gesetzt, weil es außerhalb von Niko kein NikoPaths gibt, sodass die Standardwerte auf ~/commands.yml und ~/.netmiko_mcp_tmp zurückfallen.
Jeder Pfad hier kann relativ zum Projektstammverzeichnis angegeben werden: Der Server verankert relative Werte beim Laden der Einstellungen an PARENT_DIR, sodass das cwd des gestarteten Prozesses niemals entscheidet, wo das Inventar oder der Audit-Trail liegt. Ein absoluter Pfad oder ein ~ wird wie geschrieben übernommen.
Variable | Standard | Zweck |
|
|
|
| (netmiko-tools-Suche) | Inventarpfad, wenn der Typ |
|
|
|
|
| Was eine Gruppe definiert: |
| (keiner) | Bereichsfilter, |
|
| SoT-Auflösungs-Cache, in Sekunden |
|
| Erlaubnis-/Verbotsliste |
|
| Aktiviert Pipes in Befehlen |
| (keiner) | 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) |
|
| Pfad zu einer YAML-Konfigurationsdatei mit denselben Einstellungen |
|
| Betriebsprotokoll: stderr immer, plus diese rotierende Datei (5 MB × 3, |
Anmeldeinformationen werden nicht hier gesetzt. NETMIKO_USERNAME, NETMIKO_PASSWORD,
NETMIKO_SECRET und die FEDELE_*-Variablen werden aus
<project-root>/.env gelesen, sodass sie nie in einer committeten JSON-Datei landen.
Priorität: Was im env-Block steht, gewinnt gegenüber der .env, stillschweigend – 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 das Skill geladen wurde.
Fragen Sie, welche Richtlinie in Kraft ist, und netmiko.get_command_policy nennt die Datei, die es liest –
oder meldet "fallback", was bedeutet, dass es die Datei nie gefunden hat und mit den 16 integrierten Befehlen läuft.
Autor: Ed Scrimaglia edgardo.scrimaglia@gmail.com — zuletzt aktualisiert: 2026-08-18.
This server cannot be installed
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 Connectors
Let AI operate servers without SSH. Choose actions, approve risky changes, and audit every step.
Read-only bank access for your AI agent. Connects Claude, ChatGPT, Cursor, Gemini, Codex.
Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.
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-mcp-claude'
If you have feedback or need assistance with the MCP directory API, please join our Discord server