cad
Create, modify, inspect, and validate parametric CAD parts and assemblies authored as cadgen model scripts. Use for natural-language CAD specs, reference images, 2D technical drawings, STEP/STP generation or direct inspection, Python CAD source, source-level joints, selector references, geometry fac
By earthtojake · 10,534 installs
npx skills add earthtojake/text-to-cad --skill cad
Source repository · Upstream listing
CAD modeling and inspection
Provenance: maintained in [earthtojake/text to cad](https://github.com/earthtojake/text to cad).
Use the installed local skill files for the current interface.
A model is a Python function; running its script rebuilds it in cadgen's warm engine, and the
page the person has open updates. Files are exports, made when asked.
Start with the task
Task Start with Reference
Create or edit a part or assembly The project's model script, or a new one ([below]( write a model and run it)). [Models](references/model contract.md), [build123d](references/build123d modeling.md), [positioning](references/positioning.md)
Organize a CAD project The project's existing layout. [Project layout](references/project layout.md)
Export STEP, STL, 3MF, GLB or xbf cadgen export <id <file . [Exports](references/exports.md)
Use a vendor STEP, an xbf or a scan in a model read step , read xbf or read mesh in the body. [Inputs](references/model contract.md inputs)
Resolve a reference from a prompt cadgen inspect <id '<ref ' . [References](references/inspection and validation.md references)
Measure or check geometry A check script that calls the model. [Inspection](references/inspection and validation.md)
See a model, a view or a pose cadgen snapshot <id out.png . [Snapshots](references/snapshot review.md)
Articulate a mechanism build123d joints in the body, then cadgen.ap242 . [Kinematics](references/kinematics.md)
Explode, reveal or showcase a model cadgen.gltf 's animation() in the body. [Animation](references/animation.md)
Open an existing XBF, STEP/STP, STL, 3MF or GLB Show it to the user. [Show the model]( show the model)
A project built with cadgen 0.7 may need migrating: see [migrations](references/migrations.md).
For 2D DXF drawings use $dxf ; this skill owns any 3D part the drawing projects.
Use the corresponding robot description skill for URDF, SRDF or SDF.
Setup and paths
Run cadgen through the cadgen command its installation writes, so this skill's commands
share one installation, and its engine server, with the CAD app's:
cadgen below means cadgen +0.8.2 ( ~/.local/bin/cadgen +0.8.2 where ~/.local/bin is not on your PATH)
python below means cadgen +0.8.2 run
If cadgen is not on your PATH, or it says 0.8.2 is not installed, run
uvx no config managed python python 3.13 from cadgen==0.8.2 cadgen doctor once,
outside any sandbox or with its permission: it installs cadgen, registers it, writes the
cadgen command and starts the engine. With the CAD app's server running, nothing else
needs the sandbox's permission: it starts the engine and holds it. Without it, a sandboxed
shell cannot start the engine; when a command says no engine is running, run cadgen server
outside the sandbox once.
cadgen doctor <skill dir reports the installation in use, whether it is the one
this skill pins, whether the CAD kernel loads, and whether the engine is running, starting
it when none is. Each
command's help lists its flags. The first launch downloads cadgen and may outlast a
host's server start timeout (Claude Code: 30 s by default, raised by setting MCP TIMEOUT in
milliseconds; Codex: the plugin asks for 300 s); a restart resumes the download.
A project venv can put its own cadgen ahead of the launcher on PATH, even when
~/.local/bin is on PATH. Run ~/.local/bin/cadgen +0.8.2 doctor to diagnose that
case and use that full launcher path for commands until PATH is corrected.
One engine serves the installation: the first run starts it, every run and every
command goes through it, and it serves the viewer. cadgen status lists its workers
and the documents it holds; cadgen stop stops it, and any older one left running.
A build cut off by the shell's time limit keeps running in the engine; run the same
command again and it waits for that build and replays it ( cadgen status shows it).
Give a cold build of a large model the shell tool's longest timeout, or run it in the
background. A refused folder is another case: if a command ends with 'the system denies
cadgen's local engine', this shell's sandbox forbids the engine's folder itself: rerun it
with the sandbox's permission (in Codex, escalated permissions) rather than retrying.
Command line paths, and the paths read step , read xbf , read mesh and export
take, are relative to the working directory, as are a model's own file reads. Anchor
them on file in code that must run from any folder.
Write a model and run it
A part or an assembly is a function with no parameters, decorated @model (or with its
file decorators, never both), that returns a build123d shape. Its dimensions are the
arguments of a plain helper function, and each configuration is a @model of its own, with
its own id and page; constants several models share live in a module they import. A call
builds it and returns its document: a handle with .id , .url , .shape (the built shape)
and .export(...) . For example, src/bracket.py :
Each call the script's main makes prints how its model built, the delta under it
(parts, bounds, joints and sequences), its document's id: and its page, view: (the
handle's .id and .url ). An unchanged rerun prints took ... nothing ran instead. Give the
user the page once ([Show the model]( show the model)) and use the id for every command
after it. The id comes from the
script's path and the function's name, or the script's folder and an explicit @model(name="...") ,
so it is the same run after run, and the open page follows every run. A model's name is its identity
within its namespace, the function's name by default, name= gives it another. In 0.8 the namespace
is the script's folder; two explicit names in it must differ.
Running the script is the rebuild. It writes no file. The engine's warm worker for
the script replays every operation an edit did not reach, so a comment re runs nothing
and a dimension edit re runs what reads it
([what a run runs](references/model contract.md what a run runs)). Decoration only
declares: keep the calls under if name == " main ": so other scripts can import
the models.
@memo marks stages, never parts. The engine already replays every kernel call, so
mark only a function holding seconds of kernel work that an edit elsewhere leaves
alone, such as a whole sub assembly stage; never a part, never a helper called many
times ([ @memo ](references/model contract.md memo marks stages)).
An assembly calls its parts. Its body calls each part model and composes its shape
( plate().shape ), places and labels it, and returns a Compound . Each child builds in
the same run and keeps its own document and id. Running a child's script alone leaves the assemblies that
use it as they were: run the assembly.
import build123d as bd , and use it attribute style ( bd.Box ). The import is lazy:
the kernel loads on first use, in the worker. from build123d import Box , or a
module level bd.Color(...) or bd.Align default, loads it at that line instead.
Colours are sRGB , as a person picks them: part.color = " 4a6fa5" , or 0 255
integers. Import metals from bd materials ; assign a native material with
part.material = metals.aluminum()
([colour and materials](references/build123d modeling.md colour and materials)).
Inputs are read step , read xbf and read mesh in the body, and any file its
Python opens, each tracked by its bytes. The clock, environment variables and
randomness are not seen: a body is a function of its code and its inputs. Compose
project models by calling them, never by reading a file the project exported.
References to faces, edges and parts come from cadgen inspect <id [ref] , and the
body picks the same element with build123d's selectors; verify with a snapshot when in
doubt ([references](references/inspection and validation.md references)).
A shape with no function (a notebook cell, a REPL) is handed over:
model(shape, name="plate") returns the same handle, and no command builds it again.
The engine never reruns code. A restart reopens every document from the engine's
cache, as last built. When the cache holds no file of one (deleted by hand, or never
saved), the page, cadgen inspect <id and cad show print the command that brings it
back ( cadgen run src/bracket.py ). Run it.
Model units are millimetres, +Z up. $step parts finds real vendor models of
purchasable parts such as fasteners, bearings and servos.
An image without a scale sets no fit dimension, and a drawing's units, projection and
revision decide how its numbers read. A missing or conflicting dimension that changes
the result is the person's to settle; a value chosen in its place is an assumption.
Files, when asked
A file is an action on the document the engine holds, never part of the model: no code
change and no rebuild, written at once. It holds what the document held when it was
written, so a change made after it is in the file only once it is written again. Write one
when the person asks for it:
A project with standing deliverables gets an exports.py that imports its models and
calls export(x, path, ...) on each ( x a model call's handle); running it rewrites every deliverable
([exports](references/exports.md)). An export takes a document and its destinations,
and nothing else: a posed file is a model that returns the posed assembly
( posed(arm(), "folded") ), and a part on its own is the part's own model.
The xbf, cadgen's own document, is Save As: export one only to share a model without its
code, or to compose it in another project with read xbf . A restart needs none: the
engine's own cache reopens every document it built, as last built. A vendor STEP is
converted to an xbf once
( cadgen export vendor/motor.step vendor/motor.xbf ) and read with read xbf , many
times faster than parsing the STEP.
Projects built around exported files
A project can instead revolve around its exported files, but only when the person asks to
iterate on the exported file itself or the project already does: an exports.py , a consumer
that reads the files (a robot description, a slicer, a drawing pipeline), or a 0.7 era
layout, whose runs wrote files. The loop is three steps. The script writes the file on each
run, by a file decorator in place of @model ( @step("../STEP/bracket.step") , relative to
the script), or exports.py or cadgen export follows the run. Show the file's page, not
the model's: it follows the file on disk, updating when a run rewrites the file.
Verification reads the file: cadgen snapshot or cadgen inspect with its path, or
read step in a check. The costs keep the default the default: each iteration pays the
file's translation and the page's re read, a STEP parsed again; a file names no model, so a
ref picked on its page has no made by and a Quick Edit from it no way back into the code;
and the model's page stays the better place to look while editing.
[Exports](references/exports.md model page or file page) tables the triggers and costs.
Pictures
After every run, read its line and the delta under it; a contradiction with what you
intended is fixed before anything else. A number the person gave is checked by an assert
inside the model's body on what the geometry measures, a bound, a distance or a volume, or by
cadgen inspect , never by restating the constant, and never by code after the call in the
model's script ([inspection](references/inspection and validation.md)). A derived number they
asked for is a check script; neither is ever read off a picture. A structural or appearance
change, new parts, placements, colours or a mechanism,
gets the snapshots it takes to judge it, usually one from the angle that shows the change,
more when a view leaves the