Files

4.5 KiB
Raw Permalink Blame History

迭代 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,插件其余功能不受影响。