junos mcp服务器
Juniper Junos设备的模型上下文协议(MCP)服务器,支持 LLM与网络设备的交互。
目录
- 目录 - 重要安全通知 - 安全要求 - 安全最佳实践 - 重要配置通知 - 入门指南 - 用紫外线跑步 - 启动Junos MCP服务器 - 配置 - 克劳德桌面配置(stdio传输) - 克劳德桌面配置(使用uv) - - - - 使用默认设置运行 - 覆盖默认参数 - Junos设备配置 - 基于启发式的动态设备管理 - 激励相容性通知 - 这 add_device 工具 - 运作原理 - 安全说明 - 示例用法 - SSH密钥要求 - 局限性 - - 启动服务器 - 在VSCode配置中指向此URL - MCP服务器访问的身份验证 - 身份验证行为 - 许可证管理 - 生成新令牌 - 列出所有代币 - 显示令牌值(恢复) - 撤销令牌 - 服务器身份验证状态 - 带身份验证的客户端配置 - 带令牌的VSCode配置 - 卷曲测试 - - 安全最佳实践 - 令牌文件格式 - 用于配置提交的护栏 - 用于执行操作命令的护栏 - 使用MCP服务器和Juniper云原生路由器(JCNR) - 开发者指南 - 架构概述 - 工具如何工作 - 添加新工具 - 步骤1:创建处理程序函数 - 步骤2:注册处理程序 - 步骤3:定义工具元数据 - 示例:创建BGP邻居工具 - 在工具中使用启发式 - 工具开发的最佳实践 - 使用PyEZ进行高级操作 - 测试您的工具 - 调试提示
重要安全通知
警告: 此服务器允许LLM访问您的网络基础设施。请仔细查看这些安全注意事项。
安全要求
- 公司政策合规性:仅当贵公司的
策略允许将Junos设备的数据发送到LLM服务。
- 服务器安全:在部署之前,始终保护您的Junos MCP服务器
生产环境。
- 认证:做 不 使用密码身份验证进行生产
部署。我们强烈建议使用基于SSH密钥的身份验证 增强安全性。
- 部署策略:在您的MCP服务器得到适当保护之前,只有
出于测试目的在本地部署。不要在生产环境中部署远程服务器 没有适当的安全措施。
安全最佳实践
- 使用SSH密钥身份验证而不是密码
- 实施适当的网络访问控制
- 监控并记录所有MCP服务器活动
- 定期安全审计和更新
- 遵循组织的安全策略
重要配置通知
警告: Junos MCP服务器支持配置更改,但请确保仅在您希望在Junos路由器上加载和提交LLM生成的配置时使用此功能。
始终检查LLM生成的配置,只允许使用工具 如果它是您用例的正确配置,则执行。
入门指南
获取代码。
git clone https://github.com/Juniper/junos-mcp-server.git
cd junos-mcp-server
pip install -r requirements.txt用紫外线跑步
如果你正在使用 紫外线,您可以直接运行服务器:
uv run python jmcp.py -f devices.json -t stdio启动Junos MCP服务器
python3.11 jmcp.py --help
Junos MCP Server
options:
-h, --help show this help message and exit
-f DEVICE_MAPPING, --device-mapping DEVICE_MAPPING
the name of the JSON file containing the device mapping
-H HOST, --host HOST Junos MCP Server host
-t TRANSPORT, --transport TRANSPORT
Junos MCP Server transport
-p PORT, --port PORT Junos MCP Server portJunos MCP服务器支持流式http和stdio传输。不要使用 --具有stdio传输的主机。
环境变量
JUNOS_TIMEOUT:Junos CLI操作的命令超时(秒)。JMCP_STATELESS:控制可流式传输的http会话模式。
- 违约: false (有状态会话,启发工作流所需,如 add_device). - 接受的真实值: 1, true, yes, y, on - 接受的错误值: 0, false, no, n, off
配置
克劳德桌面配置(stdio传输)
{
"mcpServers": {
"jmcp": {
"type": "stdio",
"command": "python3",
"args": ["jmcp.py", "-f", "devices.json", "-t", "stdio"]
}
}
}克劳德桌面配置(使用uv)
{
"mcpServers": {
"jmcp": {
"type": "stdio",
"command": "uv",
"args": ["run", "python", "jmcp.py", "-f", "devices.json", "-t", "stdio"]
}
}
}注: 请提供jmcp.py和devices.json文件的绝对路径。
Claude桌面配置(Docker容器)
{
"mcpServers": {
"jmcp": {
"type": "stdio",
"command": "/usr/local/bin/docker",
"args": [
"run",
"--rm",
"-i",
"-v",
"devices.json:/app/config/devices.json",
"-v",
"vsrx_keypair.pem:/app/config/vsrx_keypair.pem",
"junos-mcp-server:latest"
]
}
}
}Docker使用
构建Docker容器
docker build -t junos-mcp-server:latest .使用默认设置运行
默认情况下,Docker容器使用stdio传输运行:
docker run --rm -it -v /path/to/your/devices.json:/app/config/devices.json
junos-mcp-server:latest这将使用默认命令: python jmcp.py -f /app/config/devices.json -t stdio
覆盖默认参数
您可以通过指定完整命令来覆盖任何参数:
对于stdio传输:
docker run --rm -it -v /path/to/your/devices.json:/app/config/devices.json
junos-mcp-server:latest python jmcp.py -f /app/config/devices.json -t stdio对于可流式传输的http:
docker run --rm -it -v /path/to/your/devices.json:/app/config/devices.json -p
30030:30030 junos-mcp-server:latest python jmcp.py -f /app/config/devices.json
-t streamable-http -H 0.0.0.0对于无状态模式下的可流式传输http:
$ docker run --rm -it -e JMCP_STATELESS=true -v /path/to/your/devices.json:/app/config/devices.json -p 30030:30030 junos-mcp-server:latest python jmcp.py -f /app/config/devices.json -t streamable-http -H 0.0.0.0对于具有自定义端口的可流式传输http:
docker run --rm -it -v /path/to/your/devices.json:/app/config/devices.json -p
8080:8080 junos-mcp-server:latest python jmcp.py -f /app/config/devices.json -t
streamable-http -p 8080 -H 0.0.0.0注:
- 始终使用以下方式装载设备配置文件
-v /path/to/you/ devices.json:/app/config/devices.json - 对于可流式传输的http,使用以下命令公开端口
-p host_port:container_port - 如果使用基于密钥的认证(例如。,
-v /path/to/key.pem:/app/config/key.pem)
为Junos MCP服务器构建docker容器
docker build -t junos-mcp-server:latest .注: 安装配置文件 devices.json 并挂载任何其他文件 我的情况是,我使用pem文件进行ssh-priv-key身份验证,所以我也 安装vsrx_keypair.cem
Junos设备配置
Junos MCP服务器同时支持这两种功能 password 基于身份验证以及 SSH key 基于 身份验证(参见前2个路由器配置\[router-1,router-2\])。
{
"router-1": {
"ip": "ip-addr",
"port": 22,
"username": "user",
"auth": {
"type": "password",
"password": "pwd"
}
},
"router-2": {
"ip": "ip-addr",
"port": 22,
"username": "user",
"auth": {
"type": "ssh_key",
"private_key_path": "/path/to/private/key.pem"
}
},
"router-3": {
"ip": "ip-addr",
"port": 22,
"username": "user",
"ssh_config": "~/.ssh/config_dc",
"auth": {
"type": "ssh_key",
"private_key_path": "/path/to/private/key.pem"
}
},
"router-4": {
"ip": "ip-addr",
"port": 22,
"username": "user",
"ssh_config": "/home/user/.ssh/config_jumphost",
"auth": {
"type": "password",
"password": "pwd"
}
}
}Junos MCP服务器还支持 ProxyCommand(见最后2个路由器) configs\[router-3,router-4\]),使您能够访问目标设备 通过支持的中间主机 netcat。当你 只能通过中间主机(jumphost)登录到目标设备。
这是一个正在使用SSH配置文件的示例 .ssh/config_jumphost:
# Jumphost VM Connection
Host jumphost-vm
HostName 10.2.11.200
User root
# Used for MCP server
IdentityFile /home/user/.ssh/id_rsa_claude
IdentitiesOnly yes
StrictHostKeyChecking no
# cRPD Devices (via jump host)
Host dt-crpd1 dtwin-crpd1 digital-twin-crpd1 clab-digital-twin-eop6-pe1
HostName 172.20.20.11
User claude
IdentityFile c
# ProxyJump jumphost-vm # Not working with JunOS MCP
ProxyCommand ssh -l root jumphost-vm nc %h 22 2>/dev/null
StrictHostKeyChecking no注1: Port 值应该是整数(通常 22 SSH)。
注2: IdentityFile 建议使用完整路径(例如 /home/user/.ssh /id_rsa_claude 而不是 ~/.ssh/id_rsa_claude).
基于启发式的动态设备管理
激励相容性通知
重要提示: 启发功能目前仅适用于 VSCode (使用流式http传输)。Claude Desktop尚不支持启发式,因此 add_device 该工具不适用于Claude Desktop。这 add_device 工具
Junos MCP服务器包括一个强大的 add_device 工具,让你 在不修改配置文件的情况下动态添加新的Junos设备。 此工具使用MCP的启发功能交互式收集设备 信息。
运作原理
当你使用 add_device 工具,它将交互式地询问:
- 设备名称:设备的唯一标识符(例如“router1 east”)
- IP地址:设备的IP地址
- SSH端口:SSH端口(默认为22)
- 用户名:用于身份验证的用户名
- SSH密钥路径:MCP服务器上SSH私钥文件的路径
该工具验证每个输入:
- 设备名称必须唯一
- IP地址必须有效
- SSH密钥文件必须存在并且可读
- 添加设备前的可选连接测试
安全说明
这 add_device 工具 仅支持SSH密钥身份验证.密码 出于安全原因和VSCode的 启发UI没有正确屏蔽密码字段。
示例用法
在使用GitHub Copilot的VSCode中:
@jmcp Please add a new device to the MCP server然后,该工具将指导您完成整个过程:
- 输入设备名称:
vsrx-lab1 - 输入IP地址:
10.0.1.100 - 输入SSH端口:
22(默认情况下按Enter键) - 输入用户名:
admin - 输入SSH密钥路径:
/home/user/.ssh/junos_key.pem - 确认并可选择测试连接
成功添加后,该设备可立即用于所有 其他Junos MCP工具。
SSH密钥要求
- SSH私钥文件必须存在于MCP服务器文件系统上
- 运行MCP服务器的进程必须能够读取该文件
- 对于Docker部署,将SSH密钥文件挂载到容器中
Docker挂载示例:
docker run --rm -it \
-v /path/to/devices.json:/app/config/devices.json \
-v /path/to/ssh_key.pem:/app/config/ssh_key.pem \
-p 30030:30030 \
junos-mcp-server:latest \
python jmcp.py -f /app/config/devices.json -t streamable-http -H 0.0.0.0局限性
- 仅VSCode:Claude Desktop不支持引用
- 仅限SSH密钥:不支持密码身份验证
- 没有坚持:添加的设备仅存储在内存中;他们将
服务器重新启动时丢失
- 超时:用户有5分钟的时间对每个提示做出回应
对于Claude Desktop用户,设备仍必须在 devices.json 文件如所述 Junos设备配置 部分。
VSCode+GitHub副驾驶集成
启动服务器
python3.11 jmcp.py -f devices.json
[06/11/25 08:26:11] INFO Starting MCP server 'jmcp-server' with transport
'streamable-http' on http://127.0.0.1:30030/mcp
INFO: Started server process [33512]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:30030 (Press CTRL+C to quit)在VSCode配置中指向此URL
{
"mcp": {
"servers": {
"my-junos-mcp-server": {
"url": "http://127.0.0.1:30030/mcp/"
}
}
}
}注: 您可以使用VSCode Cmd+Shift+P 配置MCP服务器。
MCP服务器访问的身份验证
Junos MCP服务器支持基于令牌的安全客户端身份验证 使用流式http传输时的访问。这可以防止未经授权的访问 您的网络基础设施。
身份验证行为
- stdio传输 (Claude Desktop):无需身份验证-由
在本地运行时进行设计
- 可流式传输http (VSCode、web客户端):基于令牌
身份验证可用
许可证管理
服务器包括一个专用的令牌管理CLI工具: jmcp_token_manager.py
生成新令牌
# Basic token generation
python jmcp_token_manager.py generate --id "vscode-dev"
# With description
python jmcp_token_manager.py generate --id "vscode-dev" --description "VSCode
development environment"
# Example output:
Generated new token:
ID: vscode-dev
Token: jmcp_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8
Description: VSCode development environment
Save this token securely - it won't be shown again!列出所有代币
python jmcp_token_manager.py list
# Example output:
ID Description Created
-------------------------------------------------------------------------------------
vscode-dev VSCode development environment
2025-01-28T10:30:00Z
prod-client Production client access
2025-01-28T09:15:00Z显示令牌值(恢复)
python jmcp_token_manager.py show --id "vscode-dev"
# Example output:
Token ID: vscode-dev
Token: jmcp_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8
Description: VSCode development environment
Created: 2025-01-28T10:30:00Z撤销令牌
python jmcp_token_manager.py revoke --id "vscode-dev"
# Example output:
Token 'vscode-dev' has been revoked服务器身份验证状态
服务器根据以下内容自动检测并启用身份验证 代币的存在:
配置令牌后:
python jmcp.py -f devices.json -t streamable-http
INFO - Token-based authentication enabled
INFO - Clients must send 'Authorization: Bearer ' header
INFO - Use jmcp_token_manager.py to manage tokens
INFO - Streamable HTTP server started on http://127.0.0.1:30030未配置令牌:
python jmcp.py -f devices.json -t streamable-http
WARNING - No .tokens file found - server is open to all clients
INFO - Create tokens using: python jmcp_token_manager.py generate --id
INFO - Streamable HTTP server started on http://127.0.0.1:30030带身份验证的客户端配置
带令牌的VSCode配置
{
"mcp": {
"servers": {
"my-junos-mcp-server": {
"url": "http://127.0.0.1:30030/mcp/",
"headers": {
"Authorization": "Bearer
jmcp_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8"
}
}
}
}
}卷曲测试
# Test authentication with valid token
curl -X POST "http://127.0.0.1:30030/mcp/" \
-H "Authorization: Bearer jmcp_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
# Test without token (should fail with 401)
curl -X POST "http://127.0.0.1:30030/mcp/" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'注: MCP流式http需要 Accept: application/json, tex /event-stream 头球
带身份验证的Docker
使用Docker时,挂载 .tokens 文件以启用身份验证:
# Generate token first (outside container)
python jmcp_token_manager.py generate --id "docker-client"
# Run container with token file mounted
docker run --rm -it \
-v /path/to/devices.json:/app/config/devices.json \
-v /path/to/.tokens:/app/.tokens \
-p 30030:30030 \
junos-mcp-server:latest \
python jmcp.py -f /app/config/devices.json -t streamable-http -H 0.0.0.0安全最佳实践
- 令牌安全:
- 安全地存储令牌(密码管理器、环境变量) - 使用描述性令牌ID便于管理 - 通过撤销旧令牌并生成新令牌来定期轮换令牌 - 从不将令牌提交到版本控制
- 访问控制:
- 为不同的客户端/环境生成单独的令牌 - 不再需要时立即撤销代币 - 监控服务器日志以防止未经授权的访问尝试
- 网络安全:
- 在生产环境中使用HTTPS在反向代理后运行可流式传输的http服务器 - 使用防火墙规则限制对MCP服务器端口的访问 - 考虑远程客户端的VPN访问
令牌文件格式
这 .tokens 文件以JSON格式存储令牌:
{
"vscode-dev": {
"token": "jmcp_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8",
"description": "VSCode development environment",
"created": "2025-01-28T10:30:00Z"
},
"prod-client": {
"token": "jmcp_x9y8z7w6v5u4t3s2r1q0p9o8n7m6l5k4j3i2",
"description": "Production client access",
"created": "2025-01-28T09:15:00Z"
}
}重要:保护此文件的安全,不要将其提交给版本控制。
用于配置提交的护栏
这 load_and_commit_config 该工具现在包括一个预提交护栏检查,根据中的模式验证提交的候选配置 block.cfg 在尝试任何设备提交操作之前。
运作原理
- 中的每一行非注释
block.cfg被视为阻塞模式。 - 模式匹配是根据提交的规范化配置行完成的
config_text. - 模式支持正则表达式标记(例如匹配动态用户名)。
- 如果任何一行匹配,则请求被拒绝 未加载或提交任何配置.
示例 block.cfg
# Blocked configuration prefixes/patterns for load_and_commit_config
set system root-authentication
set system login user ([^ ]+) authentication这可以保护常见的高风险配置区域(例如,根身份验证或非托管的本地用户凭据更改)不被自动化提交。
用于执行操作命令的护栏
这 execute_junos_command 和 execute_junos_command_batch 工具现在包括命令护栏,使用 block.cmd.
运作原理
- 中的每一行非注释
block.cmd被视为正则表达式命令模式。 - 提交的命令在执行前会被规范化和检查。
- 如果命令与阻塞模式匹配,则拒绝执行。
- 对于批处理执行,被阻止的命令在发送到路由器之前会被拒绝。
示例 block.cmd
# Blocked operational command prefixes/patterns for execute_junos_command
request system reboot
request system halt
request system power-cycle
request system power-off
request system zeroize这会阻止破坏性命令(重新启动/电源/归零类操作),同时仍允许只读操作显示命令。
使用MCP服务器和Juniper云原生路由器(JCNR)
JCNR是一个在各种云环境中运行的云原生路由器。一个可以 按照以下步骤将此MCP服务器与JCNR一起使用。 有关配置的更多详细信息,请参阅JCNR文档。
- 在JCNR中的22以外的所需端口上配置SSH访问。这是
之所以需要,是因为JCNR在共享操作系统上作为容器运行。跑步 不建议在默认端口上使用SSH。默认情况下,SSH在端口24上启用。 但是,最好将其更改为所需的端口,具体取决于您的 网络需求。
- 启用SSH的身份验证方法。JCNR支持SSH密钥和密码
基于身份验证。
- 通过SSH启用Netconf。默认情况下,这是启用的。
set system services netconf ssh
set system services ssh port 3030
set system services ssh root-login allow
set system root-authentication encrypted-password
"$6$3vvMI$RNemhmu9izWXzO46msh38frIg4VoeFNJWJZugxgnU.NQso3OQ00QWOIZmzNePD.MWjDOD
BBEYut/W7kfADdV." (or)
set system root-authentication load-key-file
开发者指南
本节介绍Junos MCP服务器的架构以及如何 用新工具扩展它。
架构概述
Junos MCP服务器使用模型上下文协议(MCP)使LLM能够 与瞻博网络设备交互。服务器架构由以下部分组成:
- MCP服务器核心 (
jmcp.py):处理MCP协议通信 - 工具操作员:实现特定网络的单个功能
运营
- 工具注册表:将工具名称映射到其处理程序函数
- 传输层:支持stdio(克劳德桌面)和可流式传输的http
(VSCode)
工具如何工作
MCP服务器中的每个工具都遵循以下流程:
添加新工具
添加新工具是一个简单的3步过程:
步骤1:创建处理程序函数
在中创建异步处理程序函数 jmcp.py (之前 TOOL_HANDLERS 字典):
async def handle_my_new_tool(arguments: dict) -> list[types.ContentBlock]:
"""Handler for my_new_tool - describe what it does"""
# Extract arguments
router_name = arguments.get("router_name", "")
my_param = arguments.get("my_param", "default_value")
# Validate router exists
if router_name not in devices:
result = f"Router {router_name} not found in the device mapping."
else:
# Your tool logic here
log.debug(f"Executing my_new_tool on router {router_name}")
result = _run_junos_cli_command(router_name, f"show {my_param}")
return [types.TextContent(type="text", text=result)]步骤2:注册处理程序
将您的处理程序添加到 TOOL_HANDLERS 字典(第330行附近):
TOOL_HANDLERS = {
"execute_junos_command": handle_execute_junos_command,
"get_junos_config": handle_get_junos_config,
"junos_config_diff": handle_junos_config_diff,
"gather_device_facts": handle_gather_device_facts,
"get_router_list": handle_get_router_list,
"load_and_commit_config": handle_load_and_commit_config,
"add_device": handle_add_device, # Dynamic device management with
elicitation
"my_new_tool": handle_my_new_tool, # Add your tool here
}步骤3:定义工具元数据
将工具定义添加到 list_tools() 方法(围绕410线):
types.Tool(
name="my_new_tool",
description="Brief description of what your tool does",
inputSchema={
"type": "object",
"properties": {
"router_name": {"type": "string", "description": "The name of the
router"},
"my_param": {"type": "string", "description": "Description of
parameter"}
},
"required": ["router_name"] # List required parameters
}
)示例:创建BGP邻居工具
以下是一个添加工具以显示BGP邻居的完整示例:
# Step 1: Handler function
async def handle_show_bgp_neighbors(arguments: dict) -> list[types.ContentBloc
]:
"""Handler for show_bgp_neighbors tool"""
router_name = arguments.get("router_name", "")
neighbor_address = arguments.get("neighbor_address", "")
if router_name not in devices:
result = f"Router {router_name} not found in the device mapping."
else:
log.debug(f"Getting BGP neighbors from router {router_name}")
if neighbor_address:
cmd = f"show bgp neighbor {neighbor_address}"
else:
cmd = "show bgp summary"
result = _run_junos_cli_command(router_name, cmd)
return [types.TextContent(type="text", text=result)]
# Step 2: Add to TOOL_HANDLERS
TOOL_HANDLERS = {
# ... existing tools ...
"show_bgp_neighbors": handle_show_bgp_neighbors,
}
# Step 3: Add to list_tools()
types.Tool(
name="show_bgp_neighbors",
description="Show BGP neighbor information",
inputSchema={
"type": "object",
"properties": {
"router_name": {"type": "string", "description": "The name of the
router"},
"neighbor_address": {"type": "string", "description": "Optional:
specific neighbor IP"}
},
"required": ["router_name"]
}
)在工具中使用启发式
MCP服务器支持交互式数据收集的启发。使用 工具中的启发:
from mcp.server.elicitation import ElicitationResult
from pydantic import BaseModel, Field
# Define elicitation schema
class MyInputSchema(BaseModel):
user_input: str = Field(description="Enter your input")
async def handle_my_elicitation_tool(arguments: dict, context: Context) -> list
[types.ContentBlock]:
"""Tool that uses elicitation to collect user input"""
# Use elicitation to ask for user input
result = await context.elicit(
message="Please provide the required input:",
schema=MyInputSchema
)
# Handle the result
match result:
case AcceptedElicitation(data=data):
user_input = data.user_input
# Process the input...
return [types.TextContent(type="text", text=f"Processing:
{user_input}")]
case DeclinedElicitation() | CancelledElicitation():
return [types.TextContent(type="text", text="Operation cancelled")]备注:Elicitation目前仅适用于VSCode(可流式传输http 运输)。Claude Desktop尚不支持启发式。
工具开发的最佳实践
- 错误处理:始终处理连接错误和无效输入
优雅地
- 日志记录:使用全局
log调试记录器 - 验证:在尝试操作之前检查路由器是否存在
- 文档:为工具和参数编写清晰的描述
- 超时:支持长时间运行操作的可配置超时
- 返回格式:始终返回
list[types.ContentBlock]包含文本内容 - 引出:在需要时使用启发进行交互式数据收集
- 上下文参数:包括
context: Context参数(如果使用)
引出
使用PyEZ进行高级操作
对于CLI命令之外的操作,直接使用PyEZ:
from jnpr.junos import Device
from jnpr.junos.utils.config import Config
# Example: Using PyEZ tables
async def handle_get_interfaces(arguments: dict) -> list[types.ContentBlock]:
router_name = arguments.get("router_name", "")
if router_name not in devices:
result = f"Router {router_name} not found in the device mapping."
else:
device_info = devices[router_name]
try:
connect_params = prepare_connection_params(device_info, router_name)
with Device(**connect_params) as junos_device:
# Use PyEZ tables or other utilities
interfaces = junos_device.rpc.get_interface_information()
# Process interfaces...
result = "Interface information..."
except Exception as e:
result = f"Error: {e}"
return [types.TextContent(type="text", text=result)]测试您的工具
- 单元测试:使用模拟参数测试处理程序函数
- 集成测试:使用实际的Junos设备或vSRX进行测试
- 错误案例:使用无效路由器、网络故障等进行测试。
示例测试:
# Test the handler directly
result = await handle_my_new_tool({
"router_name": "router-1",
"my_param": "test"
})
print(result[0].text)调试提示
- 启用调试日志记录以查看详细执行情况:
logging.basicConfig(level=logging.DEBUG)- 使用stdio传输更容易调试:
python jmcp.py -f devices.json -t stdio- 手动测试单个命令:
result = _run_junos_cli_command("router-1", "show version")
print(result)