## 类型\n\nBrowser / WebMCP / P1\n\n## 现象\n\nElectron Browser Runtime E2E 在 webmcp:list 返回空工具列表;改为通过 window.__lumeWebMcpModelContext.registerTool 注册后,webmcp:list 能返回工具,但 webmcp:invoke 仍返回 browser_internal_error。\n\n## 根因线索\n\n- consumer 优先读取 contextBridge 暴露的 window.__lumeWebMcpModelContext,旧 fixture 给 document.modelContext 赋值不会进入实际消费路径。\n- invokeWebMcpTool 将 getTools() 返回的 contextBridge 代理对象原样传回 executeTool;Electron 无法稳定跨 bridge 克隆该代理对象。\n- 仅传递普通引用 { name: tool.name } 时,直接调用可以成功。\n\n## 复现\n\n运行 bun run --filter @lume/desktop test:browser-e2e,现有基线在 WebMCP tools were not normalized 处失败。\n\n## 验收\n\n- 页面通过 __lumeWebMcpModelContext.registerTool 注册的工具可 list 和 invoke。\n- invoke 只跨 bridge 传递可克隆的普通 tool ref。\n- Electron Browser Runtime E2E 覆盖真实 contextBridge 注册与调用。
类型\n\nBrowser / WebMCP / P1\n\n## 现象\n\nElectron Browser Runtime E2E 在 webmcp:list 返回空工具列表;改为通过 window.__lumeWebMcpModelContext.registerTool 注册后,webmcp:list 能返回工具,但 webmcp:invoke 仍返回 browser_internal_error。\n\n## 根因线索\n\n- consumer 优先读取 contextBridge 暴露的 window.__lumeWebMcpModelContext,旧 fixture 给 document.modelContext 赋值不会进入实际消费路径。\n- invokeWebMcpTool 将 getTools() 返回的 contextBridge 代理对象原样传回 executeTool;Electron 无法稳定跨 bridge 克隆该代理对象。\n- 仅传递普通引用 { name: tool.name } 时,直接调用可以成功。\n\n## 复现\n\n运行 bun run --filter @lume/desktop test:browser-e2e,现有基线在 WebMCP tools were not normalized 处失败。\n\n## 验收\n\n- 页面通过 __lumeWebMcpModelContext.registerTool 注册的工具可 list 和 invoke。\n- invoke 只跨 bridge 传递可克隆的普通 tool ref。\n- Electron Browser Runtime E2E 覆盖真实 contextBridge 注册与调用。