根本原因
这是 npx 的缓存目录被"半成品"污染导致的,我用一张图说明它的形成过程。
C:\Users\liupe\AppData\Local\npm-cache\_npx\
└── be47caeab2afd91b\ ← 路径哈希(由包名 + 环境推导)
├── package.json ← 缓存清单(记录依赖版本)
├── package-lock.json
└── node_modules\
└── @gitee\mcp-gitee-windows-amd64
这个目录不是"事务性"的,而且 npx 不会自检完整性。 流程是:
- 建目录 → 写
package.json→ 开始npm install - 如果安装过程中进程被杀,
node_modules可能已经落盘了一部分,但顶层文件处于不一致状态 - 下次启动时 npx 的逻辑是"目录在 → 直接读
package.json拿版本",读到就复用 - 而现在
package.json缺失 →read-package.js直接抛 ENOENT → 失败,且永远不会自我修复,因为目录一直"在"
你这次的日志正好完整印证了这条路径(libnpmexec/lib/index.js:307 的 exec 处读取失败、cwd 为 C:\Users\liupe、registry 走的是 registry.npmmirror.com)。
为什么会"装到一半被打断"
@gitee/mcp-gitee 是个壳包,真正干活的是它依赖的平台二进制 @gitee/mcp-gitee-windows-amd64(几十 MB)。也就是说:
- 第一次启动时 npx 要下载这个二进制,耗时可观
- Trae 启动 MCP Server 有超时限制,等不到 npx 启动完成就会 kill 掉子进程
- kill 的时机如果正好落在"二进制下载/写入中",就留下了一个残缺的
_npx目录
次要加重因素:
- 走的是
registry.npmmirror.com镜像,镜像偶发抖动会让 install 中途失败 - Node v26.2.0 是相当新的版本,npm 11 的
_npx复用逻辑历史上就有"中断后不自愈"的已知问题 - 多个 Trae 窗口/工作区并发跑同一个包,会争抢同一个哈希目录
为什么"删掉就好"
因为哈希目录是按包名推导的,删掉后 npx 会走全新安装分支,重新生成完整的 package.json + node_modules。这也正是我做的:删目录 → 预热缓存 → 实测 initialize 正常返回。
怎么避免再犯
- 预热缓存(已做):手动跑一次
npx -y @gitee/mcp-gitee@latest,让它完整装完再交给 Trae。以后 Trae 启动时只是"读缓存",秒起。 - 如果再遇到,先删
_npx\<哈希>再重启 MCP,不要反复重试(重试不会自愈)。 - 想彻底绕开 npx 的不确定性,可以改成全局安装后在 MCP 配置里写绝对路径命令:
这样就没有npm i -g @gitee/mcp-gitee # MCP 配置的 command 改为 mcp-gitee(或 .cmd 的完整路径)_npx这一层缓存可损坏了。
需要我现在帮你把它全局装好、把配置改成绝对路径吗?