Skip to main content
Glama

claude-project — netmiko MCP server + skill

Un proyecto listo para copiar que otorga a un agente de IA acceso de solo lectura a routers, switches y cortafuegos a través de SSH, mediante el Model Context Protocol.

Incluye dos piezas y el cableado entre ellas:

  • mcps/mcp_server_netmiko.py — un servidor MCP autocontenido. Diez herramientas, cada comando validado frente a una lista de permitidos/denegados definida por el operador, salida analizada en JSON con ntc-templates, y un registro de auditoría de cierre por fallo de cada intento.

  • .claude/skills/netmiko/SKILL.md — la habilidad que enseña al agente cuándo usar esas herramientas, cómo son los dialectos de CLI por plataforma y cómo leer una denegación.

Nada de esto escribe en un dispositivo. La lista de permitidos es denegación por defecto: una vacía no permite nada, y el lado de denegación siempre prevalece sobre el de permitidos.

Todo lo que sucede se registra en un registro de auditoría, y netmiko.query_audit_trail permite responderlo en la conversación: "todo lo hecho en SW-CORE-01, por fecha", "las últimas 6 acciones", "qué comandos fueron denegados esta semana". Sin interfaz de usuario en este proyecto, esa herramienta es la única forma de leerlo.

Autores y procedencia

Este proyecto está escrito por Ed Scrimagliaedgardo.scrimaglia@gmail.com, Octupus. El servidor, la habilidad, el modelo de configuración y la documentación son obra suya, escritos para el agente Niko y empaquetados aquí como proyecto independiente.

Comenzó como una bifurcación, y ese origen se reconoce en lugar de ocultarse: el punto de partida fue el trabajo de Kirk Byers, y el proyecto creció mucho más allá. Lo que está aquí ahora — el inventario respaldado por la fuente de verdad, la resolución de credenciales, las tres variantes de despliegue, la paginación de salida, el registro de auditoría, la habilidad y esta documentación — no proviene del repositorio original.

Los dos proyectos originales de Kirk Byers:

  • Netmiko — la librería SSH multiventor que hace la comunicación real con los dispositivos.

  • netmiko_mcp — el servidor MCP del que se bifurcó este. Una parte sobrevive en gran medida como estaba: el núcleo de seguridad (validación de comandos, manejo de globs, la asimetría permitidos/denegados), mantenido como un puerto fiel a propósito para que los parches del repositorio original aún puedan ser diferenciados. Esa fue una decisión de ingeniería, no un límite para el resto del trabajo.

Related MCP server: Network MCP Server

Acerca de Niko

Este servidor fue escrito para Niko, el agente de IA Neural Intelligence Knowledge Orchestrator creado por Ed Scrimaglia en Octupus. Niko maneja un conjunto de servidores MCP — el servidor de fuente de verdad, este, Jira, envío de correos, creación de archivos y otros — para que un operador pueda hacer una pregunta en lenguaje natural y obtener respuesta desde el terreno: la SoT para lo que debería ser cierto, los propios dispositivos para lo que es.

Dentro de Niko, el mismo archivo se ejecuta de forma ligeramente diferente, y vale la pena saberlo porque explica algunas cosas en el código:

  • Los servidores se ejecutan sobre HTTP en loopback, un puerto cada uno, declarados en mcps/mcp_config.json con url / transport / local / env — la misma configuración de dos ejes descrita abajo, expresada en el formato propio de Niko.

  • La instalación se realiza a través de la aplicación, no copiando archivos: la carga se valida, las dependencias se resuelven desde el propio código, y una instalación fallida se revierte en lugar de dejar medio servidor atrás.

Cada una de esas integraciones es una importación opcional con un fallback, por lo que niko nunca tiene que estar instalado. Hay cuatro, y esto es lo que cada una degrada cuando falla la importación:

Importación

Línea

Fallback independiente

niko.srvclass_logging.MCPLogging

60

NIKO_AVAILABLE = False; el servidor configura su propio logging

niko.niko_paths.NikoPaths

68

None; las rutas provienen de las variables NETMIKO_MCP_*, razón por la cual este proyecto las establece explícitamente

niko.srvclass_logging.SyncedConcurrentTimedRotatingFileHandler

436

FailClosedFileHandler — sigue siendo de cierre por fallo, solo que no es seguro para múltiples procesos

niko.srvclass_list_budget.apply_budget_to_payload

2709

una función vacía que devuelve la carga útil sin cambios

No se pierde nada que sea importante fuera de Niko: el manejador concurrente resuelve un problema de varios procesos y un archivo que no ocurre aquí, y el presupuesto de lista recorta cargas útiles largas para un agente que tiene su propia contabilidad de contexto. Un archivo, dos hogares, sin bifurcación.

Fedele es la fuente de verdad de Niko, por lo que las variables de SoT llevan el prefijo FEDELE_ incluso cuando apuntan a una instancia de NetBox.

Licencia

El código propio de este proyecto es MIT — consulte LICENSE.

Es un trabajo derivado, por lo que se aplican dos licencias y ambos archivos se incluyen:

Licencia

Archivo

Código, documentación y habilidad de este proyecto

MIT

LICENSE

Partes portadas desde ktbyers/netmiko_mcp

Apache-2.0

LICENSE-APACHE-2.0

NOTICE contiene la atribución y la declaración de modificaciones que requiere Apache-2.0 §4(b). Netmiko es una dependencia MIT común: importada, no vendida, nada que redistribuir.


Diseño

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.toml

Dos reglas que no son negociables:

  1. La habilidad reside en .claude/skills/<nombre>/SKILL.md. Claude Code no lee skills/netmiko.md: necesita el directorio y ese nombre de archivo exacto.

  2. El servidor reside en mcps/, no en la raíz. PARENT_DIR es el padre del directorio que contiene el .py (mcp_server_netmiko.py:62), y de ahí proviene el .env. Con el servidor en la raíz, el .env se buscaría un nivel por encima del proyecto.

Ponerlo en marcha

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 server

Dentro de la sesión: /mcp lista las 10 herramientas, /skills confirma que la habilidad se cargó. Primera comprobación, sin tocar la red:

¿qué política de comandos está aplicando el MCP de netmiko?


Las tres variantes

De dónde proviene el inventario y de dónde provienen las credenciales son dos ejes independientes. Eso es lo que genera tres despliegues a partir de un solo servidor — y la razón por la que el servidor nunca necesita ser modificado para moverse entre ellos: dos variables de entorno lo deciden.

Inventario

Credenciales

Lo que necesitas

Cuándo usarlo

A — SoT todo

Fedele

Fedele

Token API + clave Fernet

La SoT es autoritativa y ya contiene las credenciales del dispositivo

B — Inventario SoT, credenciales locales

Fedele o NetBox

.env

Token API

Tienes una SoT pero no su plugin de credenciales. El punto de partida habitual

C — Autocontenido

YAML local

.env

nada externo

Laboratorio, aire aislado, demo, o modo degradado cuando la SoT está caída

netmiko.get_metadata informa cuál se está ejecutando realmente — nunca asumas desde el archivo de configuración:

{
  "inventory": {"backend": "fedele", "scope_filter": {"tag": "lab"}, "available": true},
  "credential_source": "env",
  "device_types_in_inventory": ["cisco_ios", "huawei_vrp", "…"]
}

A — Fedele como fuente de verdad, credenciales incluidas

El agente solicita un dispositivo por nombre; el servidor resuelve dirección, plataforma y credenciales contra la SoT en el momento de la llamada. Nada sobre el inventario reside en este proyecto: añade un dispositivo a la SoT y estará accesible en la siguiente llamada, sin necesidad de editar archivos ni reiniciar.

// .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>

Archivos: ninguno es obligatorio. commands.yml es recomendado — sin él se aplica la política de fallback incorporada. No hay inventario local involucrado, ni NETMIKO_USERNAME / NETMIKO_PASSWORD; con credential_source=fedele, NETMIKO_SECRET es ignorado — la contraseña de enable también proviene de la SoT.

Cómo funciona la búsqueda de credenciales, tres saltos:

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 key

Cosas que vale la pena saber antes de elegir esta variante:

  • La clave Fernet es todo el perímetro de seguridad. Descifra las contraseñas de los dispositivos en la memoria del servidor. Trátala como las propias contraseñas.

  • Sin FEDELE_CREDENTIALS_KEY el servidor aún arranca, y todas las herramientas devuelven el mismo Error de inicio indicando la variable faltante. Falla de forma ruidosa, no silenciosa.

  • Establece el filtro de alcance. Sin NETMIKO_MCP_FEDELE_DEVICE_FILTER el inventario es todo el parque que la SoT conoce, que también es el conjunto completo de dispositivos a los que el agente puede acceder. El servidor registra una advertencia cuando falta; el filtro acepta sintaxis de consulta, tag=lab&status=active.

  • Un dispositivo sin primary_ip, sin platform, o cuya plataforma no es un device_type de Netmiko es excluido del inventario — las SoT también inventarizan cámaras, lectores de tarjetas y chasis. Las exclusiones se cuentan y reportan, para que el agente nunca afirme "estos son todos los dispositivos" sobre un subconjunto.

  • Hay un cortacircuitos: después de un error de transporte o un 5xx, el cliente deja de llamar a la SoT durante 30 s. Un comando grupal contra 40 dispositivos con la SoT caída falla una vez, no cuarenta veces.

B — SoT para el inventario, credenciales en el .env

Idéntico a A con una variable cambiada:

"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>

Obtienes el inventario dinámico — la parte que se paga sola — sin el plugin de credenciales y sin la clave Fernet. Se utiliza una cuenta de servicio para todos los dispositivos.

NetBox, o cualquier SoT con forma de NetBox

El backend de inventario habla el dialecto REST de NetBox, por lo que NetBox mismo funciona en esta variante, sin modificaciones:

Lo que el backend llama

Lo que lee

dcim/devices/

la lista de dispositivos, filtrada por el filtro de alcance y paginada

extras/tags/, dcim/device-roles/, dcim/sites/

el que FEDELE_GROUP_SOURCE selecciona se convierte en los grupos de dispositivos

device.primary_ip.address

el host SSH, máscara eliminada

device.platform.name

el device_type de Netmiko, validado contra CLASS_MAPPER

Apunta FEDELE_URL a la instancia de NetBox (se añade /api si lo omites) y FEDELE_TOKEN a un token de API de NetBox — el cliente se autentica con el encabezado Authorization: Token … que NetBox espera. Las variables mantienen el prefijo FEDELE_; eso es un legado de nomenclatura, no un requisito del producto.

El único requisito que NetBox no cumple por defecto: platform.name debe ser exactamente un device_type de Netmikocisco_ios, arista_eos, huawei_vrp, juniper_junos. Una plataforma llamada "Cisco IOS 15.2" no es un device_type, por lo que todos los dispositivos que la lleven son excluidos del inventario. O renombra las plataformas en NetBox o acepta las exclusiones, que son reportadas.

Las credenciales son la parte que NetBox no cubre: los endpoints plugins/credentials/… pertenecen al plugin de Fedele. Con NetBox simple, la variante A no está disponible — quédate en B.

C — Autocontenido: sin SoT en absoluto

Todo reside en este proyecto. No se contacta ningún servicio externo, nunca.

// .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>

Archivos: inventory.yml es obligatorio aquí — es el único lugar donde existen los dispositivos. commands.yml sigue siendo recomendado, no obligatorio. El inventario tiene el formato de netmiko_tools — un mapeo plano de nombre a datos de conexión, más claves de grupo:

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-01

El archivo que incluye este proyecto son datos de ejemplo: 12 dispositivos ficticios en los rangos de documentación RFC 5737, 7 grupos y plataformas elegidas para que todos los dialectos CLI que menciona la lista de permitidos estén representados. Sustitúyelo por tu propio parque.

Este es el sabor con el que este proyecto viene configurado, y también es el modo degradado: si el SoT cae, dos variables y un reinicio mueven un despliegue de sabor A o sabor B aquí. Vale la pena ensayarlo antes de que lo necesites.

El coste es que el archivo se queda obsoleto. scripts/export_inventory.py en el repositorio padre lo regenera desde el SoT; ejecútalo con una programación. Un inventario de respaldo con direcciones de hace seis meses es peor que no tener respaldo, porque te enteras durante la operación.

Lo que se mantiene igual en los tres

La política de comandos, la pista de auditoría, la paginación de salida y la superficie de herramientas no cambian entre sabores. El contrato orientado al agente es idéntico, por eso la habilidad no necesita una variante por sabor.

commands.yml es recomendado, no obligatorio

El servidor funciona sin él. Si el archivo falta, no deniega todo y no se niega a arrancar: un fallback integrado de 16 comandos de solo lectura toma el control — show version, show ip interface brief, display version y sus equivalentes Junos/VRP. Esto es deliberado. Una política vacía denegaría cada comando mientras el servidor se reporta como saludable, lo que un operador leería como "el dispositivo rechazó" en lugar de "nadie escribió una política". El fallback se anuncia al inicio, netmiko.get_command_policy reporta policy_source: "fallback", y cada intento auditado lleva la fuente.

Así que el archivo es una decisión de política, no un paso de instalación: el fallback te permite ejecutar el servidor en el primer intento, y escribes commands.yml cuando quieres la política de tu propio parque en lugar de un valor predeterminado conservador. Lo que no puedes hacer es tener una política que no elegiste y no saberlo — el servidor dice cuál está en vigor cada vez que se le pregunta.


El archivo .mcp.json

.mcp.json en la raíz del proyecto declara los servidores MCP para este proyecto. Claude Code pide aprobación la primera vez que ve el archivo, y el archivo está pensado para ser confirmado: es cómo todo el equipo obtiene el mismo servidor.

Existen otros dos ámbitos para la misma definición de servidor:

Ámbito

Dónde reside

Quién lo ve

project

.mcp.json en la raíz del proyecto

cualquiera que abra el proyecto (tras aprobarlo)

user

~/.claude.json

todos los proyectos de ese usuario, en esa máquina

local

~/.claude.json, indexado por ruta del proyecto

solo ese usuario, solo en ese proyecto

claude mcp add --scope project netmiko -- /path/to/python /path/to/server.py escribe la entrada project por ti; editar el JSON a mano es equivalente.

Forma del archivo

{
  "mcpServers": {           // ← the top-level key. Not "servers", not "mcp".
    "netmiko": {            // ← the server name; it becomes the tool prefix
      ...                   //    mcp__netmiko__<tool>
    }
  }
}

El nombre del servidor no es cosmético: Claude Code expone cada herramienta como mcp__<nombre-servidor>__<nombre-herramienta>. Con el nombre netmiko y la herramienta netmiko.get_metadata que el servidor registra, la herramienta que Claude realmente ve es mcp__netmiko__netmiko.get_metadata. Ejecuta /mcp para leer los nombres exactos antes de escribirlos en una lista allowed-tools o en una regla de permisos.

Referencia de campos

Campo

Transporte

Significado

type

ambos

"stdio" (predeterminado si se omite), "http" o "sse"

command

stdio

el ejecutable a lanzar. Ruta absoluta — no asumas un directorio de trabajo

args

stdio

lista de argumentos, cada elemento separado

env

stdio

entorno para el proceso hijo. Se fusiona sobre el heredado

url

http / sse

URL completa del endpoint, incluida la ruta

headers

http / sse

cabeceras extra de la solicitud, típicamente Authorization

Los valores soportan expansión de entorno: ${VAR} y ${VAR:-default}. Útil para mantener un token fuera del archivo confirmado:

"headers": { "Authorization": "Bearer ${NETMIKO_MCP_TOKEN}" }

Transporte 1 — stdio (el que usa este proyecto)

Claude Code lanza el servidor como un proceso hijo y habla JSON-RPC a través de su stdin/stdout. Nada escucha en un puerto, nada es accesible desde la red, y la vida del proceso es la de la sesión. Este es el valor predeterminado correcto para un servidor que contiene credenciales SSH.

{
  "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"
      }
    }
  }
}

Dos cosas que pican:

  • Sin rutas codificadas, y el directorio de trabajo no es algo en lo que confiar. ${CLAUDE_PROJECT_DIR:-.} es lo que mantiene el archivo confirmable tal cual; la siguiente sección cuenta toda la historia, porque la lectura obvia es incorrecta.

  • El servidor no debe escribir en stdout. stdout es el canal del protocolo, y una línea suelta ahí rompe la sesión. El registro va a stderr más el archivo rotatorio en LOG_FILE (5 MB × 3, creado 0600 — en DEBUG este archivo lleva la salida del dispositivo). Dentro de Niko la misma variable es manejada por MCPLogging en su lugar.

De dónde viene ${CLAUDE_PROJECT_DIR:-.}

Dos cosas separadas en una cadena: una sintaxis y una variable.

La sintaxis. ${VAR} y ${VAR:-default} es sustitución de parámetros POSIX ("usa VAR; si no está definida o está vacía, usa default"), pero no interviene ningún shell — un archivo JSON nunca pasa por uno. Claude Code implementa la expansión por sí mismo cuando lee el archivo, en command, args, env, url y headers. Es una convención de ese cliente, no parte de la especificación MCP: otro cliente puede no implementarla (ver Agentes que no son Claude, donde las rutas entonces tienen que ser literales), y VS Code tiene su propia ortografía, ${workspaceFolder}.

La variable. CLAUDE_PROJECT_DIR es establecida por Claude Code en la raíz del proyecto, el mismo valor que reciben los hooks. Es estable — conceder directorios de trabajo adicionales a mitad de sesión con --add-dir no la mueve.

La parte que es contraintuitiva, y la razón por la que :-. no es decoración: Claude Code establece esa variable en el entorno del servidor que lanza, no en el suyo propio. La expansión, sin embargo, ocurre antes del lanzamiento, contra el entorno de Claude Code — donde la variable no existe. Un ${CLAUDE_PROJECT_DIR} desnudo se expandiría por tanto a nada y dejaría /config/netmiko/inventory.yml, una ruta absoluta a la raíz del sistema de archivos.

Así que en un .mcp.json de ámbito de proyecto el valor predeterminado no es un fallback para algún caso extremo: es el valor que se usa, cada vez. Lo que llega al proceso es ./config/netmiko/inventory.yml. La única excepción es una configuración MCP enviada por un plugin — allí Claude Code sustituye la variable directamente y no se necesita ningún valor predeterminado.

Eso es lo que fuerza la mano del servidor. Un valor relativo se resolvería contra el directorio de trabajo del proceso hijo, y el directorio de trabajo es elección del cliente, no del proyecto. De ahí resolve_project_path(): cada ajuste de ruta relativa se ancla a PARENT_DIR — el padre de mcps/, la misma raíz de la que viene .env — cuando se cargan los ajustes. Una sesión lanzada desde cualquier lugar encuentra config/netmiko/, y validate_startup() nombra el archivo absoluto cuando falta uno. Una ~ sigue significando el home del operador, nunca un archivo dentro del proyecto.

La variable sigue siendo útil como la documentación pretende, leída desde dentro del servidor (os.environ["CLAUDE_PROJECT_DIR"]), donde está establecida. Este servidor no la necesita: PARENT_DIR se deriva de __file__ y por tanto no depende de ningún cliente — la misma razón por la que el transporte HTTP, donde nadie establece esa variable, no necesita un caso especial.

Fuente: Claude Code — MCP, secciones Add a local stdio server y Environment variable expansion in .mcp.json.

Transporte 2 — HTTP (HTTP transmisible)

Claude Code lo soporta, y también cualquier otro cliente MCP. Es el transporte a usar cuando el servidor se ejecuta en otro lugar: otro host, un contenedor, un servicio compartido por varios agentes, o un agente que no es Claude.

El archivo del servidor siempre llama a mcp.run(transport="stdio") bajo su guarda __main__, así que HTTP se sirve mediante la CLI de FastMCP en su lugar — sin cambio de código:

.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/

Las variables NETMIKO_MCP_* ya no forman parte de la configuración del cliente: el proceso del servidor lo inicias tú, por lo que pertenecen a su entorno (una exportación de shell, una unidad systemd, un bloque environment: de un contenedor).

Lado del cliente:

{
  "mcpServers": {
    "netmiko": {
      "type": "http",
      "url": "http://127.0.0.1:8123/mcp/",
      "headers": {
        "Authorization": "Bearer ${NETMIKO_MCP_TOKEN}"
      }
    }
  }
}

O, equivalentemente, claude mcp add --transport http netmiko http://127.0.0.1:8123/mcp/.

--transport sse y "type": "sse" también funcionan; SSE es el transporte remoto más antiguo y se mantiene para clientes que no han migrado a HTTP transmisible.

Seguridad. La CLI de FastMCP sirve esto sin autenticación alguna: quien alcance el puerto puede ejecutar comandos show contra cada dispositivo del inventario, usando las credenciales del entorno del servidor. Enlaza a 127.0.0.1 para una prueba local, y para cualquier cosa compartida ponlo detrás de un proxy inverso que termine TLS y verifique la cabecera Authorization. El bloque headers de arriba es lo que el cliente envía; el proxy es quien debe verificarlo.

Agentes que no son Claude

El objeto mcpServers mostrado aquí es la forma de facto: Claude Code, Claude Desktop, Cursor y Windsurf leen los mismos tres campos para stdio (command / args / env) y los mismos dos para remoto (url / headers). Copiar una entrada entre ellos normalmente funciona tal cual.

Diferencias conocidas que vale la pena comprobar antes de copiar:

  • VS Code usa mcp.json con una clave de nivel superior "servers" en lugar de "mcpServers", y quiere que "type" se indique explícitamente.

  • Algunos clientes no implementan la expansión ${VAR}; allí el valor tiene que ser literal, lo cual es un argumento para el transporte HTTP más un proxy en lugar de un token pegado en un archivo confirmado.

  • Un agente sin ningún archivo de configuración aún puede hablar directamente con el endpoint HTTP — la URL y la cabecera Authorization son todo el contrato.

El bloque env

Las entradas NETMIKO_MCP_* prevalecen sobre cualquier archivo de configuración YAML. Se establecen explícitamente porque fuera de Niko no hay NikoPaths, por lo que los valores predeterminados caen en ~/commands.yml y ~/.netmiko_mcp_tmp.

Cada ruta aquí puede escribirse relativa a la raíz del proyecto: el servidor ancla los valores relativos a PARENT_DIR cuando se cargan los ajustes, por lo que el directorio de trabajo del proceso lanzado nunca decide dónde vive el inventario o la pista de auditoría. Una ruta absoluta o una ~ se toma tal cual.

Variable

Default

Propósito

NETMIKO_MCP_INVENTORY_TYPE

netmiko_tools

yaml (archivo local) o fedele (SoT)

NETMIKO_MCP_INVENTORY_FILE

(búsqueda de netmiko-tools)

ruta del inventario cuando el tipo es yaml

NETMIKO_MCP_CREDENTIAL_SOURCE

env

env (lee el .env) o fedele

NETMIKO_MCP_FEDELE_GROUP_SOURCE

tags

qué define un grupo: tags, device_roles, sites

NETMIKO_MCP_FEDELE_DEVICE_FILTER

(ninguno)

filtro de alcance, tag=lab&status=active. Sin él: todo el conjunto

NETMIKO_MCP_FEDELE_CACHE_TTL

60

caché de resolución de SoT, en segundos

NETMIKO_MCP_COMMAND_FILE

~/commands.yml fuera de Niko

lista de permitidos/denegados

NETMIKO_MCP_ALLOW_PIPE

false

habilita tuberías en los comandos

NETMIKO_MCP_SSH_CONFIG_FILE

(ninguno)

ssh_config de OpenSSH. Necesario para jumphosts — Netmiko no lee ~/.ssh/config por sí mismo

NETMIKO_MCP_MAX_WORKERS

10

conexiones concurrentes en comandos de grupo

NETMIKO_MCP_SAVE_OUTPUT_DIR

~/.netmiko_mcp_tmp fuera de Niko

búfer para salidas grandes

NETMIKO_MCP_SAVE_THRESHOLD

1000

número de líneas a partir del cual la salida se guarda en lugar de devolverse en línea

NETMIKO_MCP_AUDIT_LOG_FILE

(véase el README principal)

registro de auditoría (JSON, cierre por fallo). Pida al agente que lo lea con netmiko.query_audit_trail

NETMIKO_MCP_CONFIG

~/.netmiko-mcp.yml

ruta a un archivo de configuración YAML que contiene estos mismos ajustes

LOG_FILE / LOG_LEVEL

Niko.log / INFO

registro operativo: siempre stderr, más este archivo rotatorio (5 MB × 3, 0600). LOG_LEVEL se indica con su valor predeterminado para que el control esté donde se busca — ajústelo a DEBUG y la salida del dispositivo aparecerá en el registro

Las credenciales no se configuran aquí. NETMIKO_USERNAME, NETMIKO_PASSWORD, NETMIKO_SECRET y las variables FEDELE_* se leen desde <project-root>/.env, para que nunca terminen en un archivo JSON confirmado. Precedencia: lo que está en el bloque env prevalece sobre el .env, en silencio — defina cada variable en un solo lugar.

Todas las demás variables están documentadas en el README del repositorio principal.

Comprobación de funcionamiento

claude mcp list          # netmiko: ✓ connected

Dentro de la sesión, /mcp lista las herramientas y /skills confirma que la habilidad se ha cargado. Pregunte qué política está vigente y netmiko.get_command_policy indica el nombre del archivo que está leyendo — o informa "fallback", lo que significa que nunca encontró el archivo y se está ejecutando con los 16 comandos integrados.


Autor: Ed Scrimaglia edgardo.scrimaglia@gmail.com — última actualización: 2026-08-18.

A
license - permissive license
A
quality
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides 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.
    11
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables 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.
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables read-only querying and diagnostics of Fortigate firewalls via SSH, providing security analysis, traffic monitoring, and configuration inspection through natural language.
    MIT

View all related MCP servers

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.

View all MCP Connectors

Latest Blog Posts

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