Repository navigation
cq-viewer 1.1.0: MCP tools to add model folders and files, bundled CadQuery skill - #19
Merged
Merged
Conversation
…dQuery skill
- MCP server "cq-viewer" served by the Mini App itself (POST /mcp/cq-viewer,
loopback Host/Origin only, JSON only):
- add_model_folder: register a folder (same rules as the page), list its models,
optionally switch the viewer to it.
- add_model_file: open an .stl/.step/.stp in place through the closest registered
folder (or register its own folder); copy_to_scene copies it into
~/.cqview/scene for files outside the home directory.
- list_model_folders: registered folders, pushed scene, or one folder's models.
- Requests persist in dataDir/open-requests.json (24 h, last 20); the page applies
each once, so models the AI opens while the viewer is closed show up on the next
visit. The page closes its live connection on pagehide so viewer_connected is accurate.
- Bundle skills/parametric-3d-printing from flowful-ai/cad-skill (fe42159),
PolyForm Noncommercial 1.0.0 with its Required Notice; one section appended to
SKILL.md pointing the agent at add_model_file. Author: HanZijie, flowful-ai.
- tests/mcp.test.mjs: 10 tests against the real Node entry with a temporary home.
npm run check: plugins/hanzijie/cq-viewer OK (0 errors, 0 warnings).
MyPrototypeWhat
left a comment
Collaborator
There was a problem hiding this comment.
感谢更新,MCP 工具这部分做得很扎实!看到 PR 已经合并了,我补充一些合并后的复查结果,想请你再开一个后续 PR,修一下下面两处需要修改的问题。
另外想顺便提一下:这个仓库一般使用 squash merge,并且希望 PR 在合并前至少经过一次 review,后续的 PR 麻烦等 review 后再合并,谢谢理解~
我在本地实测了新的 MCP 端点:非回环的 Host / Origin 会被拒绝(403),参数校验严格,add_model_folder 和原地打开的 add_model_file 沿用了原来的路径规则(home 外、隐藏目录、指向外部的软链都会被拒绝);tests/mcp.test.mjs 和 npm run check 都通过。内置 skill 与上游 fe42159 对比,除了 SKILL.md 末尾追加的一节,其余文件都一致。
需要修改(#18 中的两处,请在后续 PR 中修复)
- 并发写入:
addRoot、pushRequest、copyToScene已经进入serial()队列,8 个并发登记现在都成功了 👍。但writeSelection还没有进队列,writeJsonAtomic的 tmp 名也还是 pid + 毫秒(见行内评论),实测 40 个并发保存标注仍有 21 个返回 500。 - dispose 之后仍会启动 Python:这部分还没有改动。我在 f0c477d 上重测,转换过程中 abort 后,同一秒又启动了 fallback 的
python -c转换,并写入了缓存。建议 dispose 后runChild直接拒绝,被信号结束(包括超时)时不再进入 fallback。
提醒(非必改)
- 内置 skill
skills/parametric-3d-printing/使用的是 PolyForm Noncommercial 1.0.0(仅限非商业用途)。你已经在 LICENSE、README 和 UPSTREAM.md 里标注得很清楚了,谢谢。这里只是提出来,请维护者留意一下这个仓库收录非商业许可内容是否合适。
建议(可选)
/viewer/api/*页面路由仍然没有 Host 校验,可以直接复用 MCP 端点里的isLoopbackRequest。host-bridge.js里的APP_INFO.version还是 1.3.0,建议与 plugin.json 的 1.1.0 统一。
后续 PR 提上来后我会尽快复查,谢谢!
| async function writeJsonAtomic(file, data) { | ||
| await mkdir(EXCHANGE_DIR, { recursive: true }); | ||
| await mkdir(dirname(file), { recursive: true }); | ||
| const tmp = `${file}.${process.pid}.${Date.now()}.tmp`; |
Collaborator
There was a problem hiding this comment.
这里的 tmp 名还是 pid + 毫秒,而 writeSelection 没有进 serial(),同一毫秒内的两次保存仍会撞名:实测 40 个并发 POST /api/selection 有 21 个 500(ENOENT)。建议 tmp 名加随机后缀(例如 randomBytes(6).toString('hex'),上面已经 import 了),并让 writeSelection 也走 serial()。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Update of
plugins/hanzijie/cq-viewer(CadQuery Viewer) to 1.1.0.MCP tools for the AI
The Mini App now serves an MCP server
cq-vieweritself (servers.mcp.json+mcpEndpoints, Streamable HTTP onPOST /mcp/cq-viewer):add_model_folder{path, select?}$HOME, not$HOME/~/Library/hidden top-level). Returns folder ID + up to 200 model paths;select(default true) switches the viewer to it.add_model_file{path}.stl/.step/.stpin place via the closest registered folder that lists it (or registers the file's own folder). The viewer ticks it, fits, and live-reloads on re-export.add_model_file{path, copy_to_scene: true, name?, color?, opacity?}~/.cqview/scene/(likecqview.show_file) for files outside$HOME, e.g./tmp.list_model_folders{folder?}Requests are persisted in
dataDir/open-requests.json(24 h, last 20) and applied once per browser, so a model the AI opens while the viewer is closed shows up on the next visit. Results carryviewer_connected; the page closes its SSE connection onpagehideso that flag is accurate.Bundled skill
skills/parametric-3d-printing/= the skill from flowful-ai/cad-skill @fe42159. Runtime files are byte-identical;README.md,docs/,tests/are left out; one clearly marked section is appended toSKILL.mdtelling the agent to open exported models withadd_model_file. Seeskills/parametric-3d-printing/UPSTREAM.md.Other
author:HanZijie, flowful-ai; root README rows list both.roots.json/ scene files are serialized;writeJsonAtomiccreates the target's own directory.Checks
npm run check:plugins/hanzijie/cq-viewer: OK— 0 errors, 0 warnings; 55/55 repo tests. (The 4 warnings shown belong to two other packages.)node --test plugins/hanzijie/cq-viewer/tests/*.test.mjs: 10/10 (real Node entry, temporary$HOME): the three tools, folder rules, copy with colour, request log across a restart, 403 on non-loopback Host/Origin, 405 on GET, 415 on non-JSON.Data & access (delta — full detail in the README)
copy_to_scene, the one model file the AI names (regular.stl/.step/.stp≤ 512 MB, any location).~/.cqview/scene/<name>.<ext>+scene.json(only forcopy_to_scene);dataDir/open-requests.json(folder ID / relative path / scene name — no absolute paths).POST /mcp/cq-viewer, loopbackHost/Originonly, JSON only. No network, no new processes. The bundled skill's scripts are run by the agent, never by the Mini App.Tested environment
3.1.1-preview.4597(Electron 42), macOS 26 (Apple Silicon); Python 3.9, CadQuery 2.5.2 / OCP 7.7.2, trimesh 4.12, pyrender 0.1.45.mcp__cq-viewer__add_model_folder/add_model_file/list_model_foldersand the skillcq-viewer:parametric-3d-printing;list_model_foldersandadd_model_folder(select:false) called through the Host returnok: true.add_model_folder;add_model_fileticks + renders the file and toasts;copy_to_sceneshows the part in the requested colour; a file requested while the page is closed opens on the next visit, is not replayed afterwards, and stays closed after the user unticks it;viewer_connectedgoes false when the page leaves. No console errors.run_cadquery_model.py --preview --strictfrom the installed plugin directory → STL, watertight, preview PNG.Not verified
add_model_filethrough the Host with the viewer panel open (page side verified in headless Chrome only).mcode.miniapp.message.append) actually fills the conversation input in this build; STEP face colours from other CAD tools.Need help on this PR? Tag
@codesmith-botwith what you need.