Device MCP Server
A comprehensive MCP server for network device management via SSH/Telnet. Supports multiple vendors such as Cisco IOS and BDCOM, enabling AI assistants to execute commands and manage routers, switches, and firewalls.
README
Device MCP Server
English
A comprehensive MCP (Model Context Protocol) server for network device management via SSH/Telnet. Execute commands and manage routers, switches, and firewalls through AI assistants like Claude and Amazon Q. Works with Cisco IOS, BDCOM, and any other netmiko-supported platform.
✨ Features
- 🔌 Dual Protocol Support: Connect via SSH or Telnet
- 🧩 Multi-Vendor: Cisco IOS (default), BDCOM, and 400+ netmiko platforms via a
device_typeselector - 🔄 Persistent Connections: Maintain long-lived connections for efficient command execution
- 🎯 Universal Command Execution: Execute any device command through a single interface
- 🔐 Mode Management:
autodefault runs at the current privilege level without downgrading;user/enable/configforce a level - 🧾 Self-describing results: every command returns its raw output plus a
[device-mcp]footer reporting device errors (vs transport failures) and where the CLI ended up — see Result footer - 🧱 Batch Config:
configure_deviceapplies an ordered command list atomically, handles sub-mode nesting, and reports the exact line that failed - 🌐 Multi-Device Support: Manage many devices at once — including several behind one IP on different ports (console/terminal servers), addressed as
host:port - ✅ Interactive Confirmations: Answer
(y/n)/[confirm]prompts (e.g.reboot,delete startup-config) viaexpect_string+answer - 📜 Console Diagnostics: Per-connection raw I/O history (
get_console_history) and live stream reads (read_console_stream) for auditing logins, desyncs, and reboots - ❓ Inline Help: Query CLI
?help withget_help(parsedoptions:footer) - 🤖 AI-Friendly: Natural language command translation through AI assistants
- 📊 Connection Monitoring: Track active connections and their status
Implementation: Python / FastMCP server. SSH/Telnet transport is handled by netmiko, which is purpose-built for network devices (robust prompt detection, paging, and user/enable/config mode handling). BDCOM uses a small custom driver — see BDCOM notes.
🚀 Quick Start
-
Clone and Install
git clone https://github.com/very99/cisco-mcp.git device-mcp cd device-mcp python -m venv .venv # Windows: .venv\Scripts\activate # macOS/Linux: source .venv/bin/activate pip install -e . # or: pip install -r requirements.txt -
Run / Verify
python -m device_mcp.server # serves over stdio -
Configure MCP Client
Add to your MCP configuration (e.g., Claude Desktop). Use the Python interpreter from the virtual environment you created above:
{ "mcpServers": { "device-mcp": { "command": "/path/to/device-mcp/.venv/bin/python", "args": ["-m", "device_mcp.server"] } } }On Windows, use
\path\to\device-mcp\.venv\Scripts\python.exe. If you installed the package (pip install -e .), you can instead pointcommandat the generateddevice-mcpexecutable with noargs.
🛠 Available Tools
connect_device
Establish a connection to a network device.
Parameters:
host(required): IP address or hostnameusername(optional): Authentication username (omit for unsecured consoles)password(optional): Authentication password (omit for unsecured consoles)device_type(optional):cisco_ios(default),bdcom, or any netmiko device typeprotocol(optional):sshortelnet(default:ssh)port(optional): Custom port number (default 22 SSH / 23 Telnet). The connection is keyed byhost:port, so several devices behind one IP stay independent.enable_password(optional): Enable password for privileged mode. Many devices (e.g. BDCOM withaaa authentication enable default none) need none — leave it unset andenablemode still works.
Example (Cisco):
{
"host": "192.168.1.1",
"username": "admin",
"password": "password123",
"device_type": "cisco_ios",
"protocol": "ssh",
"enable_password": "enable123"
}
Example (BDCOM):
{
"host": "192.168.1.2",
"username": "admin",
"password": "password123",
"device_type": "bdcom",
"enable_password": "enable123"
}
execute_command
Execute a command on a connected device. Returns the raw command output plus a
one-line [device-mcp] footer reporting any device error and where the CLI ended
up (see Result footer).
Parameters:
host(required): Target device IP/hostnamecommand(required): Command to executemode(optional):auto(default),user,enable, orconfig.autoruns at the current privilege level without downgrading (soshowworks on BDCOM, which connects in enable);user/enable/configforce that exact level. For multi-step config preferconfigure_device.expect_string(optional): Regex for an interactive confirmation promptanswer(optional): Reply to send whenexpect_stringmatchesport(optional): Required only when several devices share an IP
Example:
{
"host": "192.168.1.1",
"command": "show version"
}
Interactive example (BDCOM reboot):
{
"host": "192.168.100.34",
"port": 10003,
"command": "reboot",
"mode": "enable",
"expect_string": "\\(y/n\\)",
"answer": "y"
}
configure_device
Apply a sequence of configuration commands as one block. Enters config mode, sends
each command in order (handling sub-mode prompt changes like
Switch_config_vlan30#), then exits config mode. If a command is rejected, the
footer reports which one failed and where the session was left — no partial
config applied silently.
Parameters:
host(required): Target device IP/hostnamecommands(required): Ordered list of config commands. Send a sub-modeexitas its own list item when moving between contexts. A trailing;is not a separator.port(optional): Required only when several devices share an IP
Example (BDCOM VLAN + access port):
{
"host": "192.168.100.34",
"port": 10003,
"commands": [
"vlan 30", "exit",
"interface GigaEthernet0/1",
"switchport mode access", "switchport pvid 30", "exit"
]
}
disconnect_device
Disconnect from a device.
Parameters:
host(required): Device IP/hostname to disconnectport(optional): Required only when several devices share an IP
list_connections
List all active connections (target = host:port, host, port, device_type,
protocol, current mode, timestamps).
get_console_history
Return the last N lines of raw console I/O captured for a connection — useful for auditing logins, prompt-matching failures, and reboots.
Parameters: host (required), limit (optional, default 100), port (optional).
⚠️ History can contain sensitive output (e.g. a config dump exposes plaintext credentials). Treat it as sensitive.
read_console_stream
Read live console output without sending a command — accumulates whatever the device emits until a pattern matches or the timeout elapses. Handy for watching a device reboot back to its login prompt.
Parameters: host (required), expect_pattern (optional regex),
timeout (optional seconds, default 10, capped at 120), port (optional).
get_help
Send command_prefix + '?' and return the device's inline CLI help, then clear the
input line so the next command runs cleanly. The footer lists the parsed next-token
options: (or flags an invalid prefix). The prefix is normalized (a stray trailing
? is dropped, multiple trailing spaces collapse to one), and long lists like
ip ? are no longer truncated.
Parameters: host (required), command_prefix (optional, e.g. "show "),
port (optional).
🧾 Result footer
execute_command, configure_device, and get_help append one compact status
line so the model never has to guess session state:
<raw command output>
[device-mcp] ok | now: Switch# (enable)
[device-mcp] device error: Unknown command near 'status' | now: Switch# (enable)
[device-mcp] FAILED: <transport exception> | now: <prompt|unknown>
[device-mcp] options: interface, ip, ipv6 | now: Switch_config# (config)
- device error — the device rejected the command (with the offending token
when it prints a
^caret); distinct from a FAILED transport error (e.g. a prompt-detection desync — reconnect). - now — the current prompt and derived mode (
user/enable/config), so the model knows where a sub-mode (e.g.Switch_config_vlan30#) left it.
💡 Usage Examples
Basic Device Information
AI: "Connect to router 192.168.1.1 and show me the device information"
The AI will:
- Use
connect_deviceto establish connection - Use
execute_commandwith "show version"
Interface Configuration
AI: "Configure interface GigabitEthernet0/1 with IP 10.1.1.1/24"
The AI will:
- Use
execute_commandwith mode "config" - Execute: "interface GigabitEthernet0/1"
- Execute: "ip address 10.1.1.1 255.255.255.0"
Network Troubleshooting
AI: "Check the routing table and interface status on the core switch"
The AI will execute multiple commands:
- "show ip route"
- "show ip interface brief"
- "show interface status"
Multiple devices behind one console server
When a terminal/console server exposes several devices on one IP at different
ports, connect to each with its port, then address tools by host + port:
connect_device host=192.168.100.34 port=10003 device_type=bdcom protocol=telnet
connect_device host=192.168.100.34 port=10004 device_type=bdcom protocol=telnet
execute_command host=192.168.100.34 port=10003 command="show version"
list_connections shows each as a distinct target (192.168.100.34:10003,
192.168.100.34:10004). If a host has only one connection, port can be omitted.
🔧 Supported Commands
This server is a generic command executor — it forwards any command the device accepts. Cisco IOS and BDCOM share most of the common CLI:
| Category | Examples |
|---|---|
| Show | show version, show running-config, show ip interface brief, show ip route, show vlan brief, show mac address-table |
| Config | interface <if>, ip address <ip> <mask>, no shutdown, vlan <id>, router ospf <id> |
| Diagnostic | ping <dest>, traceroute <dest>, show tech-support |
📟 BDCOM notes
netmiko has no built-in BDCOM driver, so this server ships a small custom one
(device_mcp/bdcom.py) that adapts BDCOM's Cisco-IOS-like
CLI. The differences it handles (verified against the BDCOM Switch L3 docs):
| Aspect | Cisco IOS | BDCOM | Handled by |
|---|---|---|---|
| Enter global config | configure terminal |
config |
custom driver |
| Config prompt | host(config)# |
Switch_config# (no parens) |
custom driver |
| Exit config | end |
Ctrl-Z (device doesn't echo it) | custom driver |
| Exit privileged | disable |
exit (Switch# → Switch>) |
custom driver |
| Set terminal width | terminal width 511 |
(unsupported) | custom driver (skipped) |
| Disable paging | terminal length 0 (any mode) |
terminal length 0 (enable mode only) |
custom driver (in enable mode) |
| Enter enable | enable (+secret) |
enable (often no secret) |
inherited |
Select it per connection with "device_type": "bdcom" (or protocol: "telnet"
for Telnet). Mode names (user / enable / config) map to BDCOM's user /
management / global-configuration modes.
Why a custom session setup: BDCOM rejects terminal width and only accepts
terminal length 0 (disable paging) in privileged mode. netmiko's stock Cisco
setup runs both at login in user mode, which fails and leaves paging on — so
the next large show stalls on --More-- and desyncs the session. The BDCOM
driver instead enters enable mode and disables paging there.
Field tips (from real-hardware testing):
- Use
device_type: "bdcom"for BDCOM switches — required for config-mode ops. enableneeds no password on a default BDCOM (aaa authentication enable default none); just omitenable_password.- A config dump exposes plaintext credentials — treat
show running-configoutput (andget_console_history) as sensitive. - If a session ever desyncs,
disconnect_devicethenconnect_devicefor a clean one rather than retrying the failing command.
BDCOM CLI cheat-sheet (commands the server can't enforce)
The server is a generic executor, so these BDCOM-specific rules are on the caller
(the footer's device error will tell you when one is violated):
- Access-port VLAN: there is no Cisco
switchport access vlan <id>. Useswitchport mode accessthenswitchport pvid <id>. - VRF needs an RD first: after
ip vrf <name>/ipv6 vrf <name>, setrd <a>:<b>before referencing the VRF anywhere (vrf forwarding, routes) — otherwise:%Err, VRF '<n>' does not exist or does not have a RD. - Order around VRF on an SVI: setting
vrf forwarding/ipv6 vrf forwardingon an interface clears its existing IP/IPv6 addresses. Set the VRF first, then (re-)apply the addresses. - Sub-modes don't auto-exit:
vlan X,interface X,ip vrf Xeach open a sub-mode; send an explicitexitbetween contexts — or just useconfigure_devicewith theexitlines in the list. - Privileged for
show: BDCOMshowneeds enable mode; the defaultautomode keeps you there after connect, so nomodeis needed.
🔒 Security Notes
- This tool is designed for network automation and management
- Credentials are passed per connection and not stored
- Use appropriate network security practices
- Consider using SSH keys for enhanced security (future enhancement)
🏗 Architecture
AI Assistant (Claude/Amazon Q)
↓ Natural Language
MCP Client
↓ Tool Calls
Device MCP Server ── netmiko (cisco_ios) / custom driver (bdcom)
↓ SSH/Telnet
Network Devices (Routers/Switches/Firewalls)
🤝 Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📝 License
This project is licensed under the MIT License - see the LICENSE file for details.
中文
一个全面的MCP(模型上下文协议)服务器,用于通过SSH/Telnet管理网络设备。通过Claude和Amazon Q等AI助手执行命令并管理路由器、交换机和防火墙。支持Cisco IOS、BDCOM以及任何 netmiko 支持的平台。
✨ 功能特性
- 🔌 双协议支持: 支持SSH或Telnet连接
- 🧩 多厂商支持: 通过
device_type选择 Cisco IOS(默认)、BDCOM 以及 400+ netmiko 平台 - 🔄 持久连接: 维护长连接以实现高效的命令执行
- 🎯 通用命令执行: 通过单一接口执行任何设备命令
- 🔐 模式管理: 自动在用户、特权和配置模式之间切换
- 🌐 多设备支持: 同时管理多个设备
- 🤖 AI友好: 通过AI助手进行自然语言命令转换
- 📊 连接监控: 跟踪活动连接及其状态
🚀 快速开始
-
克隆并安装
git clone https://github.com/very99/cisco-mcp.git device-mcp cd device-mcp python -m venv .venv # Windows: .venv\Scripts\activate # macOS/Linux: source .venv/bin/activate pip install -e . # 或: pip install -r requirements.txt -
运行 / 验证
python -m device_mcp.server # 通过 stdio 提供服务 -
配置MCP客户端
添加到您的MCP配置中(例如Claude Desktop),使用上面创建的虚拟环境中的 Python 解释器:
{ "mcpServers": { "device-mcp": { "command": "/path/to/device-mcp/.venv/bin/python", "args": ["-m", "device_mcp.server"] } } }Windows 请使用
\path\to\device-mcp\.venv\Scripts\python.exe。
🛠 可用工具
连接以 host:port 为键,因此同一 IP、不同端口的多台设备(控制台/终端服务器)互不影响;
当某主机只有一个连接时,工具的 port 参数可省略。
connect_device
建立到网络设备的连接(参数 device_type 选择平台:cisco_ios 默认 / bdcom / 任意 netmiko 类型)。
username / password 可选(用于无认证的控制台);默认 BDCOM 进入 enable 无需密码。
execute_command
在已连接的设备上执行命令。mode 默认 auto(在当前权限级别执行、不降级;BDCOM 连接后处于
enable,因此 show 可直接工作),也可强制 user/enable/config。返回原始输出加一行
[device-mcp] footer(报告设备错误与当前提示符/模式)。支持 expect_string + answer
应答交互式 (y/n) 确认;port 仅在同一 IP 有多台设备时需要。
configure_device
按顺序批量下发配置命令(自动进出配置模式,处理子模式提示符变化)。在上下文之间用单独的
exit 列表项切换;若某条命令被拒绝,footer 会指出是哪一条以及会话停在何处。
disconnect_device
断开与设备的连接(同一 IP 多设备时需指定 port)。
list_connections
列出所有活动连接(含 target = host:port)。
get_console_history
返回某连接最近 N 行原始控制台 I/O,用于审计登录、提示符不匹配和重启。可能包含明文凭据,请按敏感数据处理。
read_console_stream
不发送命令,直接读取实时控制台输出,直到匹配正则或超时(适合观察设备重启回到登录提示符)。
get_help
发送 command_prefix + '?' 返回设备的内联 CLI 帮助,并清理输入行;footer 列出解析出的
下一级 options:。会归一化前缀(去掉手动多写的 ?、合并多余尾随空格),长列表(如 ip ?)
不再被截断。
📟 BDCOM 说明
netmiko 没有内置 BDCOM 驱动,本服务器提供了一个小型自定义驱动
(device_mcp/bdcom.py)来适配 BDCOM 的 CLI:进入全局配置用
config(而非 configure terminal),配置提示符为 Switch_config#(无括号),用
Ctrl-Z 退出配置模式,特权模式用 exit 退出。BDCOM 不支持 terminal width,且
terminal length 0(关闭分页)仅在特权模式可用——因此驱动会先进入 enable 模式再关闭分页,
避免大输出在 --More-- 处卡住导致会话错乱。默认 BDCOM enable 无需密码。连接时设置
"device_type": "bdcom" 即可。
BDCOM CLI 速查(服务器无法强制,需调用方遵循):
- 接入口 VLAN 用
switchport mode access+switchport pvid <id>(没有switchport access vlan)。 - VRF 必须先在
ip vrf/ipv6 vrf内设置rd a:b再被引用,否则报does not have a RD。 - 在接口上设置
vrf forwarding会清除其已配置的 IP/IPv6 地址——先设 VRF,再配地址。 - 子模式(
vlan/interface/ip vrf)不会自动退出,上下文之间需exit,或用configure_device。
📝 许可证
本项目采用MIT许可证 - 详见LICENSE文件。
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.