Skip to main content
Glama

Netdisco MCP

将完整的 Netdisco REST API 转化为面向代理的 MCP 服务器

Python 3.11+ CI FastMCP MCP Docker License: MIT

81 个工具 · 动态 Swagger 发现 · stdio + Streamable HTTP · 引导优先的代理用户体验 · 持有者认证


Netdisco MCP 将实时 Netdisco 的 swagger.json 文档转化为一个完整、可搜索的 MCP 工具表面。它不维护一个脆弱的端点手写子集。启动时,它发现连接的 Netdisco 版本,将 Swagger 2.0 升级到 OpenAPI 3,修复模式不兼容,分配稳定的工具名称,并通过 FastMCP 发布每个支持的操作。

结果是一个 MCP 服务器,可以回答操作问题,检查设备和交换机端口,搜索节点和 VLAN,运行库存报告,并且——当显式启用时——提交或删除 Netdisco 作业。

[!IMPORTANT] 实时 API 是权威来源。当 Netdisco 添加端点时,工具数量可能增加。此 README 中的目录是 Netdisco 2.103000 的已验证快照。

目录

为什么存在这个项目

能力

含义

完整 API 覆盖

连接到的 Netdisco 实例所公布的每个操作都成为 MCP 工具。

版本感知

容器重启会重新加载实时规范并发现新端点。

代理优先的引导

get_guidance 故意是第一个工具,中间件会重定向跳过它的代理。

能力发现

find_capability 按名称、路由、标签、方法和描述进行搜索。

更安全的探索

只读模式在工具生成前移除 POST、PUT、PATCH 和 DELETE 操作。

上下文保护

过大的响应会被截断,并给出清晰的提示以缩小请求范围。

灵活传输

可在本地通过 stdio 运行,或通过 MCP Streamable HTTP 远程运行。

远程认证

Streamable HTTP 可以要求使用部署特定的持有者令牌。

容器加固

提供的 Compose 服务使用只读文件系统、no-new-privileges 且无主机端口。

架构

flowchart LR
    subgraph Clients["MCP clients"]
        ChatGPT["ChatGPT / OpenAI"]
        Codex["Codex"]
        ClaudeCode["Claude Code"]
        ClaudeDesktop["Claude Desktop"]
    end

    Proxy["TLS reverse proxy"]

    subgraph Server["Netdisco MCP"]
        Auth["Bearer authentication"]
        Guide["Guidance gate"]
        Catalog["FastMCP tool catalog"]
        Limit["Response limiter"]
        Adapter["Swagger 2 → OpenAPI 3 adapter"]
    end

    Spec["Netdisco swagger.json"]
    API["Netdisco REST API"]

    ChatGPT --> Proxy
    Codex --> Proxy
    ClaudeCode --> Proxy
    ClaudeDesktop --> Proxy
    Proxy --> Auth
    Auth --> Guide --> Catalog --> Limit
    Adapter --> Catalog
    Spec --> Adapter
    Catalog --> API

启动管道

sequenceDiagram
    participant S as Netdisco MCP
    participant N as Netdisco
    participant A as Swagger adapter
    participant F as FastMCP

    S->>N: GET /swagger.json
    N-->>S: Swagger 2.0 document
    S->>A: Normalize schemas and references
    A->>A: Assign stable operation IDs
    A->>A: Remove mutations when read-only
    A-->>S: OpenAPI 3.0.3 document
    S->>F: Generate and mount tools
    F-->>S: MCP server ready

高效的代理工作流

服务器故意对 AI 代理应如何处理网络管理任务持有一套意见。

flowchart TD
    Start["Start a Netdisco task"] --> Guidance["Call get_guidance"]
    Guidance --> Known{"Know the exact tool?"}
    Known -- No --> Find["Call find_capability"]
    Known -- Yes --> Read["Use search or object GET"]
    Find --> Read
    Read --> Evidence["Inspect current state"]
    Evidence --> Change{"Is a change required?"}
    Change -- No --> Report["Return evidence"]
    Change -- Yes --> Confirm["Confirm target and scope"]
    Confirm --> Mutate["Call mutation tool"]
    Mutate --> Verify["Read current state again"]
    Verify --> Report
  1. 在工作会话开始时调用一次 get_guidance

  2. 当正确工具不明确时,使用 find_capability

  3. 在广泛报告之前,优先使用搜索和对象工具。

  4. 在任何变更之前检查当前状态。

  5. 验证结果状态,而不是将超时解释为失败。

完整工具目录

已验证的 Netdisco 2.103000 表面包含:

类别

工具数

代理辅助

2

对象

31

报告

34

队列

5

搜索

4

用户

2

通用

3

总计

81

七个生成的 API 工具使用 POST、PUT 或 DELETE,被视为变更操作。设置 NETDISCO_READ_ONLY=1 可移除这七个工具。

[!CAUTION] Netdisco 暴露了 GET /logout,尽管使用了 HTTP GET,但它会销毁当前的 API 密钥和会话。基于方法的只读过滤无法将该端点归类为变更操作。请将 get_logout 视为破坏性操作。

代理辅助工具

工具

用途

get_guidance

返回捆绑的 Netdisco 操作指南,并可以高亮显示特定主题的章节。

find_capability

按任务、路由、标签、HTTP 方法或描述搜索完整的生成目录。

方法

工具

Netdisco 路由

用途

DELETE

delete_device_jobs

/api/v1/object/device/{ip}/jobs

删除设备作业并清除跳过列表,可选按字段过滤。

GET

get_device

/api/v1/object/device/{ip}

从设备表中返回一行。

GET

get_device_device_ips

/api/v1/object/device/{ip}/device_ips

返回设备的 device_ips 行。

GET

get_device_modules

/api/v1/object/device/{ip}/modules

返回设备的模块行。

GET

get_device_neighbors

/api/v1/object/device/{ip}/neighbors

返回设备的二层邻居关系。

GET

get_device_nodes

/api/v1/object/device/{ip}/nodes

返回设备上发现的节点。

GET

get_device_port

/api/v1/object/device/{ip}/port/{port}

device_port 表中返回一行。

GET

get_device_port_active_nodes

/api/v1/object/device/{ip}/port/{port}/active_nodes

返回端口的活动节点行。

GET

get_device_port_active_nodes_with_age

/api/v1/object/device/{ip}/port/{port}/active_nodes_with_age

返回端口的带年龄数据的活动节点行。

GET

get_device_port_agg_master

/api/v1/object/device/{ip}/port/{port}/agg_master

返回端口的聚合主条目。

GET

get_device_port_last_node

/api/v1/object/device/{ip}/port/{port}/last_node

返回端口的最后节点条目。

GET

get_device_port_logs

/api/v1/object/device/{ip}/port/{port}/logs

返回端口的日志行。

GET

get_device_port_neighbor

/api/v1/object/device/{ip}/port/{port}/neighbor

返回端口的邻居条目。

GET

get_device_port_nodes

/api/v1/object/device/{ip}/port/{port}/nodes

返回端口的节点行。

GET

get_device_port_nodes_with_age

/api/v1/object/device/{ip}/port/{port}/nodes_with_age

返回端口的带年龄数据的节点行。

GET

get_device_port_port_vlans

/api/v1/object/device/{ip}/port/{port}/port_vlans

返回端口的 port_vlans 行。

GET

get_device_port_power

/api/v1/object/device/{ip}/port/{port}/power

返回端口的电源条目。

GET

get_device_port_properties

/api/v1/object/device/{ip}/port/{port}/properties

返回端口的属性条目。

GET

get_device_port_ssid

/api/v1/object/device/{ip}/port/{port}/ssid

返回端口的 SSID 条目。

GET

get_device_port_vlans

/api/v1/object/device/{ip}/port/{port}/vlans

返回端口的 VLAN 行。

GET

get_device_port_wireless

/api/v1/object/device/{ip}/port/{port}/wireless

返回端口的无线条目。

GET

get_device_port_vlans_cd8cf56

/api/v1/object/device/{ip}/port_vlans

返回设备的 port_vlans 行。

GET

get_device_ports

/api/v1/object/device/{ip}/ports

返回设备的端口行。

GET

get_device_power_modules

/api/v1/object/device/{ip}/power_modules

返回 PoE 模块状态和聚合端口统计信息。

GET

get_device_powered_ports

/api/v1/object/device/{ip}/powered_ports

返回设备的供电端口行。

GET

get_device_ssids

/api/v1/object/device/{ip}/ssids

返回设备的 SSID 行。

GET

get_device_vlans

/api/v1/object/device/{ip}/vlans

返回设备的 VLAN 行。

GET

get_device_wireless_ports

/api/v1/object/device/{ip}/wireless_ports

返回设备的无线端口行。

GET

get_vlan_nodes

/api/v1/object/vlan/{vlan}/nodes

返回 VLAN 中发现的节点。

PUT

update_device_arps

/api/v1/object/device/{ip}/arps

排队一个作业以存储设备上发现的 ARP 条目。

PUT

update_device_nodes

/api/v1/object/device/{ip}/nodes

排队一个作业以存储设备上发现的节点。

方法

工具

Netdisco 路由

报告

GET

get_report_device_deviceaddrnodns

/api/v1/report/device/deviceaddrnodns

没有 DNS 条目的 IP 地址。

GET

get_report_device_devicebylocation

/api/v1/report/device/devicebylocation

按位置分组的库存。

GET

get_report_device_devicednsmismatch

/api/v1/report/device/devicednsmismatch

设备名称和 DNS 不匹配。

GET

get_report_device_deviceinventory

/api/v1/report/device/deviceinventory

设备库存。

GET

get_report_device_devicemultipleaddresses

/api/v1/report/device/devicemultipleaddresses

具有多个地址的设备。

GET

get_report_device_devicepoestatus

/api/v1/report/device/devicepoestatus

以太网供电状态。

GET

get_report_device_devicesharedaddresses

/api/v1/report/device/devicesharedaddresses

在多个设备上发现的 IP 地址。

GET

get_report_device_devicesmissingmodeloros

/api/v1/report/device/devicesmissingmodeloros

缺少型号或操作系统数据的设备。

GET

get_report_device_portutilization

/api/v1/report/device/portutilization

端口利用率。

GET

get_report_device_recentlyaddeddevices

/api/v1/report/device/recentlyaddeddevices

最近添加的设备。

GET

get_report_ip_duplicateprivatenetworks

/api/v1/report/ip/duplicateprivatenetworks

重复的私有网络。

GET

get_report_ip_ipinventory

/api/v1/report/ip/ipinventory

IP 库存。

GET

get_report_ip_subnets

/api/v1/report/ip/subnets

子网利用率。

GET

get_report_node_nodemultiips

/api/v1/report/node/nodemultiips

具有多个活动 IP 地址的节点。

GET

get_report_node_nodesdiscovered

/api/v1/report/node/nodesdiscovered

通过 LLDP 或 CDP 发现的节点。

GET

get_report_port_duplexmismatch

/api/v1/report/port/duplexmismatch

双工设置不匹配。

GET

get_report_port_halfduplex

/api/v1/report/port/halfduplex

在半双工模式下运行的端口。

GET

get_report_port_portadmindown

/api/v1/report/port/portadmindown

管理性禁用的端口。

GET

get_report_port_portblocking

/api/v1/report/port/portblocking

被生成树阻塞的端口。

GET

get_report_port_portmultinodes

/api/v1/report/port/portmultinodes

具有多个连接节点的端口。

GET

get_report_port_portserrordisabled

/api/v1/report/port/portserrordisabled

错误禁用的端口。

GET

get_report_port_portssid

/api/v1/report/port/portssid

端口 SSID 库存。

GET

get_report_port_portswithmostvlans

/api/v1/report/port/portswithmostvlans

承载最多 VLAN 的端口。

GET

get_report_port_portvlanmismatch

/api/v1/report/port/portvlanmismatch

VLAN 配置不匹配。

GET

get_report_vlan_devicevlancount

/api/v1/report/vlan/devicevlancount

每个设备的 VLAN 数量。

GET

get_report_vlan_vlaninventory

/api/v1/report/vlan/vlaninventory

VLAN 库存。

GET

get_report_vlan_vlanmultiplenames

/api/v1/report/vlan/vlanmultiplenames

具有多个名称的 VLAN。

GET

get_report_vlan_vlansneverconfigured

/api/v1/report/vlan/vlansneverconfigured

已知但从未配置的 VLAN。

GET

get_report_vlan_vlansonlyuplinks

/api/v1/report/vlan/vlansonlyuplinks

仅在上行链路上发现的 VLAN。

GET

get_report_vlan_vlansunused

/api/v1/report/vlan/vlansunused

不再使用的 VLAN。

GET

get_report_wireless_apchanneldist

/api/v1/report/wireless/apchanneldist

接入点信道分布。

GET

get_report_wireless_apclients

/api/v1/report/wireless/apclients

接入点客户端数量。

GET

get_report_wireless_apradiochannelpower

/api/v1/report/wireless/apradiochannelpower

接入点无线电信道和功率。

GET

get_report_wireless_ssidinventory

/api/v1/report/wireless/ssidinventory

SSID 库存。

方法

工具

Netdisco 路由

目的

GET

get_queue_backends

/api/v1/queue/backends

列出活动的 Netdisco 后端名称。

GET

get_queue_jobs

/api/v1/queue/jobs

返回带有可选过滤器的排队作业。

GET

get_queue_status

/api/v1/queue/status

返回按状态分组的作业计数。

POST

create_queue_jobs

/api/v1/queue/jobs

将作业提交到 Netdisco 队列。

DELETE

delete_queue_jobs

/api/v1/queue/jobs

删除队列作业和带有可选过滤器的跳过列表条目。

方法

工具

Netdisco 路由

目的

GET

search_device

/api/v1/search/device

按身份、地址、位置、型号、操作系统、供应商和其他属性搜索设备。

GET

search_node

/api/v1/search/node

搜索节点,包括活动和归档的观察结果。

GET

search_port

/api/v1/search/port

按描述和端口特征搜索交换机端口。

GET

search_vlan

/api/v1/search/vlan

搜索 VLAN。

方法

工具

Netdisco 路由

目的

GET

get_users

/api/v1/users

列出具有角色和令牌状态的用户。

POST

create_user

/api/v1/user

预配一个仅令牌的服务账户,并颁发或撤销其 API 令牌。

方法

工具

Netdisco 路由

目的

GET

get_statistics

/api/v1/statistics

返回最新的 Netdisco 统计行。

GET

get_logout

/logout

销毁当前的 API 密钥和会话 cookie;这具有破坏性副作用。

POST

create_login

/login

获取 Netdisco API 密钥。

快速开始

要求

  • Python 3.11 或更新版本

  • 一个可访问的 Netdisco 实例,带有 swagger.json

  • 一个永久的 Netdisco API 令牌或支持的 用户名/密码 凭据

  • 用于容器部署的 Docker 和 Docker Compose

本地开发

git clone https://github.com/omichelbraga/netdisco-mcp.git
cd netdisco-mcp
cp .env.example .env

.env 中设置所需的值:

NETDISCO_URL=https://netdisco.example.net
NETDISCO_API_TOKEN=replace-with-a-permanent-netdisco-token

安装、验证实时规范并运行:

uv sync --extra dev
uv run netdisco-mcp --check
uv run netdisco-mcp

默认传输是 stdio。

Docker Compose

提供的 Compose 文件期望共享的外部网络 mcp-edge,并且 不发布主机端口。

docker network create mcp-edge
docker compose up --build -d

mcp-edge 上的反向代理可以通过以下地址访问该服务:

http://netdisco-mcp:8000/mcp

配置参考

设置

默认值

用途

NETDISCO_URL

必填

Netdisco 实例的基础 URL。

NETDISCO_SPEC_URL

$NETDISCO_URL/swagger.json

覆盖实时的 Swagger/OpenAPI URL。

NETDISCO_API_TOKEN

未设置

发送到上游 API 的 Netdisco API 凭证。

NETDISCO_AUTH_SCHEME

Bearer

授权方案;使用 raw 表示无前缀的令牌。

NETDISCO_USERNAME

未设置

可选的 Netdisco Basic-auth 用户名。

NETDISCO_PASSWORD

未设置

可选的 Netdisco Basic-auth 密码。

NETDISCO_TLS_VERIFY

1

验证 Netdisco TLS 证书。

NETDISCO_TIMEOUT

30

上游请求超时时间(秒)。

NETDISCO_READ_ONLY

0

设置为 1 时移除 POST、PUT、PATCH 和 DELETE 工具。

NETDISCO_GUIDANCE_GATE

1

在正常工具使用前需要指导。

NETDISCO_GUIDANCE_TTL

1800

指导活动窗口(秒)。

NETDISCO_MAX_RESPONSE_CHARS

50000

工具响应在截断前的最大大小。

NETDISCO_MCP_TRANSPORT

stdio

stdiostreamable-httpstdinhttp 是接受的别名。

NETDISCO_MCP_HTTP_HOST

127.0.0.1

Streamable HTTP 的绑定地址。

NETDISCO_MCP_HTTP_PORT

8000

进程或容器内的监听端口。

NETDISCO_MCP_BEARER_TOKEN

未设置

配置时 HTTP 传输所需的静态 Bearer 令牌。

[!WARNING] NETDISCO_API_TOKEN 对服务器进行 Netdisco 身份验证。 NETDISCO_MCP_BEARER_TOKEN 对 MCP 客户端进行此服务器身份验证。它们 保护不同的信任边界,绝不应共享相同的值。

连接 MCP 客户端

Claude Code

claude mcp add --transport http --scope user \
  netdisco-mcp https://netdisco-mcp.example.net/mcp \
  --header "Authorization: Bearer <mcp-bearer-token>"

验证连接:

claude mcp get netdisco-mcp

Codex

将 MCP Bearer 令牌存储在 NETDISCO_MCP_BEARER_TOKEN 中,然后将此条目添加到 ~/.codex/config.toml

[mcp_servers."netdisco-mcp"]
url = "https://netdisco-mcp.example.net/mcp"
bearer_token_env_var = "NETDISCO_MCP_BEARER_TOKEN"
default_tools_approval_mode = "prompt"

请参阅官方 Codex MCP 配置 以获取额外的超时、允许列表和审批控制。

Claude Desktop

Claude Desktop 可以使用附带的经过身份验证的 stdio 代理。该代理将 远程 Bearer 令牌排除在 Desktop 发送的 MCP 协议消息之外,并仅在连接上游时添加它。

fastmcp install claude-desktop \
  src/netdisco_mcp/desktop_proxy.py:mcp \
  --name netdisco-mcp \
  --with-editable . \
  --env NETDISCO_MCP_URL=https://netdisco-mcp.example.net/mcp \
  --env NETDISCO_MCP_BEARER_TOKEN=<mcp-bearer-token>

安装后重启 Claude Desktop。

OpenAI Responses API

import os

from openai import OpenAI

client = OpenAI()

response = client.responses.create(
    model="gpt-5.6",
    input="Call get_guidance, then summarize the Netdisco device inventory.",
    tools=[
        {
            "type": "mcp",
            "server_label": "netdisco",
            "server_url": "https://netdisco-mcp.example.net/mcp",
            "authorization": os.environ["NETDISCO_MCP_BEARER_TOKEN"],
            "require_approval": "always",
        }
    ],
)

print(response.output_text)

authorization 字段遵循官方 远程 MCP 工具 契约。将此服务器的 require_approval 设置为 always 是合适的,因为其 实时目录可能包含变更工具。

通用 MCP 客户端

{
  "mcpServers": {
    "netdisco-mcp": {
      "type": "http",
      "url": "https://netdisco-mcp.example.net/mcp",
      "headers": {
        "Authorization": "Bearer <mcp-bearer-token>"
      }
    }
  }
}

安全模型

flowchart LR
    Client["Authenticated MCP client"]
    Edge["TLS reverse proxy"]
    MCP["Netdisco MCP bearer verifier"]
    Credential["Internal Netdisco credential"]
    Netdisco["Netdisco authorization"]

    Client -- "MCP bearer token" --> Edge
    Edge -- "preserved Authorization header" --> MCP
    MCP -- "approved tool call" --> Credential
    Credential -- "separate API token" --> Netdisco

项目提供的安全控制:

  • 对配置的 MCP Bearer 令牌进行恒定时间比较。

  • 独立的 MCP 客户端和 Netdisco 上游凭证。

  • 基于方法的可选只读工具过滤。

  • 操作工具使用前的指导中间件。

  • 响应大小限制以保护模型上下文。

  • 默认启用 Netdisco 的 TLS 验证。

  • 提供的 Compose 文件中没有主机端口。

  • 只读容器文件系统和 no-new-privileges

推荐的生产环境控制:

  • 在反向代理处终止受信任的 TLS。

  • 将两个凭证存储在密钥管理器或 Portainer 密钥环境中。

  • 按定义的时间表以及在意外泄露后轮换凭证。

  • 将 Netdisco 凭证限制为所需的最低角色。

  • 保持对变更工具的审批提示启用。

  • 审查反向代理访问日志和 Netdisco 作业历史。

  • 对于仅发现的部署,使用 NETDISCO_READ_ONLY=1

工具生成方式

Netdisco 2.103000 发布 Swagger 2.0,而 FastMCP 使用 OpenAPI 3。 适配器执行以下转换,而不移除支持的操作:

  1. 将 Swagger 引用重写为 OpenAPI components 引用。

  2. 将主体和表单参数转换为 OpenAPI 请求主体。

  3. 将参数类型信息移动到模式中。

  4. 修复 Netdisco 属性级别的 required 标志。

  5. 规范化布尔值、整数和数组默认值。

  6. 将响应模式转换为媒体类型内容条目。

  7. 分配确定性的、人类可读的操作 ID。

  8. 将原始 HTTP 方法和路由添加到每个工具描述中。

  9. 在启用只读模式时移除写入方法。

如果两个路由将获得相同的友好名称,则会附加一个确定性的七字符 摘要。这解释了诸如 get_device_port_vlans_cd8cf56 之类的名称,并保持完整的 API 表面无冲突。

仓库布局

netdisco-mcp/
├── src/netdisco_mcp/
│   ├── __main__.py          # CLI and transport startup
│   ├── auth.py              # MCP bearer-token verification
│   ├── config.py            # Environment-driven settings
│   ├── desktop_proxy.py     # Authenticated Claude Desktop proxy
│   ├── guidance.py          # Guidance loading and enforcement
│   ├── server.py            # FastMCP assembly and tool mounting
│   ├── spec.py              # Swagger normalization and tool catalog
│   └── data/GUIDANCE.md     # Operating instructions for AI agents
├── tests/                   # Configuration, auth, and spec tests
├── compose.yaml             # Internal-network container deployment
├── Dockerfile
└── pyproject.toml

开发和测试

运行测试套件:

uv run pytest

验证连接的实时 API 而不启动传输:

NETDISCO_URL=https://netdisco.example.net \
NETDISCO_API_TOKEN=<netdisco-api-token> \
uv run netdisco-mcp --check

检查报告 API 版本覆盖率、读/写操作计数、总 MCP 工具和标签。测试涵盖传输别名、Bearer 验证、Swagger- to-OpenAPI 转换、稳定名称、请求主体、模式修复、只读 过滤和功能发现。

贡献

  1. Fork 仓库并创建一个专注的分支。

  2. 为行为更改添加测试。

  3. 针对代表性的 Swagger 夹具运行完整的测试套件。

  4. 针对授权的 Netdisco 实例运行 netdisco-mcp --check

  5. 打开一个描述用户可见行为和验证的拉取请求。

请不要提交 Netdisco 凭证、MCP Bearer 令牌、内部 URL 或 捕获的基础设施数据。

许可证

根据 MIT 许可证 发布。

-
license - not tested
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

View all MCP Connectors

Latest Blog Posts

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/omichelbraga/netdisco-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server