Files

69 lines
4.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 迭代 18 技术实现方案:QMT Bridge MCP 能力内建
> 依据:R-0202026-09-08 定稿,Q1-Q6 + 老师澄清:移除三方 dsh-skill-mcp-panel、官方 dsh-mcp-client 可依赖)| PLAN-018
> 日期:2026-09-08
## 目标架构
神之一手在 apply 内**动态挂载 DSH 官方 @deepseek-ai/dsh-mcp-client**(依赖官方库、管理在插件内),把 QMT Bridge 的 MCP 工具注册给模型;MCP 实例生命周期(挂/切/卸)随 QMT 连接配置的增删改与激活切换联动;状态出口 = 设置页 + 会话头部指示灯。REST 直连架构不变(技术约束-003)。
```
神之一手 apply(ctx)
├─ settingsQMT 连接配置:list + activeId + defaultId [已有 R-004]
├─ dataSourceREST 直连,baseUrl 随激活热切换) [已有]
└─ QmtMcpManager(新增 src/mcp/QmtMcpManager.js
├─ 动态 import(@deepseek-ai/dsh-mcp-client) → ctx.plugin(module, config)
│ config = { serverName: QMT_Bridge_MCP, transport: streamable-http,
│ url: 激活 baseUrl + /mcp, failOnStartupError:false,
│ reconnect: {enabled, 500ms→30s, 10次} } ← 与宿主现受管块同参(Q5)
├─ 生命周期:start(启动挂载激活连接)/ resync(url)(激活·编辑地址·删除联动)
├─ 状态:probe()SDK listTools 握手:connected + 工具数 + 延迟 / error
│ getStatus() → { state, serverName, url, mounted, toolCount, error, latencyMs, checkedAt }
└─ dispose:卸载 fiberctx.effect 释放)
```
## 关键事实(已实证)
- `@deepseek-ai/dsh-mcp-client@0.1.1-rc.2` 已加入 dependencies;从插件 lib 可 import,模块导出 {name:mcp-client, inject:[tools], apply, Config},可 ctx.plugin() 动态挂载(mcp_router 同款实证);
- serverName 存活实例内必须唯一 → 移三方受管块前插件实例与宿主实例不可并存(实施时序见 PLAN-018 注意事项);
- dsh-mcp-client 不暴露连接状态查询 API → 状态用**独立 SDK 探测**(@modelcontextprotocol/sdk Clientinitialize + tools/list → 工具数/延迟),与 dsh-mcp-client 自管连接互不干扰;
- 宿主现 QMT_Bridge_MCP 受管块 = 三方 dsh-skill-mcp-panel 写入,连接与注册实为官方 dsh-mcp-client。
## 改动清单
| 文件 | 改动 |
|---|---|
| package.json | dependencies + @deepseek-ai/dsh-mcp-client@0.1.1-rc.2 + @modelcontextprotocol/sdk@1.30.0(已加) |
| src/mcp/QmtMcpManager.js(新增) | MCP 实例管理:动态挂载/卸载 + resync + probe/getStatus + dispose |
| src/index.js | 实例化 QmtMcpManager、start、ctx.effect 释放、传入 registerApi runtime |
| src/api/index.js | runtime 增 mcpManager(分发 handleQmt/handleMarket |
| src/api/qmt-connections.js | METHODS + mcp-statusactivate/update(地址变)/remove 热切换点 + mcpManager.resync(url) |
| src/api/market.js | sync-status 增加 mcp 域(读 mcpManager.getStatus |
| src/client/views/SyncIndicators.jsx | 三灯 → 四灯:+「MCP」(绿=已连接 / 黄=重连中 / 红=断开 / 灰=未启用;点击刷新) |
| src/client/views/SettingsSection.jsx | QMT 连接配置子 tab 顶部 MCP 状态条 + 「检查 MCP」按钮(手动触发 mcp-status refresh |
## MCP 状态语义(对齐产品约束-012 指示灯体系)
| state | 灯色 | 说明 |
|---|---|---|
| connected | 绿 | 已连接 + N 工具(probe listTools 成功) |
| connecting | 黄 | 挂载中 / 重连中 |
| error | 红 | 不可达 / 失败(含原因) |
| disabled | 灰 | 无激活连接(未启用) |
## 实现步骤
1. QmtMcpManager(挂/卸/resync/probe/getStatus/dispose);
2. index.js 接线 + registerApi runtime
3. apimcp-status + sync-status.mcp + 热切换联动;
4. 客户端:SyncIndicators 四灯 + 设置页 MCP 状态条;
5. 构建(pnpm build)验证;
6. 宿主迁移(独立步骤,需老师确认 + editing-cordis-compositions 流程):卸载 dsh-skill-mcp-panel + 移除 cordis.patch.yml 受管块 → 重载 → 验证工具来自神之一手;
7. 验收。
## 风险与注意
- 同 serverName 冲突:插件实例与宿主受管块不可并存(先插件后移除,或先移除后插件接管,二选一窗口);
- ctx.plugin 子 fiber 需要 tools 服务:one-divine-lot inject 列表评估(对齐 mcp_router inject [webServer, tools]);
- dsh-mcp-client 初始连接失败不抛(failOnStartupError:false),但**重复 serverName 会抛** → 挂载错误必须 catch,插件其余功能不受影响。