5.6 KiB
Windows-MCP 打包集成文档
本文档说明如何将 windows-mcp 预打包到 Electron 客户端中,避免用户首次使用时从 PyPI 下载。
背景
windows-mcp 是 Python MCP 服务器,提供 Windows 桌面自动化能力。原实现通过 uv tool run windows-mcp 动态从 PyPI 下载安装,首次启动可能因网络原因超时失败。
打包后,随应用附带 离线 wheel 包;用户在首次启动时由本机 uv tool install 从该目录安装到用户数据目录,一般无需再访问 PyPI。
架构
打包产物(resources → extraResources)
prepare-windows-mcp.js 在 Windows 打包机上执行,生成:
resources/windows-mcp/
├── manifest.json # 解析出的版本与 resolvedSpec(如 windows-mcp==0.7.1)
└── wheels/
└── *.whl # 及其传递依赖的 wheel(仅二进制包)
不会在 resources/windows-mcp/bin/ 下预生成 windows-mcp.exe;可执行文件在用户首次运行客户端时安装到用户目录(见下)。
运行时路径
- 随包资源:
process.resourcesPath/windows-mcp/(含wheels/、manifest.json) - 安装后的可执行文件:
%USERPROFILE%\.qimingclaw\windows-mcp-runtime\<version>\bin\windows-mcp.exe(由windowsMcp.ts中的uv tool install创建)
日志中启动阶段为 [WindowsMcp] Starting (runtime) on port ...(不是 “bundled” 直启 exe)。
相关文件
| 文件 | 说明 |
|---|---|
scripts/prepare/prepare-windows-mcp.js |
打包脚本:用 bundled uv 拉取 wheel 并写 manifest |
src/main/services/packages/windowsMcp.ts |
运行时:uv tool install(离线优先)与进程启动 |
src/main/services/system/dependencies.ts |
getWindowsMcpBinPath()(可选 legacy 路径,当前主线未使用) |
package.json |
prepare 脚本和 extraResources 配置 |
实现方案
打包时(Windows CI / 本地 Windows)
npm run prepare:windows-mcp
脚本执行:
- 非 Windows 平台则跳过(直接返回)。
- 校验
resources/uv/bin/uv(.exe)存在。 - 清空并重建
resources/windows-mcp/,创建wheels/。 - 调用 bundled uv:新版 uv 已移除
uv pip download,因此使用
uv run --no-project --isolated --python <版本> -w pip python -m pip download ...
将windows-mcp及其依赖的 wheel 下载到wheels/。
脚本内PIP_DOWNLOAD_PYTHON须满足 PyPI 上windows-mcp的Requires-Python,且windowsMcp.ts中uv tool install --python须与之一致,否则离线 wheel 的 cp 标签可能与运行时解释器不符。 - 从
windows_mcp-*.whl解析版本,写入manifest.json。
打包机需要能访问 PyPI(或等价镜像);最终用户在离线安装成功时无需外网。
运行时(Electron 启动)
见 windowsMcp.ts:ensureWindowsMcpRuntime 优先执行
uv tool install --force --no-index --find-links <随包wheels目录> <resolvedSpec>
失败时再回退 uv tool install --force <resolvedSpec>(在线)。
配置变更
package.json
{
"scripts": {
"prepare:windows-mcp": "node scripts/prepare/prepare-windows-mcp.js",
"prepare:all": "... && npm run prepare:windows-mcp"
},
"build": {
"win": {
"extraResources": [
{
"from": "resources/windows-mcp",
"to": "windows-mcp",
"filter": ["**/*"]
}
]
}
}
}
版本策略
- 每次在 Windows 上执行 prepare 时解析 当前 PyPI 上满足 Python 约束的最新
windows-mcp(及依赖),版本写入manifest.json。 - 用户升级客户端即可获得当时打包锁定的版本。
平台限制
| 平台 | 打包 | 运行 |
|---|---|---|
| Windows x64 | ✅ 支持 | ✅ 支持 |
| macOS | ⚠️ 跳过 | ❌ 不适用 |
| Linux | ⚠️ 跳过 | ❌ 不适用 |
测试验证
本地打包(Windows)
cd crates/agent-electron-client
npm run prepare:windows-mcp
dir resources\windows-mcp\wheels
type resources\windows-mcp\manifest.json
npm run dist:win
运行时验证
- 启动 Windows 客户端。
- 日志:
[WindowsMcp] offline_install_success或在线回退相关日志。 - 确认
windows-mcp-runtime下已生成bin\windows-mcp.exe。
离线验证
- 断开网络。
- 删除已有 runtime 目录或强制重装后启动(视实现而定)。
- 在 wheels 齐全时,应能通过离线
uv tool install完成安装并启动。
常见问题
Q: prepare 阶段需要网络吗?
A: 需要。prepare 要从索引下载 wheel;这与最终用户离线使用随包 wheels 不矛盾。
Q: 如果 windows-mcp 打包失败会怎样?
A: prepare-windows-mcp.js 会 process.exit(1),导致后续 make electron-dev / 打包失败。请保证 Windows 构建环境网络与 PyPI 可达。
Q: CI 里没有本机 Python 怎么办?
A: 脚本通过 uv run --python … 使用 uv 管理的解释器;默认将 UV_PYTHON_DOWNLOADS 设为 automatic,以便首次拉取 CPython。若环境禁止下载,需预先提供满足 Requires-Python 的解释器或调整环境变量。
Q: Python 依赖也会进 wheels 吗?
A: 会。pip download 会拉取传递依赖的 wheel(--only-binary :all: 要求均为预编译 wheel;若某依赖无 wheel,下载会失败)。
更新日志
| 日期 | 版本 | 说明 |
|---|---|---|
| 2026-04-02 | 0.10 | 初始集成(wheels + 运行时 uv tool install) |
| 2026-04-09 | — | 文档与注释对齐实际流程;prepare 改用 uv run + pip download(兼容移除 uv pip download 的 uv) |