Token导航 LogoToken导航TokenDH.com
Network Discovery MCP logo
运维云端stdio官方级别未说明来源级核验

Network Discovery MCP

MCP Server

Network Discovery MCP是一个模块化、容器化的网络发现服务,支持自动化网络映射和分析,能够从单一设备开始自动发现网络设备、收集配置并生成交互式拓扑可视化。

工具数

22

提示词数

0

GitHub Stars

2

资源数

0
PythonClaude配置管理Claude DesktopClaudeCline

安装说明

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

作者 / 组织

Presidio-Federal

提供方

Presidio-Federal

最后核验

2026/5/17 20:21

运行时

Docker

快速接入

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

命令预览

docker run -d \

详细介绍

网络发现MCP-用户指南

一种模块化、容器化的网络发现服务,用于自动化网络映射和分析。网络发现MCP自动发现网络设备,收集配置,并从单个种子设备开始生成交互式拓扑可视化。

目录

______________________________________________________________________

概述

网络发现MCP提供自动化的网络基础设施发现和映射。该系统支持两种发现方法:

发现方法1:种子装置发现

  1. 连接到单个“种子”网络设备
  2. 通过以下方式自动发现网络拓扑:

- 接口信息(子网、VRF) - 路由表(已知网络) - ARP表(活动主机) - CDP/LDP邻居(直接连接的设备)

  1. 扫描所有发现的IP地址以获取可达性
  2. 确定设备供应商和型号
  3. 收集设备配置
  4. 生成交互式网络拓扑可视化

在以下情况下使用此方法:您可以通过网络访问设备,并希望自动发现拓扑结构。

发现方法2:直接IP/子网扫描

  1. 直接接受IP地址或子网列表
  2. 扫描提供的地址以查找可达性
  3. 确定设备供应商和型号
  4. 收集设备配置
  5. 生成网络拓扑可视化

在以下情况下使用此方法:您有设备IP的真实来源(如NetBox、电子表格或IPAM),并希望跳过拓扑发现。

操作模式

该服务可以在两种模式下运行:

  • REST API模式:用于与脚本、工具和CI/CD管道集成的传统HTTP API
  • MCP模式:用于直接AI代理集成的模型上下文协议接口

这两种模式都提供了相同的功能,但集成模式不同。

______________________________________________________________________

特性

核心发现功能

  • 自动网络映射:从单个种子设备发现整个网络拓扑
  • 智能多供应商支持:登录后自动检测设备操作系统(思科、瞻博网络、Arista、帕洛阿尔托、Fortinet、华为)
  • 增强型设备指纹识别:通过支持Arista EOS、Juniper JUNOS和Palo Alto PAN-OS,改进了供应商识别
  • 并行操作:高性能扫描和配置收集
  • 配置管理:使用特定于供应商的命令安全地收集和存储设备配置
  • 交互式可视化:生成带有颜色编码设备状态的交互式HTML网络拓扑图
  • 蝙蝠鱼一体化:高级网络分析和验证

可靠性特征

  • 凭证验证:在开始昂贵的操作之前测试凭据(在失败时节省30多分钟)
  • 工作简历:恢复失败的作业,而不重新执行已完成的工作(对于大型网络至关重要)
  • 重试逻辑:针对瞬态故障,采用指数回退自动重试
  • 超时处理:可配置的超时可防止挂起操作
  • 优雅地关闭:集装箱环境的清洁停机处理

监测和可观察性

  • 系统健康检查:在开始扫描之前监视系统资源
  • 作业统计:详细的进度跟踪和成功指标
  • 失效分析:故障排除的智能建议
  • 历史跟踪:跟踪一段时间内的工作历史和成功率

智能功能

  • 自动操作系统检测:SSH登录后检测设备操作系统(无需平台参数)
  • 供应商特定命令:自动为每个供应商选择正确的命令
  • 指纹校正:通过验证操作系统身份验证后的错误识别
  • 回退机制:如果操作系统检测失败,则使用指纹数据

安全功能

  • 安全凭证处理:日志和表示中隐藏的密码
  • 原子文件操作:防止写入过程中的数据损坏
  • 集装箱隔离:在隔离的容器环境中运行
  • 可选HTTPS:支持加密MCP通信

______________________________________________________________________

入门指南

先决条件

  • 已安装Docker和Docker Compose
  • 对要发现的设备的网络访问
  • 至少一个“种子”设备的有效凭据

快速开始

  1. 克隆存储库:
git clone https://github.com/username/network-discovery-mcp.git
cd network-discovery-mcp
  1. 选择部署模式:

对于REST API模式:

docker compose up -d

对于MCP模式(AI代理):

docker compose -f docker-compose.mcp.yml up -d
  1. 验证服务是否正在运行:

REST API:

curl http://localhost:8000/health

MCP:

curl http://localhost:8080/mcp
  1. 启动发现(REST API示例):
curl -X POST http://localhost:8000/v1/seed \
  -H "Content-Type: application/json" \
  -d '{
    "seed_host": "192.168.1.1",
    "credentials": {
      "username": "admin",
      "password": "your_password"
    },
    "methods": ["interfaces", "routing", "arp", "cdp"]
  }'

备注:The platform 参数(如 cisco_ios)现在是可选的!登录后,系统会自动检测设备操作系统,并选择相应的命令。您仍然可以提供 platform 如有需要,作为备选方案。

响应中包含一个job_id,可用于跟踪进度和检索结果。

______________________________________________________________________

部署模式

REST API模式(默认)

REST API模式为编程访问提供了传统的HTTP端点。

在以下情况下使用此模式:

  • 与现有工具和脚本集成
  • 从CI/CD管道运行
  • 构建自定义应用程序
  • 您需要与语言无关的HTTP访问

正在启动REST API模式:

docker compose up -d

访问API:

  • API基本URL: http://localhost:8000
  • API文件: http://localhost:8000/docs
  • 健康检查: http://localhost:8000/health

配置文件: docker-compose.yml

______________________________________________________________________

MCP模式(AI代理集成)

MCP模式为AI代理集成提供了一个模型上下文协议接口。

在以下情况下使用此模式:

  • 与AI代理(Claude、GPT等)集成
  • 构建自主网络发现工作流
  • 你想要人工智能驱动的网络运营

启动MCP模式:

docker compose -f docker-compose.mcp.yml up -d

访问MCP服务器:

  • MCP端点: http://localhost:8080/mcp
  • 健康检查: http://localhost:8080/health

配置文件: docker-compose.mcp.yml

带HTTPS的MCP

一些AI代理框架(如某些Claude实现或企业AI平台)需要HTTPS连接,并且不接受HTTP。如果您的AI代理需要HTTPS,则需要配置SSL证书。

何时使用HTTPS:

  • 您的AI代理框架拒绝HTTP连接
  • 您的AI代理正在另一个网络上运行,需要加密
  • 公司安全政策要求加密通信
  • 您正在将MCP服务器暴露在互联网上

先决条件:

  • SSL证书文件(fullchain.pem或certificate.crt)
  • SSL私钥文件(privkey.pem或private.key)

第一步:准备证书

选项A-使用Let's Encrypt证书:

# If using Let's Encrypt/Certbot, certificates are typically at:
# Certificate: /etc/letsencrypt/live/yourdomain.com/fullchain.pem
# Private key: /etc/letsencrypt/live/yourdomain.com/privkey.pem

选项B-使用自签名证书(用于测试):

# Generate self-signed certificate
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout privkey.pem \
  -out fullchain.pem \
  -subj "/CN=localhost"

选项C-使用公司证书:

# Use certificates provided by your organization
# Ensure you have both the certificate and private key files

步骤2:修改docker-compose.mcp.yml

编辑 docker-compose.mcp.yml 用于装载证书的文件:

services:
  network-discovery-mcp:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: network-discovery-mcp
    environment:
      - ENABLE_MCP=true
      - TRANSPORT=https                    # Set transport to https
      - PORT=8080
      - HOST=0.0.0.0
      - ARTIFACT_DIR=/artifacts
      - BATFISH_HOST=batfish
      - LOG_LEVEL=info
    ports:
      - "8080:8080"                         # HTTP port (optional, for health checks)
      - "443:443"                           # HTTPS port (required)
volumes:
  - ./artifacts:/artifacts
      # Mount your SSL certificates (REQUIRED for HTTPS):
      - /path/to/your/fullchain.pem:/certs/fullchain.pem:ro
      - /path/to/your/privkey.pem:/certs/privkey.pem:ro
    depends_on:
      - batfish
    networks:
      - discovery-network

  batfish:
    image: batfish/batfish:latest
    container_name: batfish
ports:
      - "9996:9996"
      - "9997:9997"
    networks:
      - discovery-network

networks:
  discovery-network:
    driver: bridge

重要变更:

  1. 改变 TRANSPORThttphttps
  2. 添加端口映射 443:443
  3. 取消注释并使用您的实际证书路径更新证书卷装载
  4. 替换 /path/to/your/ 带有证书的实际路径

步骤3:启动服务

# Start with HTTPS enabled
docker compose -f docker-compose.mcp.yml up -d

# Check logs to verify HTTPS is working
docker compose -f docker-compose.mcp.yml logs network-discovery-mcp

# You should see logs indicating nginx started with HTTPS on port 443

步骤4:验证HTTPS是否正常工作

# Test HTTPS endpoint
curl https://localhost/mcp

# If using self-signed certificates, use -k to skip verification
curl -k https://localhost/mcp

# You should get a response from the MCP server

步骤5:配置您的AI代理

更新您的AI代理配置以使用HTTPS端点:

# Example: Connecting AI agent to HTTPS MCP server
import mcp

# With valid certificates
client = mcp.Client("https://your-server.com/mcp")

# With self-signed certificates (development only)
import ssl
context = ssl._create_unverified_context()
client = mcp.Client("https://localhost/mcp", ssl_context=context)

HTTPS故障排除

问题:“证书验证失败”

如果使用自签名证书,您的AI代理可能会拒绝它们。解决:

  1. 对于测试,请在代理中禁用证书验证(不建议用于生产)
  2. 将自签名证书添加到系统的受信任证书中
  3. 使用Let's Encrypt或CA的正确签名证书

问题:“端口443上的连接被拒绝”

检查:

# 1. Container is running
docker compose -f docker-compose.mcp.yml ps

# 2. Port 443 is mapped
docker compose -f docker-compose.mcp.yml port network-discovery-mcp 443

# 3. Nginx is running with HTTPS
docker compose -f docker-compose.mcp.yml logs network-discovery-mcp | grep nginx

# 4. Certificates are mounted correctly
docker exec network-discovery-mcp ls -la /certs/

问题:“找不到证书”

容器在以下位置查找证书:

  • /certs/fullchain.pem
  • /certs/privkey.pem

验证它们是否已安装:

docker exec network-discovery-mcp ls -la /certs/
# Should show both files

示例:使用Let's Encrypt完成HTTPS设置

# 1. Obtain Let's Encrypt certificates (on host machine)
sudo certbot certonly --standalone -d your-domain.com

# 2. Update docker-compose.mcp.yml with certificate paths
# Edit the volumes section:
volumes:
  - ./artifacts:/artifacts
  - /etc/letsencrypt/live/your-domain.com/fullchain.pem:/certs/fullchain.pem:ro
  - /etc/letsencrypt/live/your-domain.com/privkey.pem:/certs/privkey.pem:ro

# 3. Ensure TRANSPORT is set to https
# environment:
#   - TRANSPORT=https

# 4. Start the service
docker compose -f docker-compose.mcp.yml up -d

# 5. Test HTTPS connection
curl https://your-domain.com/mcp

# 6. Configure AI agent to use HTTPS endpoint
# In your AI agent config:
# mcp_server_url: https://your-domain.com/mcp

HTTP与HTTPS决策矩阵

场景使用HTTP使用HTTPS
在同一台机器上使用AI代理进行本地测试
AI代理框架需要HTTPS
通过网络暴露MCP服务器
公司安全政策
不同网络上的AI代理
开发/测试环境可选
生产环境

摘要:

  • HTTP(端口8080)更便于本地测试
  • 不接受HTTP的AI代理框架需要HTTPS(端口443)
  • 该服务会自动检测已装载的证书并启用HTTPS
  • HTTP和HTTPS可以同时运行(对端口8080上的健康检查很有用)

测试您的MCP服务器

您可以使用标准HTTP工具测试MCP服务器:

# Test HTTP MCP server
curl http://localhost:8080/mcp

# Test HTTPS MCP server
curl https://localhost/mcp --insecure

# Check available tools (pretty print)
curl http://localhost:8080/mcp | jq '.tools'

# Verify specific tool availability
curl http://localhost:8080/mcp | jq '.tools[] | select(.name=="run_network_discovery")'

如果您在本地安装了官方MCP SDK中的MCP Inspector工具,您也可以使用它,或者直接与Claude Desktop、Cline或其他MCP兼容客户端等AI代理框架集成。

______________________________________________________________________

单容器部署

对于想要更多控制或不需要蝙蝠鱼的高级用户:

REST API模式:

docker run -d \
  -p 8000:8000 \
  -e ARTIFACT_DIR=/data \
  -v /path/to/artifacts:/data \
  ghcr.io/username/network-discovery-mcp:latest

MCP模式(HTTP):

docker run -d \
  -p 8080:8080 \
  -e ENABLE_MCP=true \
  -e TRANSPORT=http \
  -e ARTIFACT_DIR=/data \
  -v /path/to/artifacts:/data \
  ghcr.io/username/network-discovery-mcp:latest

MCP模式(HTTPS):

docker run -d \
  -p 443:443 -p 8080:8080 \
  -e ENABLE_MCP=true \
  -e TRANSPORT=https \
  -e ARTIFACT_DIR=/data \
  -v /path/to/artifacts:/data \
  -v /etc/ssl/certs/fullchain.pem:/certs/fullchain.pem:ro \
  -v /etc/ssl/private/privkey.pem:/certs/privkey.pem:ro \
  ghcr.io/username/network-discovery-mcp:latest

注: 在没有Batfish容器的情况下运行会禁用拓扑可视化和分析功能。

______________________________________________________________________

使用REST API

REST API提供对所有网络发现功能的编程访问。

完成发现工作流程

下面是使用REST API发现网络的完整示例:

步骤1:验证凭据(推荐)

在开始发现之前测试凭据,以避免浪费时间:

curl -X POST http://localhost:8000/v1/credentials/validate \
  -H "Content-Type: application/json" \
  -d '{
    "seed_host": "192.168.1.1",
    "username": "admin",
    "password": "cisco123"
  }'

备注:The platform 参数是可选的。连接后,系统将自动检测操作系统。

答复:

{
  "valid": true,
  "latency_ms": 2340,
  "detected_vendor": "Cisco",
  "detected_model": "IOS-XE",
  "can_read_config": true
}

如果凭据无效,在浪费时间进行发现之前,您将收到带有建议的错误。

步骤2:从设备中播种

从种子设备开始发现:

curl -X POST http://localhost:8000/v1/seed \
  -H "Content-Type: application/json" \
  -d '{
    "seed_host": "192.168.1.1",
    "credentials": {
      "username": "admin",
      "password": "cisco123"
    },
    "methods": ["interfaces", "routing", "arp", "cdp"]
  }'

备注:平台自动检测自动发生。您可以选择提供 "platform": "cisco_ios" 如果检测失败,则作为回退。

答复:

{
  "job_id": "net-disc-20251102-123456",
  "status": "completed",
  "targets_count": 256,
  "targets_path": "/artifacts/net-disc-20251102-123456/targets.json"
}

保存 job_id 用于后续操作。

步骤3:扫描发现的目标

扫描发现的目标以获取可达性:

curl -X POST http://localhost:8000/v1/scan \
  -H "Content-Type: application/json" \
  -d '{
    "job_id": "net-disc-20251102-123456",
    "ports": [22, 443],
    "concurrency": 200
  }'

答复:

{
  "job_id": "net-disc-20251102-123456",
  "status": "completed",
  "hosts_scanned": 256,
  "hosts_reachable": 42
}

第四步:指纹识别设备

确定供应商和型号:

curl -X POST http://localhost:8000/v1/fingerprint \
  -H "Content-Type: application/json" \
  -d '{
    "job_id": "net-disc-20251102-123456"
  }'

答复:

{
  "job_id": "net-disc-20251102-123456",
  "status": "completed",
  "hosts_fingerprinted": 42,
  "identified_count": 38
}

步骤5:收集配置

收集设备配置(平台自动检测):

curl -X POST http://localhost:8000/v1/state/collect \
  -H "Content-Type: application/json" \
  -d '{
    "job_id": "net-disc-20251102-123456",
    "credentials": {
      "username": "admin",
      "password": "cisco123"
    },
    "concurrency": 50
  }'

备注:登录后,系统会自动检测每个设备的操作系统,并运行相应的命令:

  • 思科: show running-config
  • 阿里斯塔: show running-config
  • 朱尼珀: show configuration | display set
  • 帕洛阿尔托: show config running
  • Fortinet: show full-configuration
  • 华为: display current-configuration

答复:

{
  "job_id": "net-disc-20251102-123456",
  "status": "completed",
  "device_count": 42,
  "success_count": 38,
  "failed_count": 4
}

步骤6:生成拓扑可视化

构建蝙蝠鱼快照并生成可视化:

# Build Batfish snapshot
curl -X POST http://localhost:8000/v1/batfish/build \
  -H "Content-Type: application/json" \
  -d '{
    "job_id": "net-disc-20251102-123456"
  }'

# Load into Batfish
curl -X POST http://localhost:8000/v1/batfish/load \
  -H "Content-Type: application/json" \
  -d '{
    "job_id": "net-disc-20251102-123456"
  }'

# Generate visualization
curl -X GET "http://localhost:8000/v1/batfish/topology/html?job_id=net-disc-20251102-123456" \
  -o network_topology.html

# Open in browser
open network_topology.html

步骤7:检查作业状态

随时监控进度:

curl http://localhost:8000/v1/status/net-disc-20251102-123456

答复:

{
  "job_id": "net-disc-20251102-123456",
  "seeder": {
    "status": "completed",
    "targets_count": 256,
    "completed_at": "2025-11-02T12:34:56Z"
  },
  "scanner": {
    "status": "completed",
    "hosts_scanned": 256,
    "hosts_reachable": 42,
    "completed_at": "2025-11-02T12:38:45Z"
  },
  "fingerprinter": {
    "status": "completed",
    "hosts_fingerprinted": 42,
    "completed_at": "2025-11-02T12:40:22Z"
  },
  "state_collector": {
    "status": "completed",
    "device_count": 42,
    "success_count": 38,
    "failed_count": 4,
    "completed_at": "2025-11-02T12:55:33Z"
  }
}

处理失败:工作简历

如果作业中途失败(例如,在配置收集期间),您可以在不重新执行已完成的工作的情况下恢复它:

# Check for resumable jobs
curl http://localhost:8000/v1/jobs/resumable

# Resume a specific job
curl -X POST http://localhost:8000/v1/jobs/resume \
  -H "Content-Type: application/json" \
  -d '{
    "job_id": "net-disc-20251102-123456",
    "credentials": {
      "username": "admin",
      "password": "cisco123",
      "platform": "cisco_ios"
    }
  }'

恢复操作:

  • 检测哪些阶段已成功完成
  • 跳过已完成的工作
  • 仅检索失败或不完整的阶段
  • 保存所有成功的结果

这对于大型网络至关重要,因为瞬态故障不需要重新启动整个发现过程。

替代方案:直接从子网扫描

如果您不需要基于种子的发现,并且已经拥有IP地址或子网列表(来自NetBox、IPAM、电子表格等),则可以直接扫描它们:

curl -X POST http://localhost:8000/v1/scan/from-subnets \
  -H "Content-Type: application/json" \
  -d '{
    "job_id": "manual-scan-001",
    "subnets": ["192.168.1.0/24", "10.0.0.0/24"],
    "ports": [22, 443],
    "concurrency": 200
  }'

然后像往常一样继续指纹识别和配置收集。

与真相来源系统合作

如果你在真相源系统(NetBox、phpIPAM等)中维护一个清单,你可以提取IP地址并直接扫描它们,而无需发现种子设备。

示例:使用NetBox作为真实来源

# 1. Query NetBox for device IPs (this is pseudocode)
DEVICE_IPS=$(curl -H "Authorization: Token YOUR_TOKEN" \
  https://netbox.example.com/api/dcim/devices/ | \
  jq -r '.results[].primary_ip.address' | \
  cut -d'/' -f1)

# 2. Convert to JSON array
SUBNETS=$(echo "$DEVICE_IPS" | jq -R -s -c 'split("\n")[:-1]')

# 3. Start scan with those IPs
curl -X POST http://localhost:8000/v1/scan/from-subnets \
  -H "Content-Type: application/json" \
  -d "{
    \"job_id\": \"netbox-scan\",
    \"subnets\": $SUBNETS,
    \"ports\": [22, 443],
    \"concurrency\": 200
  }"

# 4. Continue with fingerprinting
curl -X POST http://localhost:8000/v1/fingerprint \
  -H "Content-Type: application/json" \
  -d '{"job_id": "netbox-scan"}'

# 5. Collect configs
curl -X POST http://localhost:8000/v1/state/collect \
  -H "Content-Type: application/json" \
  -d '{
    "job_id": "netbox-scan",
    "credentials": {
      "username": "admin",
      "password": "your_password",
      "platform": "cisco_ios"
    }
  }'

# 6. Generate topology
curl -X POST http://localhost:8000/v1/batfish/build \
  -H "Content-Type: application/json" \
  -d '{"job_id": "netbox-scan"}'

curl -X POST http://localhost:8000/v1/batfish/load \
  -H "Content-Type: application/json" \
  -d '{"job_id": "netbox-scan"}'

curl -X GET "http://localhost:8000/v1/batfish/topology/html?job_id=netbox-scan" \
  -o topology.html

示例:使用带有IP地址的CSV文件

# 1. Convert CSV to subnet list
# Assuming devices.csv has a column "ip_address"
SUBNETS=$(tail -n +2 devices.csv | cut -d',' -f1 | jq -R -s -c 'split("\n")[:-1]')

# 2. Start scan
curl -X POST http://localhost:8000/v1/scan/from-subnets \
  -H "Content-Type: application/json" \
  -d "{
    \"job_id\": \"csv-scan\",
    \"subnets\": $SUBNETS,
    \"ports\": [22, 443]
  }"

AI代理实例与真相来源

import mcp
import requests

# Connect to MCP server
client = mcp.Client("http://localhost:8080/mcp")

# 1. Retrieve device IPs from NetBox
netbox_response = requests.get(
    "https://netbox.example.com/api/dcim/devices/",
    headers={"Authorization": "Token YOUR_TOKEN"}
)
device_ips = [d["primary_ip"]["address"].split("/")[0] 
              for d in netbox_response.json()["results"] 
              if d.get("primary_ip")]

# 2. Scan the devices from NetBox
result = client.call_tool("scan_from_subnets", {
    "job_id": "netbox-discovery",
    "subnets": device_ips,
    "ports": [22, 443]
})

# 3. Continue with fingerprinting and config collection
client.call_tool("fingerprint_devices", {"job_id": "netbox-discovery"})
client.call_tool("collect_device_configs", {
    "job_id": "netbox-discovery",
    "credentials": {
        "username": "admin",
        "password": "password",
        "platform": "cisco_ios"
    }
})

# 4. Generate topology
client.call_tool("build_batfish_snapshot", {"job_id": "netbox-discovery"})
client.call_tool("load_batfish_snapshot", {"job_id": "netbox-discovery"})
topology = client.call_tool("generate_topology_visualization", {"job_id": "netbox-discovery"})

print(f"Topology visualization saved to: {topology['path']}")

在以下情况下,这种方法是理想的:

  • 您已经在另一个系统中维护了设备清单
  • 你想验证你的真实数据来源
  • 您只需要发现特定的设备,而不是整个网络
  • 您希望避免基于CDP/LDP的发现

______________________________________________________________________

与AI代理(MCP)一起使用

MCP接口提供了AI代理可以用来自主发现和分析网络的工具。

MCP工作流示例

以下是AI代理如何与MCP服务器交互:

import mcp

# Connect to MCP server
client = mcp.Client("http://localhost:8080/mcp")

# Step 1: Validate credentials first
validation = client.call_tool("validate_device_credentials", {
    "seed_host": "192.168.1.1",
    "username": "admin",
    "password": "cisco123",
    "platform": "cisco_ios"
})

if not validation["valid"]:
    print(f"Invalid credentials: {validation['error']}")
    print(f"Suggestion: {validation['suggestion']}")
    exit(1)

print("Credentials validated successfully!")

# Step 2: Check system health
health = client.call_tool("check_system_health", {})
if not health["ready_for_scan"]:
    print(f"System not ready: {health['issues']}")
    exit(1)

# Step 3: Seed from device
result = client.call_tool("seed_device", {
    "seed_host": "192.168.1.1",
    "credentials": {
        "username": "admin",
        "password": "cisco123",
        "platform": "cisco_ios"
    },
    "methods": ["interfaces", "routing", "arp", "cdp"]
})
job_id = result["job_id"]

# Step 4: Scan targets
client.call_tool("scan_targets", {
    "job_id": job_id,
    "ports": [22, 443]
})

# Step 5: Get job statistics
stats = client.call_tool("get_job_stats", {
    "job_id": job_id
})
print(f"Found {stats['results']['scanning']['reachable_hosts']} devices")

# Step 6: Fingerprint devices
client.call_tool("fingerprint_devices", {
    "job_id": job_id
})

# Step 7: Collect configs
result = client.call_tool("collect_device_configs", {
    "job_id": job_id,
    "credentials": {
        "username": "admin",
        "password": "cisco123",
        "platform": "cisco_ios"
    }
})

# Step 8: Generate topology
client.call_tool("build_batfish_snapshot", {"job_id": job_id})
client.call_tool("load_batfish_snapshot", {"job_id": job_id})
viz = client.call_tool("generate_topology_visualization", {"job_id": job_id})

print(f"Topology saved to: {viz['path']}")

# Step 9: Get final statistics
final_stats = client.call_tool("get_job_stats", {"job_id": job_id})
print(f"Discovery complete!")
print(f"- Devices discovered: {final_stats['results']['scanning']['reachable_hosts']}")
print(f"- Vendors identified: {final_stats['results']['vendors']}")
print(f"- Configs collected: {final_stats['results']['config_collection']['configs_collected']}")

AI代理最佳实践

1.始终先验证凭据

在开始昂贵的发现操作之前,请验证凭据:

# GOOD: Validate first (10 seconds)
validation = client.call_tool("validate_device_credentials", {...})
if validation["valid"]:
    # Proceed with discovery
    
# BAD: Skip validation, waste 30 minutes on wrong credentials
client.call_tool("seed_device", {...})  # Fails after 30 min

2.大扫描前检查系统健康状况

health = client.call_tool("check_system_health", {})
if health["cpu"]["usage_percent"] > 80:
    print("System busy, waiting...")
    time.sleep(60)

3.恢复失败的作业

# Check for failed jobs
resumable = client.call_tool("list_resumable_jobs", {})

if resumable["count"] > 0:
    # Offer to resume
    client.call_tool("resume_failed_job", {
        "job_id": resumable["resumable_jobs"][0]["job_id"],
        "username": "admin",
        "password": "cisco123"
    })

4.使用作业统计进行报告

stats = client.call_tool("get_job_stats", {"job_id": job_id})

# Generate user-friendly report
print(f"""
Network Discovery Complete:
- Devices discovered: {stats['results']['scanning']['reachable_hosts']}
- Identification rate: {stats['results']['fingerprinting']['identification_rate'] * 100}%
- Vendor breakdown:
  - Cisco: {stats['results']['vendors'].get('cisco', 0)}
  - Juniper: {stats['results']['vendors'].get('juniper', 0)}
  - Arista: {stats['results']['vendors'].get('arista', 0)}
- Configs collected: {stats['results']['config_collection']['configs_collected']}
""")

______________________________________________________________________

GitHub操作集成

该存储库包括从GitHub Actions运行网络发现的工作流。

设置

  1. 将您的设备凭据添加为GitHub Secrets:

- 前往“设置”>“秘密和变量”>“操作” - 添加 DEVICE_USERNAME - 添加 DEVICE_PASSWORD

  1. 使用工作流:

创建 .github/workflows/discover-network.yml:

name: Discover Network

on:
  workflow_dispatch:
    inputs:
      seed_host:
        description: "Seed device IP or hostname"
        required: true
        default: "192.168.1.1"
      platform:
        description: "Device platform"
        required: true
        default: "cisco_ios"
        type: choice
        options:
          - cisco_ios
          - cisco_nxos
          - juniper_junos
          - arista_eos

jobs:
  discover:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      
      - name: Start containers
        run: docker compose up -d
      
      - name: Wait for service
        run: |
          timeout 60 bash -c 'until curl -s http://localhost:8000/health; do sleep 2; done'
      
      - name: Validate credentials
        run: |
          curl -X POST http://localhost:8000/v1/credentials/validate \
            -H "Content-Type: application/json" \
            -d '{
              "seed_host": "${{ github.event.inputs.seed_host }}",
              "username": "${{ secrets.DEVICE_USERNAME }}",
              "password": "${{ secrets.DEVICE_PASSWORD }}",
              "platform": "${{ github.event.inputs.platform }}"
            }'
      
      - name: Run discovery
        run: |
          JOB_ID=$(curl -X POST http://localhost:8000/v1/seed \
            -H "Content-Type: application/json" \
            -d '{
              "seed_host": "${{ github.event.inputs.seed_host }}",
              "credentials": {
                "username": "${{ secrets.DEVICE_USERNAME }}",
                "password": "${{ secrets.DEVICE_PASSWORD }}",
                "platform": "${{ github.event.inputs.platform }}"
              },
              "methods": ["interfaces", "routing", "arp", "cdp"]
            }' | jq -r '.job_id')
          
          echo "JOB_ID=$JOB_ID" >> $GITHUB_ENV
          
          # Scan
          curl -X POST http://localhost:8000/v1/scan \
            -H "Content-Type: application/json" \
            -d "{\"job_id\": \"$JOB_ID\", \"ports\": [22, 443]}"
          
          # Fingerprint
          curl -X POST http://localhost:8000/v1/fingerprint \
            -H "Content-Type: application/json" \
            -d "{\"job_id\": \"$JOB_ID\"}"
          
          # Collect configs
          curl -X POST http://localhost:8000/v1/state/collect \
            -H "Content-Type: application/json" \
            -d "{
              \"job_id\": \"$JOB_ID\",
              \"credentials\": {
                \"username\": \"${{ secrets.DEVICE_USERNAME }}\",
                \"password\": \"${{ secrets.DEVICE_PASSWORD }}\",
                \"platform\": \"${{ github.event.inputs.platform }}\"
              }
            }"
          
          # Generate topology
          curl -X POST http://localhost:8000/v1/batfish/build \
            -H "Content-Type: application/json" \
            -d "{\"job_id\": \"$JOB_ID\"}"
          
          curl -X POST http://localhost:8000/v1/batfish/load \
            -H "Content-Type: application/json" \
            -d "{\"job_id\": \"$JOB_ID\"}"
          
          curl -X GET "http://localhost:8000/v1/batfish/topology/html?job_id=$JOB_ID" \
            -o topology.html
      
      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: network-discovery-results
          path: |
            topology.html
            /tmp/network_discovery_artifacts/${{ env.JOB_ID }}/

运行工作流

  1. 转到GitHub中的“操作”选项卡
  2. 选择“发现网络”
  3. 点击“运行工作流”
  4. 输入种子设备IP和平台
  5. 查看工作流工件中的结果

______________________________________________________________________

api参考

核心发现端点

方法端点描述
职位/v1/seed从设备启动seeder,创建targets.json
职位/v1/scan扫描现有作业中的目标
职位/v1/scan/from-subnets直接扫描特定子网
职位/v1/scan/add-subnets向现有作业添加子网
职位/v1/fingerprint指纹识别设备
职位/v1/state/collect收集设备配置
职位/v1/state/update/{hostname}重新收集单个设备配置

凭证管理端点

方法端点描述
职位/v1/credentials/validate在发现之前验证凭据
职位/v1/credentials/validate/batch针对多个设备进行验证

作业管理端点

方法端点描述
得到/v1/status/{job_id}获取作业状态和进度
得到/v1/jobs/resumable列出可以恢复的作业
职位/v1/jobs/resume恢复失败的作业

蝙蝠鱼终点

方法端点描述
职位/v1/batfish/build从配置构建蝙蝠鱼快照
职位/v1/batfish/load将快照加载到Batfish中
得到/v1/batfish/topology获取JSON格式的拓扑
得到/v1/batfish/topology/html生成交互式HTML可视化
得到/v1/batfish/networks列出所有网络
得到/v1/batfish/networks/{name}/snapshots列出网络快照
职位/v1/batfish/networks/{name}/snapshot/{snapshot}设置当前快照

数据检索端点

方法端点描述
得到/v1/scan/{job_id}获取扫描结果
得到/v1/scan/{job_id}/reachable仅获取可访问的主机
得到/v1/fingerprint/{job_id}获取指纹识别结果
得到/v1/state/{hostname}获取设备配置
得到/v1/artifacts/{job_id}/{filename}获取任何工件文件

系统端点

方法端点描述
得到/health基本健康检查
得到/ready准备状态检查与验证
得到/docs交互式API文档

______________________________________________________________________

MCP工具参考

播种机工具

seed_设备

  • 从种子设备启动网络发现
  • 参数:seed_host、凭据、方法、job_id
  • 返回:job_id、状态、targets_count

get_targets

  • 检索从种子设备收集的目标
  • 参数:job_id
  • 返回:具有IP和子网的目标数组

扫描工具

扫描目标

  • 扫描目标以查找打开的管理端口
  • 参数:job_id、端口、并发
  • 返回:hosts_scanned,hosts_rea可达

scan_from_subnets

  • 直接扫描特定子网(无需种子)
  • 参数:job_id、子网、端口、并发
  • 返回:hosts_scanned,hosts_rea可达

获取可访问的帖子

  • 从扫描结果中仅获取可访问的主机
  • 参数:job_id
  • 返回:可达主机数组

指纹识别工具

指纹设备

  • 确定设备供应商和型号
  • 参数:job_id、snmp_community(可选)
  • 返回:主机_指纹识别,标识_计数

get_fingerprint_results

  • 获取指纹识别结果
  • 参数:job_id
  • 返回:供应商提供的详细指纹数据

配置收集器工具

collect_device_config

  • 并行收集设备配置
  • 参数:job_id、凭据、并发性
  • 返回:设备计数、成功计数、失败计数

get_device_config

  • 获取特定设备的配置
  • 参数:job_id,主机名
  • 返回:设备配置JSON

蝙蝠鱼工具

build_batfish_snapshot

  • 根据收集到的配置构建蝙蝠鱼快照
  • 参数:job_id
  • 返回:snapshot_dir、device_count

load_batfish_snapshot

  • 将快照加载到Batfish中进行分析
  • 参数:job_id
  • 返回:网络名称、快照名称

get_topology

  • 获取JSON格式的网络拓扑
  • 参数:job_id或网络名称+快照名称
  • 返回:具有节点和边的拓扑图

生成拓扑可视化

  • 生成交互式HTML可视化
  • 参数:job_id或网络名称+快照名称
  • 返回:HTML文件的路径

凭证验证工具

validate_device_credentials

  • 快速证书测试(5-15秒)
  • 参数:seed_host、用户名、密码、平台
  • 返回:有效、latency_ms、供应商、platform_correct、错误、建议
  • 在开始昂贵的查找操作之前使用此选项

validate_credentials_multiple

  • 并行测试多个设备的凭据
  • 参数:设备数组、用户名、密码、并发性
  • 返回:总设备数、有效计数、无效计数、成功率、每台设备结果
  • 可用于跨不同设备类型测试凭据

工作简历工具

求职失败

  • 在不重新完成已完成工作的情况下恢复失败的工作
  • 参数:job_id、阶段(可选)、凭据
  • 返回:resumed_rom、phases_executed、summary
  • 对于大型网络至关重要-在部分故障时节省数小时

list_resumable_jobs

  • 获取可以恢复的作业列表
  • 参数:无
  • 返回:resumable_jobs数组,包含failed_phases和completed_phase
  • 有助于主动提出恢复失败的工作

监视工具

检查系统健康

  • 开始扫描前检查系统资源
  • 参数:无
  • 返回:CPU、内存、磁盘使用率、ready_for_scan状态
  • 在大型扫描之前使用,以确保系统容量

get_job_stats

  • 获取作业的详细统计数据
  • 参数:job_id
  • 返回:模块状态、扫描结果、供应商细分、时间
  • 用于进度监控和报告

get_recent_job_history

  • 分析最近的作业执行情况
  • 参数:小时(默认:24),限制(默认:50)
  • 返回:success_rate、failed_jobs、健康评估
  • 用于识别趋势和重复出现的问题

get_system_推荐

  • 获取智能建议和警告
  • 参数:无
  • 返回:警告、建议、quick_actions
  • 用于主动问题检测

工件工具

获取广告内容

  • 从作业目录检索任何工件文件
  • 参数:job_id,文件名
  • 返回:文件内容(文本或base64编码)
  • 支持HTML、JSON、文本和二进制文件

______________________________________________________________________

配置

环境变量

核心设置

  • ARTIFACT_DIR:作业工件目录(默认值: /tmp/network_discovery_artifacts)
  • DEFAULT_PORTS:要扫描的逗号分隔端口(默认值: 22,443)
  • DEFAULT_CONCURRENCY:并联操作限制(默认值: 200)
  • CONNECT_TIMEOUT:连接超时(秒)(默认值: 1.5)
  • LOG_LEVEL:记录详细程度(默认值: info)

蝙蝠鱼设置

  • BATFISH_HOST:蝙蝠鱼服务器主机名(默认值: batfish)
  • BATFISH_PORT:Batfish服务器端口(默认值: 9996)

服务器设置

  • HOST:服务器绑定地址(默认值: 0.0.0.0)
  • PORT:服务器端口(默认:REST: 8000,MCP: 8080)

MCP设置

  • ENABLE_MCP:启用MCP模式(默认: false)
  • TRANSPORT:运输类型 httphttps (默认值: http)
  • BASE_PATH:代理部署的URL基本路径(默认值: "")

Docker编写配置

该服务附带了两个Docker Compose文件:

docker-compose.yml (REST API模式)

services:
  network-discovery:
    environment:
      - ARTIFACT_DIR=/artifacts
      - DEFAULT_PORTS=22,443
      - DEFAULT_CONCURRENCY=200
      - BATFISH_HOST=batfish
    ports:
      - "8000:8000"
volumes:
      - ./artifacts:/artifacts

docker-compose.mcp.yml (MCP模式)

services:
  network-discovery-mcp:
    environment:
      - ENABLE_MCP=true
      - TRANSPORT=http
      - PORT=8080
      - ARTIFACT_DIR=/artifacts
      - BATFISH_HOST=batfish
    ports:
      - "8080:8080"
    volumes:
      - ./artifacts:/artifacts

您可以自定义这些文件或覆盖值:

# Override concurrency
DEFAULT_CONCURRENCY=400 docker compose up -d

# Use custom artifact directory
ARTIFACT_DIR=/var/network-discovery docker compose up -d

______________________________________________________________________

建筑

系统组件

网络发现MCP由六个主要模块组成:

  1. 播种机:连接到种子设备并发现网络拓扑

- 收集接口信息 - 检索路由表 - 收集ARP条目 - 通过CDP/LDP发现邻居 - 输出: targets.json, device_states/{host}.json

  1. 扫描仪:探测器发现了可达性目标

- 具有可配置并发性的并行端口扫描 - 测试管理端口(SSH、HTTPS等) - 输出: ip_scan.json, reachable.json

  1. 指纹识别器:确定设备供应商和型号

- 横幅分析 - SNMP探测(可选) - 模式匹配 - 输出: fingerprints.json

  1. 配置收集器:检索设备配置

- 多供应商支持(思科、瞻博网络、Arista等) - 具有重试逻辑的并行收集 - 凭证验证 - 输出: state/{hostname}.json

  1. 蝙蝠鱼装载机:准备网络进行分析

- 将配置转换为蝙蝠鱼格式 - 构建网络快照 - 装载到Batfish中进行分析 - 输出: batfish_snapshot/configs/{hostname}.cfg

  1. 拓扑可视化工具:生成交互式可视化

- 查询Batfish的拓扑数据 - 生成D3.js力定向图 - 输出: topology.html, topology.json

数据流

[Seed Device] 
    ↓
[Seeder] → targets.json
    ↓
[Scanner] → ip_scan.json, reachable.json
    ↓
[Fingerprinter] → fingerprints.json
    ↓
[Config Collector] → state/*.json
    ↓
[Batfish Loader] → batfish_snapshot/configs/*.cfg
    ↓
[Topology Visualizer] → topology.html

目录结构

network-discovery-mcp/
  ├── network_discovery/
│   ├── __main__.py              # Entry point (REST API or MCP mode)
│   ├── api.py                   # FastAPI REST endpoints
│   ├── mcp_server.py            # MCP tools implementation
│   ├── seeder.py                # Network discovery seeding
│   ├── scanner.py               # Port scanning
│   ├── fingerprinter.py         # Device identification
│   ├── config_collector.py      # Configuration collection
│   ├── batfish_loader.py        # Batfish integration
│   ├── topology_visualizer.py   # Visualization generation
│   ├── credential_validator.py  # Credential testing
│   ├── job_resume.py            # Job resumption logic
│   ├── metrics.py               # System monitoring
│   ├── artifacts.py             # File I/O operations
│   ├── config.py                # Configuration management
│   └── workers.py               # Async task coordination
├── tests/                       # Unit tests
├── Dockerfile                   # Container image definition
├── docker-compose.yml           # REST API deployment
├── docker-compose.mcp.yml       # MCP deployment
└── requirements.txt             # Python dependencies

工件存储结构

每个发现作业都会创建一个目录结构:

{ARTIFACT_DIR}/{job_id}/
├── targets.json                 # Discovered network targets
├── device_states/
│   └── {hostname}.json          # Per-device state from seeder
├── ip_scan.json                 # Full scan results
├── reachable.json               # Filtered reachable hosts
├── fingerprints.json            # Device identification results
├── state/
│   ├── {hostname1}.json         # Device configurations
│   ├── {hostname2}.json
  │   └── ...
├── batfish_snapshot/
│   └── configs/
│       ├── {hostname1}.cfg      # Batfish-format configs
│       ├── {hostname2}.cfg
  │       └── ...
├── topology.json                # Topology graph data
├── topology.html                # Interactive visualization
├── status.json                  # Job status tracking
└── error.json                   # Error details (if any)

所有文件写入都是原子性的(写入 .tmp,然后重命名)以防止损坏。

______________________________________________________________________

故障排除

服务无法启动

问题:容器无法启动

docker compose up -d
# Error: port already in use

解决方案:检查端口冲突

# Check what's using port 8000
lsof -i :8000

# Use different port
PORT=8001 docker compose up -d

______________________________________________________________________

身份验证失败

问题:所有设备身份验证失败

Error: Authentication failed for all devices

解决方案:首先验证凭据

# Test credentials before discovery
curl -X POST http://localhost:8000/v1/credentials/validate \
  -H "Content-Type: application/json" \
  -d '{
    "seed_host": "192.168.1.1",
      "username": "admin",
    "password": "your_password",
    "platform": "cisco_ios"
  }'

# Check response for specific error
{
  "valid": false,
  "error": "Authentication failed - invalid username or password",
  "suggestion": "Verify credentials for user 'admin' on this device"
}

______________________________________________________________________

配置收集期间作业失败

问题:收集某些配置后作业失败

Status: 200/450 configs collected, then failure

解决方案:恢复作业,而不是重新启动

# List resumable jobs
curl http://localhost:8000/v1/jobs/resumable

# Resume the failed job
curl -X POST http://localhost:8000/v1/jobs/resume \
  -H "Content-Type: application/json" \
  -d '{
    "job_id": "net-disc-123",
    "credentials": {"username": "admin", "password": "pass"}
  }'

# This will retry only the 250 failed devices

______________________________________________________________________

缓慢发现

问题:发现耗时太长

解决方案:检查系统资源

# Check system health
curl http://localhost:8000/v1/health

# Check specific job statistics
curl http://localhost:8000/v1/status/{job_id}

# Reduce concurrency if CPU high
curl -X POST http://localhost:8000/v1/scan \
  -H "Content-Type: application/json" \
  -d '{"job_id": "...", "concurrency": 50}'

______________________________________________________________________

蝙蝠鱼连接问题

问题:拓扑生成失败

Error: Cannot connect to Batfish

解决方案:验证蝙蝠鱼集装箱

# Check Batfish is running
docker compose ps

# Check Batfish logs
docker compose logs batfish

# Restart if needed
docker compose restart batfish

# Wait for Batfish to initialize
sleep 30

______________________________________________________________________

大型网络超时

问题:大型子网超时

解决方案:增加超时或缩小范围

# Increase timeout
CONNECT_TIMEOUT=5.0 docker compose up -d

# Or scan in smaller batches
curl -X POST http://localhost:8000/v1/scan/from-subnets \
  -H "Content-Type: application/json" \
  -d '{
    "job_id": "batch1",
    "subnets": ["192.168.1.0/24"],
    "concurrency": 100
  }'

______________________________________________________________________

查看日志

对于调试,请检查容器日志:

# REST API mode
docker compose logs -f network-discovery

# MCP mode
docker compose -f docker-compose.mcp.yml logs -f network-discovery-mcp

# Just errors
docker compose logs network-discovery | grep ERROR

# Specific time range
docker compose logs --since 30m network-discovery

______________________________________________________________________

获得帮助

如果您遇到此处未涵盖的问题:

  1. 检查日志: docker compose logs network-discovery
  2. 查看作业状态: curl http://localhost:8000/v1/status/{job_id}
  3. 检查系统建议:使用 get_system_recommendations MCP工具
  4. 查看中的工件文件 {ARTIFACT_DIR}/{job_id}/

______________________________________________________________________

其他资源

  • API文档: http://localhost:8000/docs(交互式Swagger用户界面)
  • GitHub发布: https://github.com/username/network-discovery-mcp/releases(版本历史和变更日志)

______________________________________________________________________

许可证

此项目根据LICENSE文件中指定的条款获得许可。

目录标签

目录标签

PythonClaude配置管理网络映射本地部署自动化发现拓扑可视化多厂商支持

支持客户端

Claude DesktopClaudeCline

接入字段

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

stdio

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

token

运行时(runtime,运行环境)

Docker

工具数量(toolCount,工具数)

22

资源数量(resourceCount,资源数)

0

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

0

权限和风险

stdiotoken部署方式未说明

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

安装前确认

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

来源信息

继续浏览同类 MCP