pyATS MCP Server
pyATS MCP Server
Cisco pyATS y Genie ya saben cómo hablar con una red: analizar comandos show, aplicar configuración, aprender el estado de las funciones y ejecutar pruebas declarativas. Lo que no tenían era una forma de que un agente de IA pudiera manejarlos directamente. Este servidor cierra esa brecha: envuelve pyATS/Genie como un conjunto de herramientas MCP estructuradas y protegidas que un agente como Claude puede invocar contra un testbed real, a través del transporte Streamable HTTP actual del Model Context Protocol.
Apúntale un agente y podrá buscar un dispositivo, ejecutar y analizar un comando show, aplicar configuración con un punto de rollback, aprender y comparar el estado de una función antes y después de un cambio, distribuir un comando a través de una flota (un grupo de hilos o un proceso por dispositivo), ejecutar una prueba declarativa de Blitz o Robot Framework, o llamar directamente a la API REST/RESTCONF de un dispositivo. Cada ruta riesgosa está protegida antes de llegar al dispositivo, y cada llamada queda registrada en un registro de auditoría en memoria que el agente puede revisar durante la sesión.
De un vistazo
Transporte — Streamable HTTP (
mcp>=2.0.0), con o sin estado, elegido con una variable de entorno. STDIO ya no existe.26 herramientas en descubrimiento, comandos show, configuración, aprendizaje/diferencias de Genie, Genie Clean, pruebas declarativas (Blitz, Robot Framework, AEtest), REST/RESTCONF genérico y Cisco XPresso.
Dos formas de distribuir un comando entre muchos dispositivos: un grupo de hilos compartido para uso diario, o un proceso de SO por dispositivo (
pyats.async_.pcall) cuando se necesita aislamiento real a escala.Protecciones, no sistemas de honor — los comandos peligrosos se bloquean antes de llegar al dispositivo, Genie Clean nunca puede ejecutar una etapa que reinicie o reimage un dispositivo, y las acciones destructivas requieren una frase de confirmación exacta.
Nada codificado — cada credencial y detalle del dispositivo vive en
.env, se incorpora atestbed.yamlen tiempo de ejecución mediante la sustitución%ENV{}.
Related MCP server: network-mcp
Requisitos previos
Python 3.10+
Un
testbed.yamlde pyATS apuntando a dispositivos de red reales o virtuales: un laboratorio físico, Cisco Modeling Labs / VIRL / GNS3, o cualquier otra cosa que Unicon pueda alcanzar por SSH/Telnet. pyATS MCP no simula una red; la maneja.Un cliente compatible con MCP para comunicarse con él — consulte Conecte su agente a continuación.
Inicio rápido
# 1. Clone and install
git clone https://github.com/automateyournetwork/pyATS_MCP
cd pyATS_MCP
pip install -r requirements.txt
# 2. Configure your environment
cp .env.example .env
# Edit .env — see Configuration below
# 3. Run — starts a Streamable HTTP server on 0.0.0.0:8080 by default
python3 pyats_mcp_server.pyEl endpoint MCP estará disponible en http://<host>:<port>/mcp.
Configuración
Todos los detalles de los dispositivos y las credenciales viven en un archivo .env — nada está codificado en el repositorio.
1. Copie la plantilla
cp .env.example .env2. Establezca las variables del servidor
PYATS_TESTBED_PATH=/absolute/path/to/your/testbed.yaml
PYATS_MCP_ARTIFACTS_DIR= # default: ~/.pyats-mcp/artifacts
PYATS_MCP_KEEP_ARTIFACTS=1 # 1 = keep, 0 = delete after each run
PYATS_MCP_TESTBED_CACHE_TTL=30 # seconds before testbed reloads from disk
PYATS_MCP_CONN_CACHE_TTL=0 # seconds to keep connections alive (0 = off)
PYATS_MCP_OP_LOG_MAX=500 # max entries in the in-memory operation log
# Transport (Streamable HTTP only — STDIO is not supported)
PYATS_MCP_TRANSPORT_MODE=stateful # stateful (default) | stateless
PYATS_MCP_HTTP_HOST=0.0.0.0
PYATS_MCP_HTTP_PORT=8080
# Optional — only needed for pyats_xpresso_request
XPRESSO_URL=
XPRESSO_API_TOKEN=
XPRESSO_GROUP=PYATS_MCP_TRANSPORT_MODE=stateless establece stateless_http=True en el transporte Streamable HTTP, de modo que no se retiene estado de sesión en el servidor entre solicitudes de clientes que aún negocian el protocolo antiguo basado en handshake. Los clientes que hablan el protocolo MCP actual (2026-07-28, SEP-2575) no requieren handshake por defecto independientemente de esta configuración; eso proviene del propio SDK mcp>=2.0.0, no de nada configurado aquí.
3. Añada un bloque para cada dispositivo
Cada dispositivo en su testbed.yaml usa la sustitución %ENV{VAR}, por lo que las credenciales y los detalles de conexión se leen de .env en tiempo de ejecución.
Use la convención de nomenclatura {DEVICENAME}_{FIELD}:
# Supported os values: iosxe | iosxr | nxos | ios | eos | junos | panos | linux | windows
# Set os=generic and platform="" to let Unicon autodetect on first connect.
CORE1_IP=10.1.1.1
CORE1_PORT=22
CORE1_OS=iosxe
CORE1_PLATFORM=cat9k
CORE1_USERNAME=admin
CORE1_PASSWORD=s3cr3t
CORE1_ENABLE_PASSWORD=s3cr3t
FW1_IP=10.1.1.2
FW1_PORT=22
FW1_OS=panos
FW1_PLATFORM=
FW1_USERNAME=admin
FW1_PASSWORD=s3cr3t
# (no enable password for Palo Alto)
LINUX1_IP=10.1.1.3
LINUX1_PORT=22
LINUX1_OS=linux
LINUX1_PLATFORM=ubuntu
LINUX1_USERNAME=admin
LINUX1_PASSWORD=s3cr3t
# (no enable password for Linux)Si un grupo de dispositivos comparte credenciales, defina variables a nivel de grupo y refiéralas en todos los dispositivos:
SITE_A_USERNAME=netops
SITE_A_PASSWORD=s3cr3t
SITE_A_ENABLE_PASSWORD=s3cr3t4. Referencie las variables en testbed.yaml
devices:
CORE1:
alias: "Core Switch 1"
type: "switch"
os: "%ENV{CORE1_OS}"
platform: "%ENV{CORE1_PLATFORM}"
credentials:
default:
username: "%ENV{CORE1_USERNAME}"
password: "%ENV{CORE1_PASSWORD}"
enable:
password: "%ENV{CORE1_ENABLE_PASSWORD}"
connections:
cli:
protocol: ssh
ip: "%ENV{CORE1_IP}"
port: "%ENV{CORE1_PORT}"
arguments:
connection_timeout: 360Para dispositivos con SO desconocido, establezca
os: "%ENV{DEVICE_OS}"conDEVICE_OS=genericen.envy opcionalmente añadalearn_os: truebajoarguments:— Unicon detectará y almacenará en caché el SO después de la primera conexión.
Docker
Compilar
docker build -t pyats-mcp-server .Ejecutar (pasar .env directamente)
docker run -p 8080:8080 --rm \
--env-file /absolute/path/to/.env \
-v /absolute/path/to/testbed.yaml:/app/testbed.yaml \
pyats-mcp-serverEn cualquier caso, el servidor es un proceso de larga duración que se inicia una vez y al que los clientes se conectan; no es algo que un agente genere por sesión. Vea a continuación exactamente cómo se conecta cada cliente.
Conecte su agente
El servidor expone una sola cosa: un endpoint MCP en http://<host>:<port>/mcp (Streamable HTTP). Cada cliente a continuación solo necesita esa URL — sin command/args, sin proceso local que el cliente deba gestionar.
Claude Code
claude mcp add --transport http pyats http://localhost:8080/mcp
# Behind auth (e.g. a reverse proxy in front of the server)
claude mcp add --transport http pyats http://localhost:8080/mcp \
--header "Authorization: Bearer your-token"O colóquelo directamente en .mcp.json (a nivel de proyecto, confirmado en el repositorio) o en ~/.claude.json (a nivel de usuario):
{
"mcpServers": {
"pyats": { "type": "http", "url": "http://localhost:8080/mcp" }
}
}VS Code (GitHub Copilot Chat)
Añada un .vscode/mcp.json en el espacio de trabajo (o ejecute MCP: Add Server desde la Paleta de Comandos):
{
"servers": {
"pyats": { "type": "http", "url": "http://localhost:8080/mcp" }
}
}OpenAI Codex CLI
codex mcp add pyats --url http://localhost:8080/mcpO en ~/.codex/config.toml:
[mcp_servers.pyats]
url = "http://localhost:8080/mcp"Claude Desktop
El claude_desktop_config.json de Claude Desktop es solo stdio — poner un campo url no funciona (es un problema conocido, no una ruta compatible). Los servidores remotos/HTTP se añaden en su lugar como Custom Connector en Configuración → Conectores, y Desktop se conecta desde la nube de Anthropic, no desde su máquina local — por lo que necesita una URL HTTPS real y accesible públicamente, no localhost.
Para apuntar Desktop a un servidor que se ejecuta en su propia máquina de todos modos, conéctelo a través de mcp-remote como un proxy stdio local:
{
"mcpServers": {
"pyats": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://localhost:8080/mcp", "--transport", "http-only"]
}
}
}Python puro (LangGraph, agentes personalizados, cualquier otra cosa)
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
async def main():
async with streamablehttp_client("http://localhost:8080/mcp") as (read, write, _session_id):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await session.list_tools()
result = await session.call_tool(
"pyats_run_show_command",
arguments={"device_name": "CORE1", "command": "show version"},
)Qué pedirle
Una vez conectado, hable con él como hablaría con alguien que ya conoce la red:
"¿Qué dispositivos hay en el testbed?" →
pyats_list_devices"Muéstrame el resumen de BGP en CORE1" →
pyats_run_show_command, analizado en JSON estructurado"Captura el estado de OSPF de CORE1, luego aplica esta configuración y muéstrame qué cambió" →
pyats_learn_feature(antes) →pyats_configure_with_diff→pyats_learn_feature(después) →pyats_diff_learned_snapshots"Ejecuta
show ip interface briefen todos los switches" →pyats_run_show_command_multi(opyats_pcall_show_commandpara aislamiento por proceso a escala real)"Si ese cambio de configuración rompe algo, reviértelo" →
pyats_rollback_config"Ejecuta esta prueba Blitz contra R1 y R2" / "Ejecuta esta suite de Robot Framework" →
pyats_run_blitz/pyats_run_robot
El agente encadena estas acciones por sí mismo — usted describe el resultado, él elige las herramientas.
Herramientas disponibles
26 herramientas, agrupadas por lo que hacen.
Descubrimiento
Herramienta | Descripción |
| Lista todos los dispositivos del testbed |
| Búsqueda difusa de dispositivos por nombre o alias |
Comandos show
Herramienta | Descripción |
| Ejecuta un comando show validado; devuelve JSON analizado o salida sin procesar |
| Ejecuta un comando show en varios dispositivos simultáneamente (grupo de hilos) |
| Igual, pero un proceso de SO por dispositivo ( |
| Obtiene la configuración en ejecución completa (texto sin procesar) |
| Obtiene los registros del sistema del dispositivo mediante |
| Ejecuta un ping desde un dispositivo de red |
| Ejecuta un comando en un host Linux |
Configuración
Herramienta | Descripción |
| Aplica comandos de configuración con protecciones de seguridad |
| Aplica configuración en varios dispositivos simultáneamente (grupo de hilos) |
| Igual, pero un proceso de SO por dispositivo |
| Aplica configuración y devuelve una diferencia antes/después |
| Revierte a la última instantánea de configuración guardada |
Estado y diagnóstico
Herramienta | Descripción |
| Captura CPU, memoria, interfaces y estado de enrutamiento |
| Obtiene vecinos CDP/LLDP |
| Encuentra qué interfaz posee una dirección IP dada |
| Genie |
| Compara dos instantáneas guardadas por |
Pruebas y automatización
Herramienta | Descripción |
| Genie Clean (Kleenex), restringido a etapas no destructivas |
| Ejecuta una prueba declarativa YAML de pyATS Blitz |
| Ejecuta una suite de Robot Framework usando las bibliotecas de palabras clave |
| Ejecuta un script AEtest de pyATS en un entorno aislado |
APIs
Herramienta | Descripción |
| Llamada REST/RESTCONF/NX-API genérica a través del |
| Llamada autenticada a la API REST v2 de Cisco XPresso (solicitudes de prueba, trabajos, testbeds, imágenes, …) |
Sesión
Herramienta | Descripción |
| Obtiene el registro de operaciones en memoria |
Seguridad
Los comandos show se validan: se bloquean tuberías, redirecciones y palabras clave peligrosas.
Los cambios de configuración se verifican para
reload,erase,write erase,delete,format; la misma verificación se ejecuta dentro depyats_clean_device,pyats_run_blitzypyats_run_robot.Los scripts de prueba dinámicos se ejecutan en un sandbox restringido (importaciones prohibidas:
os,sys,subprocess, etc.).pyats_clean_devicenunca ejecuta una etapa real de Genie Clean que reinicie, borre o reinstale la imagen de un dispositivo; solo se generanconnect+execute_command, y el valor predeterminado esdry_run=True; ejecutarlo de verdad también requiere una frase de confirmación exacta.Cada caché global del proceso (caché de conexiones, caché de testbed, instantáneas de configuración/aprendizaje, registro de operaciones) está protegida por un bloqueo, de modo que los clientes HTTP concurrentes no pueden corromper el estado compartido.
Todas las credenciales provienen de
.env; nunca se almacenan en el archivo de testbed ni en el código fuente.
Estructura del Proyecto
.
├── pyats_mcp_server.py # MCP server
├── test_pyats_mcp_server.py # Unit tests (119 tests)
├── benchmark/ # Pre/post, stateful/stateless transport benchmark
├── Dockerfile # Container definition
├── requirements.txt # Pinned runtime dependencies
├── requirements-dev.txt # Dev/test dependencies
├── pyproject.toml # Tool config (black, isort, pytest, mypy)
├── .env.example # Configuration template — copy to .env
├── .gitignore
├── LICENSE
└── CONTRIBUTING.mdDesarrollo
# Install dev dependencies with uv
uv venv .venv && uv pip install -r requirements-dev.txt
# Run tests
.venv/bin/python -m pytest
# Lint and format
.venv/bin/black .
.venv/bin/isort .
.venv/bin/flake8 . --max-line-length=100Consulta CONTRIBUTING.md para la configuración completa y el flujo de trabajo de PR.
Benchmark
benchmark/ compara STDIO (heredado) con Streamable HTTP en modo con estado y sin estado, contra un testbed real. Consulta benchmark/scenarios.py para la lista de escenarios y benchmark/aggregate.py para generar el informe de comparación; benchmark/results/summary.md contiene los números de la ejecución más reciente.
Licencia
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 Servers
- AlicenseNot gradedqualityBmaintenanceEnables structured interaction with Cisco network devices using pyATS and Genie. Supports executing show commands, ping tests, and configuration changes on IOS/NX-OS devices through secure STDIO communication.78MIT
- 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 gradedqualityAmaintenanceEnables LLMs to interact with network devices via Cisco RADKit, supporting inventory discovery, device attribute inspection, CLI command execution, and SNMP queries.11Apache 2.0
Related MCP Connectors
Build, validate, and deploy multi-agent AI solutions from any AI environment.
Curated knowledge API for AI agents - skill packs, semantic search, validated patterns.
Deterministic reasoning stack for AI agents: simulate, decide & compute, plus cross-domain tools.
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/sunayan22doli-bit/MCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server