mirror of
https://github.com/hansjone/netx.git
synced 2026-10-18 07:40:50 +08:00
MCP: serve tools from the API process over Streamable HTTP at /mcp
- netx_api/mcp_remote: ops / topology / bizMonitor tools, Bearer auth, per-tool RBAC filtering, ?groups= filter, readOnlyHint and group meta. - Mount the official MCP Streamable HTTP app at /mcp (stateless); AuthAuditMiddleware is pure ASGI and skips /mcp. - Let uvicorn chunk MCP responses; some Windows LSPs rewrite Content-Length replies on */mcp* paths into broken chunked framing. - NETX_MCP_ALLOWED_HOSTS opts into DNS-rebinding checks (off by default so LAN and reverse-proxy hosts work; Bearer is the gate). - Remove the three stdio Python MCP packages; tests moved to /mcp, including real-TCP framing regressions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
918ece86c3
commit
52679a7cfc
150 changed files with 2367 additions and 2812 deletions
263
docs/MCP.md
263
docs/MCP.md
|
|
@ -1,249 +1,64 @@
|
|||
# netx MCP — 安装与更新
|
||||
# netx 远程 MCP(Streamable HTTP)
|
||||
|
||||
netx 通过 **stdio MCP** 把告警/网元能力暴露给 Cursor、Claude Desktop、oclaw 等宿主。MCP 进程只做 HTTP 客户端,**不直连数据库**;数据来自已运行的 netx REST API。
|
||||
netx API 在同一端口(默认 `8890`)提供 `/mcp` 端点,使用 MCP **Streamable HTTP** 传输。客户端(Claude Code、Codex、Cursor、DSH netxops)只需配置 URL 与 Bearer token,**无需安装 Python MCP 包**。
|
||||
|
||||
## 架构
|
||||
|
||||
```
|
||||
MCP 宿主 (Cursor / oclaw) → stdio netx_mcp → HTTP NETX_API_URL → netx API
|
||||
MCP 宿主 → HTTP http://127.0.0.1:8890/mcp → netx_api.mcp_remote(进程内工具)
|
||||
```
|
||||
|
||||
| 组件 | 部署位置 | 说明 |
|
||||
|------|----------|------|
|
||||
| **netx API** | 本机或远端服务器 | `python -m netx_api.main`,默认 `http://127.0.0.1:8890` |
|
||||
| **netx-mcp** | 与 MCP 宿主同机 | `pip install` 轻量包,仅需 Python + httpx |
|
||||
工具分组(查询参数 `groups`):
|
||||
|
||||
---
|
||||
| groups | 工具数 | 说明 |
|
||||
|--------|--------|------|
|
||||
| `ops` | 15 | 告警 / 网元 / 只读 CLI |
|
||||
| `topology` | 16 | 拓扑树 / 画布 / Fabric / 布局 |
|
||||
| `bizMonitor` | 8 | 割接与业务状态只读 |
|
||||
| (省略) | 39 | 当前 token 有权限的全部工具 |
|
||||
|
||||
## 前置条件
|
||||
示例:`/mcp?groups=ops,bizMonitor`
|
||||
|
||||
1. **netx API 已启动**且可访问:
|
||||
## 鉴权
|
||||
|
||||
```powershell
|
||||
curl http://127.0.0.1:8890/health
|
||||
```
|
||||
- Header:`Authorization: Bearer <token>`
|
||||
- 接受 MCP 令牌(`NETX_AUTH_MCP_TOKEN_FILE`,bootstrap 写入)或用户 JWT
|
||||
- 无 token / 无效 → HTTP **401**
|
||||
- `tools/list` 只列出当前 token 有 scope 的工具;`tools/call` 再按 RBAC 校验
|
||||
|
||||
2. **Python 3.11+**(与 MCP 宿主使用的 `python` 一致)。
|
||||
## 客户端配置
|
||||
|
||||
3. 远端 API 时:记下 base URL(无尾部 `/`),例如 `http://10.0.0.5:8890`。
|
||||
见根目录 [`mcp.all.json`](../mcp.all.json)。Claude Code 示例:
|
||||
|
||||
---
|
||||
|
||||
## 1. 安装 `netx-mcp` 包
|
||||
|
||||
在 **运行 MCP 的那台机器**上执行(不必安装整套 netx 服务依赖):
|
||||
|
||||
```powershell
|
||||
cd D:\project\chatgpt\netx
|
||||
pip install -e ./packages/netx-mcp
|
||||
```bash
|
||||
claude mcp add --transport http netx http://127.0.0.1:8890/mcp \
|
||||
--header "Authorization: Bearer <token>"
|
||||
```
|
||||
|
||||
验证(**必须用 oclaw 启动时会调用的同一个 `python`**,见下方说明):
|
||||
仅 ops:
|
||||
|
||||
```powershell
|
||||
where python
|
||||
python -c "import netx_mcp; print('ok')"
|
||||
python -m netx_mcp
|
||||
```text
|
||||
http://127.0.0.1:8890/mcp?groups=ops
|
||||
```
|
||||
|
||||
若你在 A 终端里 `import netx_mcp` 成功,但 oclaw Admin 安装/Health 无反应或失败,多半是 **pip 装到了另一个 Python**。请用 oclaw 实际用的解释器安装:
|
||||
## 语言
|
||||
|
||||
```powershell
|
||||
# 把路径换成 where python 的第一条,或 oclaw 服务 venv 里的 python.exe
|
||||
C:\Path\To\Same\python.exe -m pip install "git+https://github.com/hansjone/netx.git#subdirectory=packages/netx-mcp"
|
||||
C:\Path\To\Same\python.exe -c "import netx_mcp; print('ok')"
|
||||
```
|
||||
- 环境变量 `NETX_LANG=zh|en`,或请求头 `Accept-Language`
|
||||
- 工具 `description` / `inputSchema` 与历史 Python 包一致;`en` 时 API 查询附加 `lang=en`
|
||||
|
||||
从 GitHub 安装(无本地仓库时,**子目录必须是 `packages/netx-mcp`**):
|
||||
## 安全
|
||||
|
||||
```powershell
|
||||
pip install "git+https://github.com/hansjone/netx.git#subdirectory=packages/netx-mcp"
|
||||
```
|
||||
- `execManagedNe` 等写工具带 `annotations.readOnlyHint=false`
|
||||
- CLI 硬门(`cli_guard`):仅单行 `show`/`display`,拒绝 shell 与破坏性命令
|
||||
- 异步 exec / layout job:先返回 job id,再用轮询工具查询
|
||||
|
||||
开发者在 netx 仓库根目录也可 `pip install -e .`(含 API);MCP 仍推荐只装 `packages/netx-mcp`。
|
||||
## 版本
|
||||
|
||||
---
|
||||
`initialize.serverInfo.version` 使用 netx 包版本(`pyproject.toml` / `netx-ops`)。
|
||||
|
||||
## 2. 环境变量
|
||||
无状态模式下不主动推送 `notifications/tools/list_changed`;客户端应在需要时重新 `tools/list`。
|
||||
|
||||
| 变量 | 必填 | 默认 | 说明 |
|
||||
|------|------|------|------|
|
||||
| `NETX_API_URL` | 否 | `http://127.0.0.1:8890` | netx REST 根地址,可指向远端 |
|
||||
| `NETX_API_TOKEN` | 否 | 空 | Bearer;空则自动读 `data/auth/mcp_token`(API 首次启动生成) |
|
||||
| `NETX_MCP_TOKEN_FILE` | 否 | `data/auth/mcp_token` | 默认 token 文件路径 |
|
||||
| `NETX_LANG` | 否 | `zh` | `zh` / `en`,影响 API 文案 |
|
||||
| `NETX_NE_EXEC_MAX_COMMANDS` | 否 | `5` | `execManagedNe` 单次最多命令数(硬上限 50);API 与 MCP 需同设 |
|
||||
| `NETX_NE_EXEC_ASYNC_MIN_NES` | 否 | `4` | 批量 NE 数 ≥ 此值时自动走后台 job(`0`=仅 `async=true`) |
|
||||
| `NETX_NE_EXEC_JOB_DIR` | 否 | `data/ne_exec_jobs` | 后台 exec job 状态目录 |
|
||||
| `NETX_NE_EXEC_JOB_MAX_CONCURRENT` | 否 | `3` | 同时运行的 exec job 上限 |
|
||||
## 相关文档
|
||||
|
||||
本机默认端口时 **可不设任何变量**。启用登录后,先启动一次 netx API,会生成 `data/auth/mcp_token`;MCP 会自动带上该 token。若要把 token 写进 Cursor 配置:
|
||||
|
||||
```json
|
||||
"NETX_API_TOKEN": "nxt_从文件复制的内容"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 在 Cursor / Claude Desktop 中配置
|
||||
|
||||
复制仓库中的 [`mcp.json`](../mcp.json)(或 [`packages/netx-mcp/mcp.json`](../packages/netx-mcp/mcp.json))到客户端 MCP 配置,例如 Cursor:`.cursor/mcp.json`。
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"netx": {
|
||||
"command": "python",
|
||||
"args": ["-m", "netx_mcp"],
|
||||
"env": {
|
||||
"NETX_API_URL": "http://127.0.0.1:8890",
|
||||
"NETX_LANG": "zh",
|
||||
"PYTHONIOENCODING": "utf-8",
|
||||
"PYTHONUTF8": "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
(可选)显式设置 `"NETX_API_TOKEN": "nxt_..."`;不设则读仓库/`cwd` 下的 `data/auth/mcp_token`。
|
||||
|
||||
保存后 **重启 Cursor/客户端**,使 MCP 子进程重新拉起。
|
||||
|
||||
---
|
||||
|
||||
## 4. 在 oclaw Admin 中安装
|
||||
|
||||
与 Cursor **同一份** `mcpServers` JSON 即可,无需转成别的格式。
|
||||
|
||||
1. 完成上文 **§1**(用 **oclaw 同机同一个 `python`** 安装 `netx-mcp`)。
|
||||
2. Admin → MCP → 粘贴 `mcp.json` 全文 → 点击 **Install from JSON**(安装状态在下方一行小字)。
|
||||
3. **Health** → **Sync Tools**(完整 scope 下应看到 **15** 个工具)。
|
||||
4. 在 **MCP 专家绑定** 中为 ops 专家勾选 `server_id=netx`。
|
||||
|
||||
更细的 oclaw 说明(双轨内置工具、锚点注入等)见 oclaw 仓库:
|
||||
`oclaw/docs/NETX_MCP_INTEGRATION.md`。
|
||||
|
||||
可选:oclaw 专用字段展开版 [`mcp_install_payload.json`](../mcp_install_payload.json)(与 `mcp.json` 等价)。
|
||||
|
||||
**Skills(真源)**:仓库根 [`skills/`](../skills/README.md) — `netx-ops` / `netx-topology` (ops = NMS + managed CLI)。MCP 包不再带 skills 镜像;Cursor 直接指 `netx/skills/`。dsh-netxops 发版前可 `sync-skills-from-netx.ps1`。oclaw 旧 playbook 不再维护。
|
||||
|
||||
**拓扑画布 MCP**(独立安装/绑定)见 [`MCP_TOPOLOGY.md`](./MCP_TOPOLOGY.md)(`server_id=netx-topology`)。
|
||||
|
||||
---
|
||||
|
||||
## 5. 暴露的工具
|
||||
|
||||
模型面使用通用 **Nms** 命名(当前适配器仍为 zte-ume,HTTP 仍 `/v1/ume/*`)。**0.3.0** 起不再暴露 `*Ume*` 工具名。
|
||||
|
||||
| 类别 | 工具名 |
|
||||
|------|--------|
|
||||
| NMS 告警 | `queryNmsAlarms`, `aggregateNmsAlarms`, `runNmsDiagnostics` |
|
||||
| NMS 网元 | `queryNmsNeInventory`, `getNmsNe` |
|
||||
| NMS 原始/SQL | `queryNmsAlarmsRaw`, `aggregateNmsAlarmsRaw`, `listNmsAlarmFields`, `sqlQueryNms` |
|
||||
| common(CLI + 路径) | `listManagedNe`, `getManagedNe`, `execManagedNe`, `getNeExecJob`, `listCliTargets`, `findTopologyPaths` |
|
||||
|
||||
参数使用 `nms_ne_id` / `nms_ne_ids`,旧 `ume_*` 模型参数已删除;`getManagedNe` 只接受 `ne_id`。拓扑 Fabric / 画布工具在 **[`netx-topology-mcp`](./MCP_TOPOLOGY.md)**。oclaw 中名称带前缀:`mcp__netx__<toolName>`;DSH:`netx__<toolName>`。
|
||||
|
||||
**业务监控 / 割接分析**:独立 [`netx-bizmonitor-mcp`](./MCP_BIZMONITOR.md) 提供 8 个工具,需 `biz-monitor:read`;netxops 的 bizMonitor 组使用相同 stem。三组统一配置见根 [`mcp.all.json`](../mcp.all.json),不需要安装 netxops。
|
||||
|
||||
**CLI 安全边界**:独立 MCP 强制单行只读 `show` / `display`,可用只读输出过滤;配置、shell 操作符、重定向和多行脚本在 HTTP 前拒绝。后端开放 exec_policy 或 capability 的脚本提示也不能解除这个 MCP 门禁,Linux/RouterOS 原生 CLI 当前未暴露。异步 job_id 仅表示开始,按 poll_after_ms 有界轮询;terminal 后检查 result.ok,批量还须检查 summary.failed 和每条 results[].ok,不能只凭作业 succeeded 宣称全部成功。
|
||||
|
||||
---
|
||||
|
||||
## 6. 更新 MCP
|
||||
|
||||
MCP 代码在 **`packages/netx-mcp`**(版本见 `packages/netx-mcp/pyproject.toml`)。更新步骤:
|
||||
|
||||
### 6.1 重装 `netx-mcp` 包
|
||||
|
||||
**远程 MCP 机 / 无本地 netx 仓库**(不必 `git pull`,每次更新执行一条即可):
|
||||
|
||||
```powershell
|
||||
pip install --upgrade "git+https://github.com/hansjone/netx.git#subdirectory=packages/netx-mcp"
|
||||
```
|
||||
|
||||
**本机有 netx 仓库(开发)**:
|
||||
|
||||
```powershell
|
||||
cd D:\project\chatgpt\netx
|
||||
git pull
|
||||
pip install -e ./packages/netx-mcp
|
||||
```
|
||||
|
||||
确认版本(可选):
|
||||
|
||||
```powershell
|
||||
pip show netx-mcp
|
||||
```
|
||||
|
||||
### 6.2 重启 MCP 宿主
|
||||
|
||||
| 宿主 | 操作 |
|
||||
|------|------|
|
||||
| **Cursor / Claude** | 完全退出客户端后重开,或重载 MCP |
|
||||
| **oclaw** | 重启 gateway/主进程;Admin 对 `netx` 再点 **Health** → **Sync Tools** |
|
||||
|
||||
仅改 `NETX_API_URL` 等 env 时,同样需重启 MCP 子进程(或 oclaw 整进程)。
|
||||
|
||||
### 6.3 无需改配置的情况
|
||||
|
||||
- 只改 **netx API** 业务逻辑、未改 MCP 工具名/参数:重装 `netx-mcp` 可选;API 部署后 MCP 自动走新 API。
|
||||
- 改了 **工具列表或 JSON schema**:必须重装 `netx-mcp` 并在宿主 **Sync Tools**。
|
||||
|
||||
### 6.4 从旧入口迁移
|
||||
|
||||
| 旧方式 | 新方式 |
|
||||
|--------|--------|
|
||||
| `python -m netx_api.mcp` | `python -m netx_mcp`(唯一 Python 模块入口) |
|
||||
| `NETX_MCP_MODE=db` 直连库 | 已废弃;使用 HTTP 模式 |
|
||||
|
||||
旧入口 `netx_api.mcp`、`netx_api/mcp_server.py` 和 `NETX_MCP_MODE=db` 已删除。请安装独立 `netx-mcp` 包并迁移配置;不再保留兼容委托。旧 DB 模式独有的导入告警查询/聚合/批次/诊断、同步触发、历史告警查询仍有 HTTP API,但不属于当前 ops 15 工具。
|
||||
|
||||
---
|
||||
|
||||
## 7. 自检
|
||||
|
||||
**API:**
|
||||
|
||||
```powershell
|
||||
curl http://127.0.0.1:8890/health
|
||||
```
|
||||
|
||||
**MCP 工具列表(需已 `pip install -e packages/netx-mcp`):**
|
||||
|
||||
```powershell
|
||||
cd D:\project\chatgpt\netx
|
||||
python -m pytest packages/netx-mcp/tests/test_mcp_http.py -q
|
||||
```
|
||||
|
||||
**手动 stdio(PowerShell 示例):**
|
||||
|
||||
```powershell
|
||||
$env:NETX_API_URL = "http://127.0.0.1:8890"
|
||||
$p = Start-Process python -ArgumentList "-m","netx_mcp" -RedirectStandardInput pipe -RedirectStandardOutput pipe -NoNewWindow -PassThru
|
||||
# 向 stdin 写入一行 JSON-RPC initialize / tools/list(见 packages/netx-mcp/tests)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 常见问题
|
||||
|
||||
| 现象 | 处理 |
|
||||
|------|------|
|
||||
| `ModuleNotFoundError: netx_mcp` | 用 **oclaw 同机同一个 `python.exe`** 执行 pip 安装(见 §1 验证) |
|
||||
| **oclaw Admin 点安装「没反应」** | 1) 必须点 **Install from JSON**(只粘贴不点按钮无效)<br>2) 看安装区下方 **install status** 一行字(应出现 `[json] installing...` 或错误)<br>3) 浏览器 F12 → Console 是否有红色报错<br>4) 确认 JSON 为完整 `mcpServers` 或 `mcp_install_payload.json` 格式 |
|
||||
| oclaw preflight `mcp_python_module_missing` | `python` 在 PATH 里但无 `netx_mcp`;对该 python 执行 git+pip 安装 |
|
||||
| 工具调用连不上 API | 检查 `NETX_API_URL`、防火墙、远端 API 是否启动 |
|
||||
| Windows 乱码 / JSON 解析失败 | 配置里保留 `PYTHONIOENCODING=utf-8`、`PYTHONUTF8=1`(见 `mcp.json`) |
|
||||
| oclaw 工具数为 0 | Admin **Health → Sync Tools**;确认 `server_id=netx` 已绑定 ops 专家 |
|
||||
| 旧脚本路径或模块不存在 | 安装 `packages/netx-mcp`,配置改为 `"args": ["-m", "netx_mcp"]` |
|
||||
|
||||
---
|
||||
|
||||
## 相关文件
|
||||
|
||||
| 文件 | 用途 |
|
||||
|------|------|
|
||||
| [`packages/netx-mcp/`](../packages/netx-mcp/) | MCP 实现与 `pyproject.toml` |
|
||||
| [`mcp.json`](../mcp.json) | Cursor / oclaw 粘贴用配置 |
|
||||
| [`mcp_install_payload.json`](../mcp_install_payload.json) | oclaw 字段展开版(可选) |
|
||||
| [`packages/netx-mcp/README.md`](../packages/netx-mcp/README.md) | 子包速查 |
|
||||
- [MCP_TOPOLOGY.md](./MCP_TOPOLOGY.md) — topology 组工具说明
|
||||
- [MCP_BIZMONITOR.md](./MCP_BIZMONITOR.md) — bizMonitor 组工具说明
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue