fix(builtin-mcp): make image-gen server runnable by external node in packaged app#1584
fix(builtin-mcp): make image-gen server runnable by external node in packaged app#1584
Conversation
…packaged app In packaged builds (app.isPackaged === true), the builtin MCP image-gen server was not visible to Claude because of two issues: 1. getBuiltinMcpBaseDir() returned a path inside app.asar. External node processes have no Electron ASAR virtual FS support, so `node <path>` failed silently. Fix: replace 'app.asar' with 'app.asar.unpacked' when app.isPackaged is true. 2. electron-vite's externalizeDepsPlugin leaves all npm packages as require() calls. These resolve fine inside Electron (ASAR patches require()) but cannot be found by a standalone node process launched from app.asar.unpacked. Fix: after electron-vite build, re-bundle imageGenServer.ts with esbuild (--bundle) so all dependencies are inlined into a single self-contained CJS file. Changes: - electron-builder.yml: add out/main/builtin-mcp-image-gen.js to asarUnpack so the file is physically present on disk - src/process/initStorage.ts: redirect getBuiltinMcpBaseDir() to app.asar.unpacked when packaged - scripts/build-mcp-servers.js: new esbuild config script that produces a fully self-contained bundle (uses JS API to avoid shell-quoting issues with define values containing '/') - scripts/build-with-builder.js: invoke build-mcp-servers.js after the electron-vite build step
…rces/, fix oxfmt issues
Code Review:fix(builtin-mcp): make image-gen server runnable by external node in packaged app (#1584)变更概述本 PR 修复了打包后的应用中内置 MCP 图片生成服务器无法被外部 方案评估结论:✅ 方案合理 根本原因分析准确:electron-vite 的 externalize 机制依赖 Electron 对 问题清单🟡 MEDIUM — execSync 中路径未加引号,项目路径含空格时构建将失败文件: 问题代码: execSync(`node ${path.join(__dirname, 'build-mcp-servers.js')}`, {
stdio: 'inherit',
shell: process.platform === 'win32',
});问题说明: 修复建议: execSync(`node "${path.join(__dirname, 'build-mcp-servers.js')}"`, {
stdio: 'inherit',
shell: process.platform === 'win32',
});🔵 LOW —
|
| # | 严重级别 | 文件 | 问题 |
|---|---|---|---|
| 1 | 🟡 MEDIUM | scripts/build-with-builder.js:423 |
execSync 路径未加引号,空格路径会失败 |
| 2 | 🔵 LOW | scripts/build-mcp-servers.js:32 |
file:///placeholder 在 Windows 上可能引发 fileURLToPath 异常 |
结论
本报告由本地 pr-review skill 生成,包含完整项目上下文,无截断限制。
- Quote dynamic path in execSync to handle project paths with spaces - Use Windows-compatible file:///C:/placeholder for import.meta.url define Review follow-up for #1584
PR Fix 验证报告原始 PR: #1584
总结: ✅ 已修复 2 个 | ❌ 未能修复 0 个 | ⏭️ 跳过 0 个 |
Summary
app.asarand all npm dependencies were externalized — neither accessible to a standalonenodeprocessgetBuiltinMcpBaseDir()toapp.asar.unpackedwhenapp.isPackagedis true, add the script toasarUnpack, and re-bundle it with esbuild so all dependencies are inlinedChanges
src/process/initStorage.tsgetBuiltinMcpBaseDir(): replaceapp.asarwithapp.asar.unpackedin the returned path whenapp.isPackaged === trueelectron-builder.ymlout/main/builtin-mcp-image-gen.jstoasarUnpackso the file is physically present on disk and accessible to external processesscripts/build-mcp-servers.js(new)--definevalues containing//scripts/build-with-builder.jselectron-vite buildstep, invokebuild-mcp-servers.jsto overwrite the externalized bundle with the self-contained oneRoot Cause
externalizeDepsPlugin(used by electron-vite) turns every npm package into arequire()call. Inside Electron this works because Electron patchesrequire()to support ASAR virtual paths. But the MCP server runs as a child process vianode <path>— that process has no ASAR support, so it can't find any of the dependencies (@modelcontextprotocol/sdk,zod,@office-ai/aioncli-core, etc.).Related
Follow-up fix for #1243 (introduced the builtin image-gen MCP server).
Test Plan
bun run build— confirm📦 Bundling builtin MCP servers (self-contained)...step succeedsapp.asar.unpacked/out/main/builtin-mcp-image-gen.jsphysically exists in the built.app/mcp— confirmAionui-image-generationstatus is connected (not failed)