CAD API Scripting
A skill for generating, reviewing, and debugging code that drives CAD systems programmatically. Covers Python-based APIs (commercial CAD platforms), declarative languages (OpenSCAD), and similar scripting interfaces.
When to use
- User has a finished or near-finished design and wants to translate it into a reusable script
- User wants to import a parameter table into a CAD system from JSON/CSV
- User wants to generate repetitive geometry algorithmically (grids, arrays, variant families)
- User is debugging an existing CAD script
- User wants to expose a design as a configurable OpenSCAD module
When NOT to use
- User is still exploring design options →
design-first-iteration
- User wants step-by-step manual CAD guidance →
cad-construction
- User wants general mechanical design principles →
mechanical-design-principles
- User wants firmware code or web backend code → other engineering skills
Workflow
Phase 1: Clarify the target platform
Before writing a single line, confirm:
- Which CAD platform / scripting language?
- Commercial (Fusion 360, SolidWorks, Onshape, Inventor, NX) — almost always Python or JavaScript-based
- Open-source (FreeCAD, Blender for CAD, OpenSCAD, CadQuery, Build123d)
- Declarative (OpenSCAD, JSCAD)
- Which API version / library version? APIs change. An older Fusion 360 script may not run on the current API.
- Goal of the script: one-shot generation, reusable module, parameter-import utility, test harness?
If the user is unclear, ask 1–2 targeted questions. Do not assume.
Phase 2: Sketch the code structure before writing
For non-trivial scripts, outline in plain text first:
- Setup (imports, app/document handle, parameter loading)
- Parameter definitions (from file or hardcoded)
- Helper functions (reusable geometry operations)
- Main construction sequence (sketches, features, assembly)
- Error handling and cleanup
- Save / export step
This structure sketch is the place to catch missing inputs, unclear naming, or scope creep — not the middle of a 200-line script.
Phase 3: Write the code
Principles:
- Parametric from the start. Every dimension is a named variable or parameter, never a literal in the middle of code. If the user has a parameter table from
cad-construction (three-tier structure), mirror that structure in the code rather than inventing a new one.
- Guard the obvious failure modes. Check that the document exists, that the target component is found, that a selection is non-empty. Fail with a clear message, not a stack trace.
- Keep one unit system throughout. If the CAD system works in cm internally (Fusion 360), convert at the boundary, then keep code in mm (or whatever the user thinks in). Document the convention at the top of the file.
- Comment intent, not mechanics.
# Create a 3 mm fillet on the top edge to soften the grip surface is useful. # Call addByThreeEdges() is not — the code already shows that.
- Naming: use descriptive names consistent with the parametric convention (
housing_wall_thickness, not wt). Match the names the user is already using in their parameter table — do not re-invent.
Phase 4: Test plan, even for one-shot scripts
Before handing the script over:
- State explicitly which parameter values were assumed in testing
- Note edge cases the script does NOT handle (zero-width features, negative offsets, etc.)
- If the script modifies an existing document: warn about undo behavior
Language-specific notes
OpenSCAD
- Declarative, no loops with state. Think in unions, differences, intersections, and modules.
- Use
$fn, $fa, $fs deliberately — cheap during design, expensive during export
- Modules with default parameters enable library-style reuse:
module housing(width=100, height=40, wall=2.4) { ... }
- For parametric designs with many variants, expose a
Customizer section at the top with // [Range] and // [dropdown] annotations
- Version-pin the OpenSCAD version assumption in a comment (dev snapshot vs stable differ in available features)
Python-based commercial CAD APIs
General patterns (apply across Fusion 360, Inventor, NX, SolidWorks Python wrappers):
- App and document handles first. Most APIs require getting the app object, then the active document, then the root component — establish these once at the top.
- User parameters over feature parameters. User parameters (project-level named values) survive model regeneration. Feature-local values do not.
- Transactions / undo grouping. Wrap related operations in a single undo group so the user can undo the whole script in one step.
- Error handling with try/except at the outer level, logging which step failed. Commercial APIs tend to throw informative exceptions — catch them, report them, do not swallow them.
- Unit handling varies: some APIs expose values in internal units (often cm), others in document units. Always check, document the convention, and convert at the boundary.
Parameter-Import scripts (common use case)
When generating a script that reads a JSON/CSV parameter table and writes them into the CAD system's user parameters:
- Source of truth is the parameter table from
cad-construction (JSON / CSV / Markdown) — the script does not invent parameters
- Preserve the three-tier structure if the table has it (primary / derived / tolerance). Some CAD systems let you group or tag parameters; use that if available.
- Each parameter needs: name, value, unit, optional comment
- If a parameter already exists in the document: update its value, do not create duplicate
- If a parameter name contains invalid characters for the target system: sanitize with a documented rule, not silently
- At the end: summary log of which parameters were created vs updated vs skipped
OpenSCAD / declarative DSLs
- Emphasis on pure functions and modules
- Customizer-compatible parameter blocks at the top
assert() for preconditions the caller must meet
Testing and handover
A script is not done when it runs once. Before declaring complete:
- Run with at least one edge-case parameter set
- Verify the output geometry visually (export to STL or screenshot the CAD window)
- Document the command to run the script (how to invoke it in the CAD system)
- Note the assumed API/language version
Anti-patterns
- Hardcoding dimensions in the middle of a script. If a number appears in code that isn't at the top as a parameter, something is wrong.
- Silent failures. If a feature can't be created, the script must say so, not continue with an incomplete model.
- Coupling to the current document state. A good script works in a fresh document. If it depends on "this is the third component in the tree", it's fragile.
- Over-abstraction. Writing a framework when a 30-line script would have done. Match the complexity to the actual problem.
- Mixing unit systems without conversion. Producing parts 10× or 0.1× their intended size is the classic API unit bug. Guard against it.
- Writing code before confirming the platform. Different APIs, same concept, incompatible code.
Handover checklist
Before delivering a script:
Bundled helper tool
For Fusion 360 specifically, this bundle ships a parameter-table generator:
${CLAUDE_PLUGIN_ROOT}/tools/generate_fusion360_parameters.py <parameters.json> <output.py>
Input is a JSON list of parameter objects ({name, value, unit, comment}); output is a Fusion 360 add-in script that calls userParameters.add(...) for each entry. Names and units are strictly validated and string fields are emitted via repr() so the generator is safe against malformed or hostile input.
See the docstring of generate_fusion360_parameters.py for the full input schema.
1---2name: cad-api-scripting3description: Generate and debug scripting code for CAD system APIs — Python for commercial CAD platforms, OpenSCAD language scripts, and equivalent programmatic modeling interfaces. Load this skill when the user wants to automate CAD construction, generate geometry programmatically, produce parameter-import scripts, or write reusable CAD macros. Trigger on phrases like "write me a Python script for...", "CAD macro", "OpenSCAD file", "parametric script", "API import for parameters", "script to generate geometry". Do NOT load for manual CAD construction guidance (sketch-by-sketch, feature-by-feature) — that is the cad-construction skill. Do NOT load for pure design exploration without code output — that is design-first-iteration. Complements cad-construction: construction defines WHAT to build, this skill handles HOW to build it programmatically.4---56# CAD API Scripting78A skill for generating, reviewing, and debugging code that drives CAD systems programmatically. Covers Python-based APIs (commercial CAD platforms), declarative languages (OpenSCAD), and similar scripting interfaces.910## When to use1112- User has a finished or near-finished design and wants to translate it into a reusable script13- User wants to import a parameter table into a CAD system from JSON/CSV14- User wants to generate repetitive geometry algorithmically (grids, arrays, variant families)15- User is debugging an existing CAD script16- User wants to expose a design as a configurable OpenSCAD module1718## When NOT to use1920- User is still exploring design options → `design-first-iteration`21- User wants step-by-step manual CAD guidance → `cad-construction`22- User wants general mechanical design principles → `mechanical-design-principles`23- User wants firmware code or web backend code → other engineering skills2425## Workflow2627### Phase 1: Clarify the target platform2829Before writing a single line, confirm:30311. **Which CAD platform / scripting language?**32 - Commercial (Fusion 360, SolidWorks, Onshape, Inventor, NX) — almost always Python or JavaScript-based33 - Open-source (FreeCAD, Blender for CAD, OpenSCAD, CadQuery, Build123d)34 - Declarative (OpenSCAD, JSCAD)352. **Which API version / library version?** APIs change. An older Fusion 360 script may not run on the current API.363. **Goal of the script:** one-shot generation, reusable module, parameter-import utility, test harness?3738If the user is unclear, ask 1–2 targeted questions. Do not assume.3940### Phase 2: Sketch the code structure before writing4142For non-trivial scripts, outline in plain text first:4344```45- Setup (imports, app/document handle, parameter loading)46- Parameter definitions (from file or hardcoded)47- Helper functions (reusable geometry operations)48- Main construction sequence (sketches, features, assembly)49- Error handling and cleanup50- Save / export step51```5253This structure sketch is the place to catch missing inputs, unclear naming, or scope creep — not the middle of a 200-line script.5455### Phase 3: Write the code5657Principles:5859- **Parametric from the start.** Every dimension is a named variable or parameter, never a literal in the middle of code. If the user has a parameter table from `cad-construction` (three-tier structure), mirror that structure in the code rather than inventing a new one.60- **Guard the obvious failure modes.** Check that the document exists, that the target component is found, that a selection is non-empty. Fail with a clear message, not a stack trace.61- **Keep one unit system throughout.** If the CAD system works in cm internally (Fusion 360), convert at the boundary, then keep code in mm (or whatever the user thinks in). Document the convention at the top of the file.62- **Comment intent, not mechanics.** `# Create a 3 mm fillet on the top edge to soften the grip surface` is useful. `# Call addByThreeEdges()` is not — the code already shows that.63- **Naming:** use descriptive names consistent with the parametric convention (`housing_wall_thickness`, not `wt`). Match the names the user is already using in their parameter table — do not re-invent.6465### Phase 4: Test plan, even for one-shot scripts6667Before handing the script over:6869- State explicitly which parameter values were assumed in testing70- Note edge cases the script does NOT handle (zero-width features, negative offsets, etc.)71- If the script modifies an existing document: warn about undo behavior7273## Language-specific notes7475### OpenSCAD7677- Declarative, no loops with state. Think in unions, differences, intersections, and modules.78- Use `$fn`, `$fa`, `$fs` deliberately — cheap during design, expensive during export79- Modules with default parameters enable library-style reuse: `module housing(width=100, height=40, wall=2.4) { ... }`80- For parametric designs with many variants, expose a `Customizer` section at the top with `// [Range]` and `// [dropdown]` annotations81- Version-pin the OpenSCAD version assumption in a comment (dev snapshot vs stable differ in available features)8283### Python-based commercial CAD APIs8485General patterns (apply across Fusion 360, Inventor, NX, SolidWorks Python wrappers):8687- **App and document handles first.** Most APIs require getting the app object, then the active document, then the root component — establish these once at the top.88- **User parameters over feature parameters.** User parameters (project-level named values) survive model regeneration. Feature-local values do not.89- **Transactions / undo grouping.** Wrap related operations in a single undo group so the user can undo the whole script in one step.90- **Error handling with try/except at the outer level**, logging which step failed. Commercial APIs tend to throw informative exceptions — catch them, report them, do not swallow them.91- **Unit handling varies:** some APIs expose values in internal units (often cm), others in document units. Always check, document the convention, and convert at the boundary.9293### Parameter-Import scripts (common use case)9495When generating a script that reads a JSON/CSV parameter table and writes them into the CAD system's user parameters:9697- Source of truth is the parameter table from `cad-construction` (JSON / CSV / Markdown) — the script does not invent parameters98- Preserve the three-tier structure if the table has it (primary / derived / tolerance). Some CAD systems let you group or tag parameters; use that if available.99- Each parameter needs: name, value, unit, optional comment100- If a parameter already exists in the document: update its value, do not create duplicate101- If a parameter name contains invalid characters for the target system: sanitize with a documented rule, not silently102- At the end: summary log of which parameters were created vs updated vs skipped103104### OpenSCAD / declarative DSLs105106- Emphasis on pure functions and modules107- Customizer-compatible parameter blocks at the top108- `assert()` for preconditions the caller must meet109110## Testing and handover111112A script is not done when it runs once. Before declaring complete:113114- Run with at least one edge-case parameter set115- Verify the output geometry visually (export to STL or screenshot the CAD window)116- Document the command to run the script (how to invoke it in the CAD system)117- Note the assumed API/language version118119## Anti-patterns120121- **Hardcoding dimensions in the middle of a script.** If a number appears in code that isn't at the top as a parameter, something is wrong.122- **Silent failures.** If a feature can't be created, the script must say so, not continue with an incomplete model.123- **Coupling to the current document state.** A good script works in a fresh document. If it depends on "this is the third component in the tree", it's fragile.124- **Over-abstraction.** Writing a framework when a 30-line script would have done. Match the complexity to the actual problem.125- **Mixing unit systems without conversion.** Producing parts 10× or 0.1× their intended size is the classic API unit bug. Guard against it.126- **Writing code before confirming the platform.** Different APIs, same concept, incompatible code.127128## Handover checklist129130Before delivering a script:131132- [ ] Target platform and API version documented at the top of the file133- [ ] All dimensions exposed as named parameters134- [ ] Error handling at the outer level135- [ ] Unit convention documented136- [ ] Tested with at least one realistic parameter set137- [ ] Invocation command / setup instructions provided138139## Bundled helper tool140141For Fusion 360 specifically, this bundle ships a parameter-table generator:142143```bash144${CLAUDE_PLUGIN_ROOT}/tools/generate_fusion360_parameters.py <parameters.json> <output.py>145```146147Input is a JSON list of parameter objects (`{name, value, unit, comment}`); output is a Fusion 360 add-in script that calls `userParameters.add(...)` for each entry. Names and units are strictly validated and string fields are emitted via `repr()` so the generator is safe against malformed or hostile input.148149See the docstring of `generate_fusion360_parameters.py` for the full input schema.