pyATS MCP Server
pyATS MCP Server
Cisco pyATS и Genie уже умеют разговаривать с сетью — парсить show-команды, применять конфигурацию, изучать состояние функций, запускать декларативные тесты. Чего у них не было — так это способа для ИИ-агента управлять всем этим напрямую. Этот сервер закрывает этот пробел: он оборачивает pyATS/Genie в набор структурированных, защищённых MCP-инструментов, которые агент вроде Claude может вызывать против реального тестбеда через текущий Streamable HTTP транспорт протокола Model Context Protocol.
Наведите на него агента — и он сможет найти устройство, выполнить и распарсить show-команду, применить конфигурацию с точкой отката, изучить и сравнить состояние функции до и после изменения, разослать команду по всей флотилии — один пул потоков или один процесс на устройство — запустить декларативный тест Blitz или Robot Framework, или обратиться к REST/RESTCONF API устройства напрямую. Каждый рискованный путь защищён до того, как достигнет устройства, и каждый вызов попадает в журнал аудита в памяти, который агент может просмотреть в середине сессии.
Краткий обзор
Транспорт — Streamable HTTP (
mcp>=2.0.0), с сохранением состояния или без, выбирается одной переменной окружения. STDIO больше нет.26 инструментов для обнаружения, show-команд, конфигурации, Genie learn/diff, Genie Clean, декларативного тестирования (Blitz, Robot Framework, AEtest), универсального REST/RESTCONF и Cisco XPresso.
Два способа разослать команду по множеству устройств — общий пул потоков для повседневного использования или один процесс ОС на устройство (
pyats.async_.pcall), когда нужна настоящая изоляция в масштабе.Ограждения, а не системы чести — опасные команды блокируются до того, как достигнут устройства, Genie Clean никогда не сможет выполнить этап, который перезагружает или перепрошивает устройство, а разрушительные действия требуют точной фразы подтверждения.
Ничего не захардкожено — все учётные данные и сведения об устройствах хранятся в
.envи подтягиваются вtestbed.yamlво время выполнения через подстановку%ENV{}.
Related MCP server: network-mcp
Предварительные требования
Python 3.10+
testbed.yamlот pyATS, указывающий на реальные или виртуальные сетевые устройства — физическая лаборатория, Cisco Modeling Labs / VIRL / GNS3 или что угодно ещё, к чему Unicon может добраться по SSH/Telnet. pyATS MCP не симулирует сеть; он управляет ею.MCP-совместимый клиент для взаимодействия — см. Подключение вашего агента ниже.
Быстрый старт
# 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.pyКонечная точка MCP затем доступна по адресу http://<host>:<port>/mcp.
Конфигурация
Все сведения об устройствах и учётные данные хранятся в файле .env — в репозитории ничего не захардкожено.
1. Скопируйте шаблон
cp .env.example .env2. Задайте переменные сервера
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 устанавливает stateless_http=True на транспорте Streamable HTTP, так что состояние сессии на стороне сервера не сохраняется между запросами от клиентов, всё ещё использующих старый протокол с рукопожатием. Клиенты, говорящие на текущем протоколе MCP (2026-07-28, SEP-2575), по умолчанию не требуют рукопожатия независимо от этой настройки — это обеспечивает сам SDK mcp>=2.0.0, а не какая-либо конфигурация здесь.
3. Добавьте блок для каждого устройства
Каждое устройство в вашем testbed.yaml использует подстановку %ENV{VAR}, поэтому учётные данные и сведения о подключении считываются из .env во время выполнения.
Используйте соглашение об именовании {ИМЯ_УСТРОЙСТВА}_{ПОЛЕ}:
# 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)Если группа устройств использует общие учётные данные, определите переменные уровня группы и ссылайтесь на них на всех устройствах:
SITE_A_USERNAME=netops
SITE_A_PASSWORD=s3cr3t
SITE_A_ENABLE_PASSWORD=s3cr3t4. Укажите переменные в 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: 360Для устройств с неизвестной ОС задайте
os: "%ENV{DEVICE_OS}"со значениемDEVICE_OS=genericв.env, и при желании добавьтеlearn_os: trueв разделarguments:— Unicon определит ОС и закеширует её после первого подключения.
Docker
Сборка
docker build -t pyats-mcp-server .Запуск (передача .env напрямую)
docker run -p 8080:8080 --rm \
--env-file /absolute/path/to/.env \
-v /absolute/path/to/testbed.yaml:/app/testbed.yaml \
pyats-mcp-serverВ любом случае сервер — это долгоживущий процесс, который вы запускаете один раз и подключаете к нему клиентов — это не то, что агент порождает для каждой сессии. Ниже описано, как именно каждый клиент подключается к нему.
Подключение вашего агента
Сервер предоставляет одну вещь: конечную точку MCP по адресу http://<host>:<port>/mcp (Streamable HTTP). Каждому клиенту ниже нужен только этот URL — никаких command/args, никакого локального процесса для управления клиентом.
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"Или добавьте прямо в .mcp.json (в рамках проекта, фиксируется в репозитории) или ~/.claude.json (в рамках пользователя):
{
"mcpServers": {
"pyats": { "type": "http", "url": "http://localhost:8080/mcp" }
}
}VS Code (GitHub Copilot Chat)
Добавьте .vscode/mcp.json в рабочую область (или выполните MCP: Add Server из палитры команд):
{
"servers": {
"pyats": { "type": "http", "url": "http://localhost:8080/mcp" }
}
}OpenAI Codex CLI
codex mcp add pyats --url http://localhost:8080/mcpИли в ~/.codex/config.toml:
[mcp_servers.pyats]
url = "http://localhost:8080/mcp"Claude Desktop
claude_desktop_config.json в Claude Desktop поддерживает только stdio — поле url в нём не работает (это известная проблема, а не поддерживаемый путь). Удалённые/HTTP-серверы добавляются вместо этого как Custom Connector в Settings → Connectors, и Desktop подключается к нему из облака Anthropic, а не с вашей локальной машины — поэтому ему нужен реальный, публично доступный HTTPS URL, а не localhost.
Чтобы всё же указать Desktop на сервер, запущенный на вашей собственной машине, соедините его через mcp-remote как локальный stdio-прокси:
{
"mcpServers": {
"pyats": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://localhost:8080/mcp", "--transport", "http-only"]
}
}
}Чистый Python (LangGraph, кастомные агенты, что угодно ещё)
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"},
)Что у него спросить
После подключения общайтесь с ним, как с человеком, который уже знает сеть:
«Какие устройства есть в тестбеде?» →
pyats_list_devices«Покажи сводку BGP на CORE1» →
pyats_run_show_command, распарсенная в структурированный JSON«Сними снимок состояния OSPF на CORE1, затем примени эту конфигурацию и покажи, что изменилось» →
pyats_learn_feature(до) →pyats_configure_with_diff→pyats_learn_feature(после) →pyats_diff_learned_snapshots«Выполни
show ip interface briefна всех коммутаторах» →pyats_run_show_command_multi(илиpyats_pcall_show_commandдля изоляции «один процесс на устройство» в реальном масштабе)«Если это изменение конфигурации что-то сломает, откати его» →
pyats_rollback_config«Запусти этот тест Blitz на R1 и R2» / «Запусти этот набор Robot Framework» →
pyats_run_blitz/pyats_run_robot
Агент сам выстраивает цепочку этих инструментов — вы описываете результат, а он выбирает инструменты.
Доступные инструменты
26 инструментов, сгруппированных по назначению.
Обнаружение
Инструмент | Описание |
| Список всех устройств в тестбеде |
| Нечёткий поиск устройств по имени или псевдониму |
Show-команды
Инструмент | Описание |
| Выполнить проверенную show-команду; возвращает распарсенный JSON или необработанный вывод |
| Выполнить show-команду на нескольких устройствах одновременно (пул потоков) |
| То же, но один процесс ОС на устройство ( |
| Получить полную текущую конфигурацию (необработанный текст) |
| Получить системные журналы устройства через |
| Выполнить ping с сетевого устройства |
| Выполнить команду на Linux-хосте |
Конфигурация
Инструмент | Описание |
| Применить команды конфигурации с защитными ограждениями |
| Применить конфигурацию на нескольких устройствах одновременно (пул потоков) |
| То же, но один процесс ОС на устройство |
| Применить конфигурацию и вернуть разницу до/после |
| Откатиться к последнему сохранённому снимку конфигурации |
Состояние и диагностика
Инструмент | Описание |
| Снимок CPU, памяти, интерфейсов и состояния маршрутизации |
| Получить соседей CDP/LLDP |
| Найти, какому интерфейсу принадлежит данный IP-адрес |
| Genie |
| Сравнить два снимка, сохранённых через |
Тестирование и автоматизация
Инструмент | Описание |
| Genie Clean (Kleenex), ограничен неразрушающими этапами |
| Запустить декларативный YAML-тест pyATS Blitz |
| Запустить набор Robot Framework с использованием библиотек ключевых слов |
| Выполнить изолированный скрипт pyATS AEtest |
API
Инструмент | Описание |
| Универсальный вызов REST/RESTCONF/NX-API через |
| Аутентифицированный вызов REST API v2 Cisco XPresso (тестовые запросы, задания, тестбеды, образы, …) |
Сессия
Инструмент | Описание |
| Получить журнал операций из памяти |
Безопасность
Show-команды проверяются — конвейеры, перенаправления и опасные ключевые слова блокируются.
Изменения конфигурации проверяются на
reload,erase,write erase,delete,format— та же проверка выполняется внутриpyats_clean_device,pyats_run_blitzиpyats_run_robot.Динамические тестовые скрипты выполняются в ограниченной песочнице (запрещённые импорты:
os,sys,subprocessи т. д.).pyats_clean_deviceникогда не запускает реальный этап Genie Clean, который перезагружает, стирает или переустанавливает устройство — генерируются толькоconnect+execute_command— и по умолчанию используетсяdry_run=True; реальный запуск также требует точной фразы подтверждения.Каждый глобальный для процесса кэш (кэш соединений, кэш тестовых стендов, снимки config/learn, журнал операций) защищён блокировкой, поэтому одновременные HTTP-клиенты не могут повредить общее состояние.
Все учётные данные берутся из
.env— никогда не хранятся в файле тестового стенда или в исходном коде.
Структура проекта
.
├── 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.mdРазработка
# 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=100Полную настройку и процесс работы с PR см. в CONTRIBUTING.md.
Бенчмарк
benchmark/ сравнивает STDIO (устаревший) с Streamable HTTP в stateful и stateless режимах, на реальном тестовом стенде. Список сценариев см. в benchmark/scenarios.py, а сборку отчёта о сравнении — в benchmark/aggregate.py; в benchmark/results/summary.md приведены цифры последнего запуска.
Лицензия
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