Token导航 LogoToken导航TokenDH.com
Junos MCP Server logo
AI代理stdio官方级别未说明来源级核验

Junos MCP Server

MCP Server

为Juniper Junos设备提供基于LLM的交互协议服务器,支持网络配置管理、动态设备添加和安全操作。

工具数

7

提示词数

0

GitHub Stars

93

资源数

0
配置管理PythonClaudeClaude DesktopClaude

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

Juniper

提供方

Juniper

最后核验

2026/5/17 20:22

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

命令预览

pip install -r requirements.txt

详细介绍

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 port

Junos 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 工具,它将交互式地询问:

  1. 设备名称:设备的唯一标识符(例如“router1 east”)
  2. IP地址:设备的IP地址
  3. SSH端口:SSH端口(默认为22)
  4. 用户名:用于身份验证的用户名
  5. SSH密钥路径:MCP服务器上SSH私钥文件的路径

该工具验证每个输入:

  • 设备名称必须唯一
  • IP地址必须有效
  • SSH密钥文件必须存在并且可读
  • 添加设备前的可选连接测试

安全说明

add_device 工具 仅支持SSH密钥身份验证.密码 出于安全原因和VSCode的 启发UI没有正确屏蔽密码字段。

示例用法

在使用GitHub Copilot的VSCode中:

@jmcp Please add a new device to the MCP server

然后,该工具将指导您完成整个过程:

  1. 输入设备名称: vsrx-lab1
  2. 输入IP地址: 10.0.1.100
  3. 输入SSH端口: 22 (默认情况下按Enter键)
  4. 输入用户名: admin
  5. 输入SSH密钥路径: /home/user/.ssh/junos_key.pem
  6. 确认并可选择测试连接

成功添加后,该设备可立即用于所有 其他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

安全最佳实践

  1. 令牌安全:

- 安全地存储令牌(密码管理器、环境变量) - 使用描述性令牌ID便于管理 - 通过撤销旧令牌并生成新令牌来定期轮换令牌 - 从不将令牌提交到版本控制

  1. 访问控制:

- 为不同的客户端/环境生成单独的令牌 - 不再需要时立即撤销代币 - 监控服务器日志以防止未经授权的访问尝试

  1. 网络安全:

- 在生产环境中使用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_commandexecute_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能够 与瞻博网络设备交互。服务器架构由以下部分组成:

  1. MCP服务器核心 (jmcp.py):处理MCP协议通信
  2. 工具操作员:实现特定网络的单个功能

运营

  1. 工具注册表:将工具名称映射到其处理程序函数
  2. 传输层:支持stdio(克劳德桌面)和可流式传输的http

(VSCode)

工具如何工作

MCP服务器中的每个工具都遵循以下流程:

MCP Tool Flow

添加新工具

添加新工具是一个简单的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尚不支持启发式。

工具开发的最佳实践

  1. 错误处理:始终处理连接错误和无效输入

优雅地

  1. 日志记录:使用全局 log 调试记录器
  2. 验证:在尝试操作之前检查路由器是否存在
  3. 文档:为工具和参数编写清晰的描述
  4. 超时:支持长时间运行操作的可配置超时
  5. 返回格式:始终返回 list[types.ContentBlock] 包含文本内容
  6. 引出:在需要时使用启发进行交互式数据收集
  7. 上下文参数:包括 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)]

测试您的工具

  1. 单元测试:使用模拟参数测试处理程序函数
  2. 集成测试:使用实际的Junos设备或vSRX进行测试
  3. 错误案例:使用无效路由器、网络故障等进行测试。

示例测试:

# Test the handler directly
result = await handle_my_new_tool({
    "router_name": "router-1",
    "my_param": "test"
})
print(result[0].text)

调试提示

  1. 启用调试日志记录以查看详细执行情况:
 logging.basicConfig(level=logging.DEBUG)
  1. 使用stdio传输更容易调试:
 python jmcp.py -f devices.json -t stdio
  1. 手动测试单个命令:
 result = _run_junos_cli_command("router-1", "show version")
 print(result)

目录标签

目录标签

配置管理PythonClaude网络自动化本地部署LLM集成Junos管理SSH认证

支持客户端

Claude DesktopClaude

接入字段

传输方式(transport,传输协议)

stdio

鉴权方式(authType,认证方式)

token

工具数量(toolCount,工具数)

7

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

stdiotoken部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

来源信息

继续浏览同类 MCP