agentcad — CAD tool for AI agents
You have access to agentcad, a CLI that turns CadQuery Python scripts into
3D geometry. All output is JSON. Every command returns "command" and "status" keys.
First-time setup
agentcad init --name <project_name>
agentcad --help # Read this — it is your complete operational briefing
Core workflow
-
Write a script. No imports needed —
cq,show_object, and all helpers are pre-injected.show_object(result)is required. -
Dry-run first to check metrics without consuming a version:
agentcad run script.py --output test --dry-runCheck
volume,dimensions,is_validin the response. -
Run for real. Visual feedback is on by default:
agentcad run script.py --output labelEvery successful run produces (paths in the JSON response):
preview.png— 4-view composite (front, right, top, iso). Read this to confirm the part looks right before iterating. One image, all 4 angles.diff.side_by_side— side-by-side PNG vs the most recent successful prior version. Read this when iterating to see what your change did.diff.overlay— tinted (green prev, red this) overlay for subtle shifts. Read only if side-by-side didn't resolve the question.viewer.html— interactive 3D viewer for the user (humans only; you can't render HTML). Mention it to the user so they open it.
Pass
--no-previewonly for tight parametric sweeps where latency matters. -
Show the user. After a successful build, open the interactive viewer:
agentcad view v1_label/viewer.html # or output.step / output.glbUsers expect to see the result in a browser. Do this every run, unprompted.
-
Inspect if invalid. If
is_valid: falseor geometry looks wrong:agentcad inspect v1_label/output.step -
Iterate. Fix the script, run with a new
--outputlabel. Useagentcad diff 1 2to compare versions.
Script writing rules
show_object(result)is required — at least one call.- These are pre-injected (no import needed):
cq,show_object,translate,rotate,mirror_fuse,loft_sections,tapered_sweep,naca_wire,bbox_point,place_at,assemble,ellipse_wire,spline_wire,polygon_wire,rounded_rect_wire,elliptical_sweep,involute_gear_profile - Helpers operate on
TopoDS_Shape. Bridge with.val().wrapped:part = cq.Workplane('XY').box(10, 20, 5).val().wrapped moved = translate(part, 50, 0, 0) - To show helper output:
show_object(cq.Workplane('XY').newObject([cq.Shape.cast(topo_shape)])) - For OCP internals (
gp_Pnt,BRepPrimAPI, etc.), import manually.
Key commands
| Command | Purpose |
|---|---|
agentcad init --name NAME | Initialize project |
agentcad run SCRIPT --output LABEL | Execute script, produce STEP + metrics |
agentcad run ... --dry-run | Metrics only, no version consumed |
agentcad run ... --no-preview | Suppress preview (on by default) |
agentcad run ... --render iso,front | PNG views |
agentcad run ... --export stl,glb | Mesh export |
agentcad run ... --params k=v,k=v | Override script parameters |
agentcad render STEP --view SPEC | Post-hoc renders with camera control |
agentcad export STEP --format stl,glb | Post-hoc mesh export |
agentcad inspect STEP | Topology report (validity, free edges) |
agentcad diff REF1 REF2 | Compare versions |
agentcad context | Project state |
agentcad docs [SECTION] | Deep-dive docs (16 sections) |
agentcad view FILE | Run this after every successful build — opens GLB/STEP in the user's browser |
Debugging playbook
- Check metrics first —
volumeanddimensionscatch most issues. - Read
preview.png— the 4-view composite. Fastest way to spot obvious problems. - Read
diff.side_by_sideif iterating — confirms your change did what you intended. - Negative volume? Wire winding is backwards (CW instead of CCW).
- is_valid: false? Run
agentcad inspect— checkfree_edge_countand shell status. - Hollow shape?
free_edge_count > 0means open shell. - Complex profiles (gears, splines)? Use subtractive construction — cut from
a blank cylinder/box instead of building up. See
agentcad docs patterns.
Patterns
- Build at origin, then position: Create geometry at origin, use
translate()androtate()to place it. - Compound vs Union:
makeCompound()for assemblies (parts stay separate),.union()for boolean fuse into one solid. - Parametric scripts: Top-level variable assignments become overridable via
--params. Use this for iteration. - Named parts:
show_object(shape, name="wheel", options={"color": "red"})for per-part metrics and colored GLB export.