From 3c0a8971a6ffe087ab6bd8414e9d38a105a2fef4 Mon Sep 17 00:00:00 2001 From: ypshidifu Date: Wed, 23 Sep 2026 10:12:41 +0800 Subject: [PATCH] =?UTF-8?q?v7:=20MCP=E5=AD=97=E6=AE=B5=E4=BF=AE=E6=AD=A3?= =?UTF-8?q?=E2=80=94=E2=80=94=E7=9C=9F=E6=AD=A3=E7=94=9F=E6=95=88=E7=9A=84?= =?UTF-8?q?=E5=BC=80=E5=85=B3=E6=98=AFdisabled=E4=B8=8D=E6=98=AFenabled(?= =?UTF-8?q?=E4=BC=9A=E8=A2=ABserver=20schema=E5=89=A5=E6=8E=89)=EF=BC=9Ben?= =?UTF-8?q?ableMcp=E6=94=B990s=E9=87=8D=E8=AF=95(=E5=90=AF=E5=8A=A84~5s=20?= =?UTF-8?q?location=E6=89=8D=E5=B0=B1=E7=BB=AA,=E8=BF=87=E6=97=A9=E8=B0=83?= =?UTF-8?q?=E7=94=A8404)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tui-plugins/oc-session-all.js | 43 ++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/tui-plugins/oc-session-all.js b/tui-plugins/oc-session-all.js index 81e41e2..8039f62 100644 --- a/tui-plugins/oc-session-all.js +++ b/tui-plugins/oc-session-all.js @@ -46,8 +46,9 @@ function projectDisplayName(session, projectMap) { return session.projectID ? session.projectID.slice(0, 8) : "unknown" } -// MCP server 名单:opencode.json 里 enabled:false 的项(启动无 toast), +// MCP server 名单:opencode.json 里 disabled:true 的项(启动无自动连接、无 toast), // 由本插件运行时 connect 启用(官方语义:overriding disabled config until restart)。 +// 注意:enabled 字段会被 OC 的 server schema 剥掉,真正生效的开关是 disabled。 // 新增被禁用的 MCP server 时把名字加进来即可。 const MCP_NAMES = ["baota-mcp"] @@ -86,39 +87,39 @@ export default Plugin.define({ log("[oc-session-all] toast interceptor install ERROR: " + e.message) } - // ── MCP 运行时启用(config enabled:false + 插件 connect)──────────── + // ── MCP 运行时启用(config disabled:true + 插件 connect 覆盖)───────── + // OC 启动后 location/config 异步就绪(实测约 4~5s),过早调用会 list 为空 + // → connect 返回 404 "MCP server not found"。这里每 2s 重试直到成功(上限 90s)。 const enableMcp = async () => { - // 等服务端 MCP 子系统初始化完成 await delay(1500) - try { - // 1) dump 现状(供后续动态化:字段名/状态一并写日志) + const deadline = Date.now() + 90000 + let attempt = 0 + let pending = MCP_NAMES.slice() + while (pending.length && Date.now() < deadline) { + attempt++ try { const list = await context.client.mcp.list({ location: context.location }) const data = list && list.data !== undefined ? list.data : list - log("[oc-session-all] mcp.list dump: " + JSON.stringify(data).substring(0, 800)) + const names = Array.isArray(data) ? data.map((s) => s && s.name).filter(Boolean) : [] + log("[oc-session-all] mcp.list attempt=" + attempt + " names=[" + names.join(",") + "]") } catch (e) { - log("[oc-session-all] mcp.list ERROR: " + e.message) + log("[oc-session-all] mcp.list attempt=" + attempt + " ERROR: " + e.message) } - // 2) 逐个 connect(POST /api/experimental/mcp/:server/connect) - for (const name of MCP_NAMES) { + for (const name of pending.slice()) { try { await context.client.mcp.connect({ server: name, location: context.location }) - log("[oc-session-all] mcp.connect(" + name + ") OK") + log("[oc-session-all] mcp.connect(" + name + ") OK attempt=" + attempt) + pending = pending.filter((n) => n !== name) } catch (e) { - log("[oc-session-all] mcp.connect(" + name + ") ERROR: " + e.message) + const msg = String((e && e.message) || e) + log("[oc-session-all] mcp.connect(" + name + ") attempt=" + attempt + " ERROR: " + msg) + if (/already/i.test(msg)) pending = pending.filter((n) => n !== name) } } - // 3) connect 后再拉一次 list(服务端状态已变,日志记录结果) - try { - const after = await context.client.mcp.list({ location: context.location }) - const data = after && after.data !== undefined ? after.data : after - log("[oc-session-all] mcp.list after connect: " + JSON.stringify(data).substring(0, 800)) - } catch (e) { - log("[oc-session-all] mcp.list(after) ERROR: " + e.message) - } - } catch (e) { - log("[oc-session-all] enableMcp ERROR: " + e.message) + if (pending.length) await delay(2000) } + if (pending.length) log("[oc-session-all] enableMcp gave up, pending: " + pending.join(",")) + else log("[oc-session-all] enableMcp done, all connected") } void enableMcp()