mcpField
B
batfish-q-mcp

batfish-q-mcp

本地服务
github.com/martimy云与基础设施01 天前更新

关于 batfish-q-mcp

batfish-q-mcp 是通过 Batfish 查询网络配置快照的 MCP 服务,面向网络运维人员和 AI 助手。它提供精选问题、断言、故障模拟和拓扑数据,无需手动编写 Batfish 查询。

主要功能

  1. 01运行精选的 60 个 Batfish 问题
  2. 02执行单条断言或 YAML 断言套件
  3. 03模拟节点或接口故障并派生快照
  4. 04通过差异问题比较快照
  5. 05返回三层和路由拓扑

适用场景

  1. 01检查配置解析情况和路由属性
  2. 02针对快照运行网络断言
  3. 03评估节点或接口故障后的可达性
  4. 04查看三层或 BGP 路由拓扑

MCP 相关

将 Batfish 快照、问题、断言、故障模拟和拓扑操作作为 MCP 工具提供。stdio 服务连接正在运行的 Batfish 实例,并向 MCP 客户端返回结构化结果。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"martimy-batfish-q": {
"command": "uvx",
"args": [
"batfish-q-mcp"
],
"env": {
"BATFISH_SERVER": "<BATFISH_SERVER>"
}
}
}
}
启动命令uvx batfish-q-mcp
需要配置的环境变量
BATFISH_SERVERHost of the Batfish server (default 127.0.0.1)

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypibatfish-q-mcp0.2.0

工具

9

收录的工具列表 · 更新于 今天

参数类型必填说明
categoryany否

详细介绍

batfish-q-mcp

一个 MCP(Model Context Protocol)服务,可将 Batfish 作为工具提供给 AI 助手。将它指向网络配置快照,即可使用自然语言提问,无需自行编写 Batfish 查询。

借助它,助手可以:

  • 执行 60 个精选 Batfish 问题中的任意一个(节点属性、路由、ACL、可达性、解析问题等)
  • 执行断言,例如“无转发环路”,可以单独执行,也可以作为 YAML 套件执行
  • 分叉快照,将节点或接口标记为故障,并将结果与原始快照进行差异比较
  • 将第 3 层和路由拓扑作为节点和边返回

该项目衍生自 Bat-Q,一个基于 Batfish 的 Streamlit GUI。请参阅致谢。

示例提示词

将服务连接到 MCP 客户端并加载快照后,可以尝试:

  • “列出快照,并告诉我配置是否都已成功解析。”
  • “此快照中是否存在转发环路?”
  • “显示第 3 层拓扑。”
  • “如果 r1 故障,从 r2 到 r3 的可达性会怎样?”
  • “哪些节点配置了 BGP,它们的对等体有哪些?”

在幕后,助手会调用下方列出的工具。

快速开始

1. 启动 Batfish

服务需要一个正在运行的 Batfish 实例。最快的方式是使用 Docker:

docker run --rm -p 9996:9996 -p 9997:9997 batfish/allinone

服务默认连接到 127.0.0.1。如果 Batfish 在其他位置运行,请设置 BATFISH_SERVER(例如 BATFISH_SERVER=<batfish-host>)。

2. 安装 batfish-q-mcp

需要 Python >=3.10。

git clone https://github.com/martimy/batfish-q-mcp.git
cd batfish-q-mcp

# Recommended: use a virtual environment
python3 -m venv .batmcp
source .batmcp/bin/activate
pip install -e .

其他方式:

pip install -r requirements.txt
pip install -e ".[dev]"   # includes test dependencies

此操作会安装一个控制台脚本 batfish-q-mcp,通过 stdio 启动 MCP 服务。

3. 连接 MCP 客户端
Claude Desktop、Cursor 和其他 stdio 客户端
{
  "mcpServers": {
    "batfish-q-mcp": {
      "command": "batfish-q-mcp",
      "env": { "BATFISH_SERVER": "127.0.0.1" }
    }
  }
}

如果安装在虚拟环境中,请改用脚本的绝对路径 (激活环境后运行 which batfish-q-mcp 即可查找):

{
  "mcpServers": {
    "batfish-q-mcp": {
      "command": "/path/to/batfish-q-mcp/.batmcp/bin/batfish-q-mcp",
      "env": { "BATFISH_SERVER": "127.0.0.1" }
    }
  }
}

重启客户端,使其加载新服务。

OpenCode

OpenCode 使用 opencode.json(架构 https://opencode.ai/config.json),其中包含 mcp.servers、type: "local",且 command 以数组形式给出:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "servers": {
      "batfish-q-mcp": {
        "type": "local",
        "command": ["/path/to/batfish-q-mcp/.batmcp/bin/batfish-q-mcp"],
        "environment": {
          "BATFISH_SERVER": "127.0.0.1"
        }
      }
    }
  }
}

将文件放在项目根目录(或 ~/.config/opencode/),然后从该目录启动或 重启 OpenCode,使其重新加载 MCP 服务。

注意: OpenCode Code Mode 会隔离工具。没有直接的 batfish_* 工具;请通过 execute 工具调用,例如:

await tools["batfish-q-mcp"].batfish_list_questions({});
4. 加载快照并提问

将配置打包为快照 zip(请参阅提供快照), 放入工作区,并告诉助手文件名。助手会上传快照并运行你提出的问题。

新启动的服务进程尚未设置 Batfish 网络。首次调用需要快照时,请传入 network (例如 "NETWORK");此后该设置会在进程运行期间一直生效。不传入 network 调用 batfish_list_snapshots 会失败,并报错 Network must be set。

手动运行服务(可选)

要在客户端之外检查服务是否能启动:

export BATFISH_SERVER=127.0.0.1
batfish-q-mcp
# or
python -m batfish_mcp.server

该服务使用 stdio JSON-RPC(FastMCP)通信,不会向 stdout 输出日志。

提供快照

  • 格式: 一个包含配置的 Batfish zip,可选包含 batfish/ 和 hosts/ 文件夹。 例如,abc_net.zip 包含 abc_net/configs/R1.cfg、R2.cfg、R3.cfg、FW.cfg 和 hosts/server_*.json。

  • 位置: 将 zip 放入工作区,并告知助手文件名。

  • 上传: 助手会对 zip 进行 base64 编码,并调用 batfish_upload_snapshot(name, zip_base64, network?, overwrite?)。

    • name 会经过清理(safe_snapshot_name)。除非 overwrite=true,否则同名冲突时会生成唯一名称(name_1、……)。
    • zip_base64 必须是有效的 base64,且填充正确(= 或 ==)。服务端会强制校验。
  • 已在 Batfish 服务上: 告知助手 snapshot 和 network 名称;无需上传。

  • Shell 访问: 你也可以使用 pybatfish 直接上传:

    PYTHONPATH=src python3 - <<'PY'
    import os
    from pybatfish.client.session import Session
    bf = Session(host=os.getenv("BATFISH_SERVER", "127.0.0.1"))
    bf.set_network("NETWORK")
    bf.init_snapshot("abc_net.zip", name="abc_net", overwrite=True)
    print(bf.list_snapshots())
    PY
    

工具

该服务提供 9 个工具。batfish_run_question 可访问完整的 60 个问题目录。

工具描述
batfish_list_questions(category?)精选的 60 个问题目录,包含输入类型和 TYPE_HINTS 描述。无需 Batfish 服务。
batfish_list_snapshots(network?)某个网络的快照。
batfish_upload_snapshot(name, zip_base64, network?, overwrite?)上传快照 zip(base64)。名称会经过清理(safe_snapshot_name);同名冲突时会生成唯一名称(name_1、……)。
batfish_run_question(fun, options?, snapshot?, reference_snapshot?, network?)运行目录中的任意问题。提供 reference_snapshot 和 snapshot 可运行差异问题。返回 JSON 安全格式的 {fun, snapshot, reference_snapshot, status, rows, removed_columns}。
batfish_list_assertions()实时 pybatfish 断言名称,以及包含参数描述的 16 项注册表(specs)。
batfish_run_assertion(name, params?, question?, snapshot?, network?)校验并运行一条断言(基于答案的断言会先获取答案)。返回 {type, status, message, snapshot, ran_at, runtime, fun?, answer_rows?}。
batfish_run_assertion_suite(suite_yaml, snapshot?, network?)校验(全有或全无)并运行 YAML 套件;examples/assertions.yaml 展示了其架构。返回 results[]、errors[]、summary。
batfish_fork_snapshot(base_name, name?, failed_nodes?, failed_interfaces?, overwrite?, network?)派生一个快照,可选择使节点或接口失效,然后通过差异问题将派生快照与基础快照进行比较。
batfish_get_topology(kind, snapshot?, network?)kind="layer3"(来自 layer3Edges,包含接口标题)或 "routing"(来自 bgpEdges)。返回 {kind, snapshot, node_count, edge_count, nodes, edges}。

所有工具共用一个 Batfish 会话(batfish_mcp.session,使用 BATFISH_SERVER,默认值为 127.0.0.1),并通过锁进行串行化。

工具调用示例

供参考,当你提出示例提示词时,助手大致会这样调用。 上传 abc_net.zip,然后:

batfish_upload_snapshot(name="abc_net.zip", zip_base64="UEsDBB==", network="NETWORK")
batfish_run_question(fun="nodeProperties", snapshot="abc_net")
batfish_run_assertion(name="assert_no_forwarding_loops", snapshot="abc_net")
batfish_fork_snapshot(base_name="abc_net", failed_nodes=["r1"])
batfish_run_question(fun="differentialReachability",
    options={"pathConstraints": {"startLocation": "r2", "endLocation": "r3"},
             "headers": {"dstIps": "192.168.3.1"}},
    snapshot="abc_net_Fail", reference_snapshot="abc_net")

拓扑:

batfish_get_topology(kind="layer3", snapshot="abc_net", network="NETWORK")
batfish_get_topology(kind="routing", snapshot="abc_net", network="NETWORK")

在 OpenCode 中,将这些调用包装在 execute 中,例如:

await tools["batfish-q-mcp"].batfish_run_question({
  fun: "initIssues", snapshot: "abc_net", network: "NETWORK"
});

更详细的操作指南请参阅 HOW-TO.md。

故障排除

  • Network must be set:在首次调用时传入 network="NETWORK"。
  • zip_base64 is not valid base64: Incorrect padding:使用 base64 -w 0 abc_net.zip 重新编码(不换行),并保留末尾的 = 或 ==。不要手动删除。
  • 快照已存在:传入 overwrite: true,或接受 name_1 后缀。
  • 没有解析问题但 IP 不正确? 先运行 batfish_run_question(fun="initIssues") 和 fileParseStatus。
  • 无法访问 240.254.254.1,但可以访问 8.8.8.8:240.0.0.0/4 是保留地址段,ISP 的出口过滤器(例如 Block outgoing traffic using reserved addresses)会丢弃发往该地址段的流量。请使用公网 IP 测试互联网出口。

目录结构

src/batfish_mcp/
  server.py           # FastMCP tools over the headless core
  session.py          # thread-safe singleton Session
  catalog.py          # curated question catalog (60 questions)
  assertion_specs.py  # assertion registry (params as {name, type, optional})
  assertion_io.py     # assertion YAML load/validate/dump
  assertions.py       # assertion runner (session- vs answer-based, PASS/FAIL/ERROR)
  queries.py          # question runner (incl. differential snapshots)
  utils.py            # snapshot-name sanitizing, template helpers
  presenter.py        # pure DataFrame/trace serialization helpers
  hints.py            # TYPE_HINTS: tool-parameter descriptions
  topology.py         # L3 + routing graph construction from answers
tests/
  fakes.py            # FakeBatfish + assertion fake (no server needed)
  test_queries.py
  test_assertions.py
  test_server.py      # MCP tools + wire round-trip
examples/assertions.yaml
HOW-TO.md             # mini tutorial

测试

pip install -e ".[dev]"
pytest          # no Batfish server required (fakes + one in-memory MCP round-trip)

tests/test_assertions.py 还会检查 assertion_specs.py 是否与已安装的 pybatfish 保持同步 (脚本化断言签名)。

致谢

batfish-q-mcp 最初是 Bat-Q 的衍生项目;Bat-Q 是一个基于 Batfish 的 Streamlit GUI。可复用的无头核心(问题目录、 断言注册表和运行器、答案序列化、快照工具)源自该项目;GUI 层已移除,并替换为 MCP 传输层。 两个项目均采用 Apache-2.0 许可证。

许可证

Apache-2.0(见 LICENSE)。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。