pyATS MCP Server
pyATS MCP Server
Cisco pyATS 和 Genie 本来就知道如何与网络对话——解析 show 命令、推送配置、学习功能状态、运行声明式测试。它们缺少的是一种让 AI 代理直接驱动其中任何功能的方式。这个服务器填补了这一空白:它将 pyATS/Genie 封装为一组结构化、带防护的 MCP 工具,像 Claude 这样的代理可以通过 Model Context Protocol 当前的 Streamable HTTP 传输,针对真实测试床调用这些工具。
把代理指向它,它就能查找设备、运行并解析 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中,运行时通过%ENV{}替换拉入testbed.yaml。
Related MCP server: network-mcp
前提条件
Python 3.10+
一个指向真实或虚拟网络设备的 pyATS
testbed.yaml——物理实验室、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.pyMCP 端点随后可通过 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 在 Streamable HTTP 传输上设置 stateless_http=True,因此对于仍在协商旧版基于握手的协议的客户端,服务器不会在请求之间保留任何服务端会话状态。使用当前 MCP 协议(2026-07-28、SEP-2575)的客户端默认无需握手,无论此设置如何——这来自 mcp>=2.0.0 SDK 本身,而非此处配置的任何内容。
3. 为每台设备添加一个块
testbed.yaml 中的每台设备都使用 %ENV{VAR} 替换,因此凭据和连接详情在运行时从 .env 读取。
使用 {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)如果一组设备共享凭据,请定义组级变量并在各设备中引用它们:
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}",并在.env中设置DEVICE_OS=generic, 可选地在arguments:下添加learn_os: true——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无论哪种方式,服务器都是一个长期运行的进程,你启动一次后让客户端指向它——它不是代理每次会话都会生成的东西。有关每个客户端如何连接它的详细信息,请参见下文。
连接你的代理
服务器只暴露一件事:位于 http://<host>:<port>/mcp 的 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 的 claude_desktop_config.json 仅支持 stdio——在其中放入 url 字段不起作用(这是一个已知问题,不是受支持的路径)。远程/HTTP 服务器改为在设置 → 连接器下作为自定义连接器添加,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"显示 CORE1 上的 BGP 摘要" →
pyats_run_show_command,解析为结构化 JSON"快照 CORE1 的 OSPF 状态,然后应用此配置并显示变更内容" →
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"对 R1 和 R2 运行此 Blitz 测试" / "运行此 Robot Framework 套件" →
pyats_run_blitz/pyats_run_robot
代理会自行串联这些工具——你描述期望的结果,它选择工具。
可用工具
26 个工具,按功能分组。
发现
工具 | 描述 |
| 列出测试床中的所有设备 |
| 按名称或别名模糊搜索设备 |
Show 命令
工具 | 描述 |
| 运行经过验证的 show 命令;返回解析后的 JSON 或原始输出 |
| 跨多台设备并发运行 show 命令(线程池) |
| 相同,但每台设备一个操作系统进程( |
| 检索完整运行配置(原始文本) |
| 通过 |
| 从网络设备执行 ping |
| 在 Linux 主机上运行命令 |
配置
工具 | 描述 |
| 在安全防护栏下应用配置命令 |
| 跨多台设备并发应用配置(线程池) |
| 相同,但每台设备一个操作系统进程 |
| 应用配置并返回变更前后的差异 |
| 回滚到上次保存的配置快照 |
状态与诊断
工具 | 描述 |
| 快照 CPU、内存、接口和路由状态 |
| 检索 CDP/LLDP 邻居 |
| 查找哪个接口拥有给定的 IP 地址 |
| Genie |
| 对比由 |
测试与自动化
工具 | 描述 |
| Genie Clean(Kleenex),限制为非破坏性的 |
| 运行声明式 pyATS Blitz YAML 测试 |
| 使用 |
| 执行沙箱化的 pyATS AEtest 脚本 |
API
工具 | 描述 |
| 通过 pyATS 的 |
| 对 Cisco XPresso 的 REST API v2 进行经过身份验证的调用(测试请求、作业、测试床、镜像等) |
会话
工具 | 描述 |
| 检索内存中的操作日志 |
安全
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;真正运行还需要一个精确的确认短语。每个进程级缓存(连接缓存、testbed 缓存、config/learn 快照、操作日志)都由锁保护,因此并发的 HTTP 客户端无法破坏共享状态。
所有凭据都来自
.env— 绝不存储在 testbed 文件或源代码中。
项目结构
.
├── 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 针对真实 testbed 进行比较。场景列表请参阅 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