# 迭代 18 技术实现方案:QMT Bridge MCP 能力内建 > 依据:R-020(2026-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) ├─ settings(QMT 连接配置:list + activeId + defaultId) [已有 R-004] ├─ dataSource(REST 直连,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:卸载 fiber(ctx.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 Client:initialize + 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-status;activate/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. api:mcp-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,插件其余功能不受影响。