本项目采用「瘦 MCP + 胖 Skill」架构:Python MCP Server 只提供 7 个聚合 API,
真正的操作流程(SOP)沉淀在 .agents/skills/ 的 Skill 知识库里。
编辑器 AI
│ MCP stdio
Python MCP Server (src/wechat_devtools_mcp/)
├── tools/*.py 7 个聚合工具的 handler(按 action 分发)
├── core/cli.py ──► 微信开发者工具 CLI(临时文件捕获输出,避开 stdio 冲突)
└── core/node_bridge ──► NDJSON ──► 常驻 Node daemon (dist/daemon.bundle.js)
├── miniprogram-automator WebSocket (9420)
└── CDP (9222)
| 目录 | 职责 |
|---|---|
src/wechat_devtools_mcp/tools/ |
7 个聚合工具的 Python handler |
src/wechat_devtools_mcp/core/ |
CLI 调用、Node daemon 桥接、配置、IDE 状态读取 |
src/wechat_devtools_mcp/models/ |
Pydantic 输入 schema |
src/wechat_devtools_mcp/scripts/ |
Node.js 源码;dist/daemon.bundle.js 是 ncc 构建产物(已入库) |
tests/ |
pytest 单元测试(mock _run_node_script,不依赖真实 IDE) |
.agents/skills/ |
Skill 知识库(SOP 流程 + 参数速查) |
docs/ |
实现说明与开放待办 |
pip install -e . # 开发安装
python -m pytest tests/ -q # 全量测试(316 项,无需启动 IDE)测试通过 tests/conftest.py 把 src/ 插入 sys.path,因此不装包也能直接跑。
另有三个不归 pytest 管的独立脚本,改动截图 / evaluate 逻辑时需手动执行:
node tests/test_screenshot_detect.js # 长图拼接的固定区域像素检测
node tests/test_screenshot_scroll.js # 滚动等待逻辑(长图截断的根因)
node tests/test_evaluate_modes.js # evaluate 的 fn_source / expression / statement 三种模式
node tests/test_call_method_error.js # callMethod 失败时错误带页面路径
node tests/test_call_wx_sync.js # callWx 对同步 wx API 改经 evaluate 直调的路由它们都直接 require 线上的 screenshot.js / ui_debug.js / automation.js,不复制实现,因此能真正守护源码。
scripts/*.js 的改动不会自动生效——运行时加载的是 scripts/dist/daemon.bundle.js。
改完必须重建并与源码一起提交:
cd src/wechat_devtools_mcp/scripts
npm install
npx ncc build daemon.js -o dist/daemon_tmp \
&& mv dist/daemon_tmp/index.js dist/daemon.bundle.js \
&& rm -rf dist/daemon_tmpdaemon.js 通过 require 引入其余各 handler,因此只需构建 daemon.js 这一个入口。
python -m py_compile src/wechat_devtools_mcp/server.py语法检查通过python -m pytest tests/ -q全绿- 改了 JS → bundle 已重建并一并提交
- 新功能带测试(先写 failing test,再实现)
改版本号时以下 9 处必须一致,漏改会导致客户端显示的版本与实际不符:
| # | 文件 | 位置 |
|---|---|---|
| 1 | pyproject.toml |
version = |
| 2 | src/wechat_devtools_mcp/__init__.py |
__version__ |
| 3-4 | server.json |
顶层 version + packages[0].version |
| 5 | README.md |
标题 |
| 6 | README_EN.md |
标题 |
| 7 | MCP_DOC.md |
标题 |
| 8 | .agents/skills/wechat-devtools/SKILL.md |
frontmatter version: 与正文标题 |
| 9 | .agents/skills/wechat-devtools/references/tool_reference.md |
标题 |
- Windows-only 的
subprocess属性统一用getattr(subprocess, "CREATE_NO_WINDOW", 0)兜底, 不要直接引用,否则非 Windows 平台会AttributeError - 开发者工具 1.x(NW.js) 与 2.x(Electron) 的启动路径不同,必须双轨兼容,
细节见
docs/macos-internals.md - 代码里对 IDE 内部文件(
.ide/.cli/.ide-status)的读取必须能优雅回退—— 这些是官方未承诺的实现细节
以下几条缺的是真机环境或一次设计决定,不是思路:
① Linux 适配
_resolve_ide_executable_for_cdp() 对 linux 直接抛 NotImplementedError。官方开发者工具本身不发 Linux 版,
所以这不算与官方的能力差距;但如果你在用第三方移植版(如 msojocs/wechat-web-devtools-linux),
欢迎确认它是否保留了相同的目录结构,再照 docs/macos-internals.md 的思路补上。
② 网络请求采集
本项目目前没有网络请求采集。实测开发者工具 2.x 里 wx.request 不走 webview 的网络栈,
CDP Network.* 只能看到 IDE 内部 http://127.0.0.1:<port>/apihelper/assdk 的 JSBridge 信封
(真实 API 名与参数在 POST body 里),所以按 URL 过滤的实现拿不到有用结果(见 #12 的讨论)。
可行方向是解开这个信封(Network.getRequestPostData),并单独确认 1.06.x 的行为。
③ 1.06.x(NW.js)回归
2.x 转 Stable 后本项目的真机回归都在 2.x 上做,1.06.x 分支只有历史验证。
手上还有 1.06.x 的话,跑一遍 tests/manual/smoke_ide.py 并把结果贴到 Issue 就很有价值。
除此之外,Issue 区里没有 good first issue 标签的问题也都欢迎认领——
提 Issue 说一声你想做哪条即可,避免撞车。
fix(scope): / feat(scope): / docs(scope):,scope 用工具名,如 navigate、evaluate、automator。