A CLI tool and agent skill for designing 3D-printable mechanisms in Build123d, built for LLM-driven iteration.
khana (ख़ाना) is a Hindustani suffix meaning "house" or "workshop" — as in kar-khana (factory) or dawa-khana (pharmacy). cad-khana is a place for CAD.
Status: early. API may still churn.
Used in practice to design the Sorted Studs LEGO scanner — every part drawn by an LLM via cad-khana.
cad-khana wraps Build123d with a diagnostics-first workflow. You
(or an LLM agent) write Python scripts that declare parts and
assemblies; the khana CLI runs them, exports STL/STEP, and writes
a structured diagnostics.json reporting interferences, clearances,
wall thickness, and overhangs. Assertions in the script become build
failures when violated, so geometric constraints are enforced, not
hoped for.
The tool is designed to close a specific gap: LLMs can reason about
CAD geometry from code but need explicit feedback on the things a
human would catch visually. Computed diagnostics cover the scalar
questions; khana draw produces engineering-drawing PNGs (HLR
line-art) a multimodal agent can read for shape-level questions that
numbers don't express well.
Existing code-CAD tools (OpenSCAD, CadQuery, Build123d) assume a human with a render window. For agent-driven design, a different feedback loop works better:
- Agent writes a Build123d script.
khana buildruns it, exports geometry, writes diagnostics.- Agent reads diagnostics, edits the script, repeats.
- When a shape-level question arises that diagnostics can't answer,
the agent runs
khana drawand reads the PNGs directly. - When the design is clean, a human reviews it in the OCP viewer.
Humans stay in the loop for taste and physical-world validation; correctness iteration happens in code.
khana build <path> # run script, export, write diagnostics.json
khana check <path> # diagnostics only, no export
khana view <path> # build + push to OCP viewer
khana draw <path> # orthographic/iso engineering drawings (HLR line-art)
khana diff <old> <new> # diff two diagnostics.json files
Copy the skill into your project (loads only in this project's context):
git clone --depth=1 https://github.com/cyberchitta/cad-khana /tmp/cad-khana
cp -r /tmp/cad-khana/skills/cad-khana .claude/skills/
rm -rf /tmp/cad-khanaOr for all projects (loads everywhere):
git clone --depth=1 https://github.com/cyberchitta/cad-khana /tmp/cad-khana
cp -r /tmp/cad-khana/skills/cad-khana ~/.claude/skills/
rm -rf /tmp/cad-khanaThe first time you ask Claude for CAD work, the skill notices khana isn't installed yet and follows references/install.md to run uv tool install once. After that, the skill loads automatically whenever you ask for CAD work.
From a local checkout (for development):
uv sync
uv run khana build assembly.pyAs a global tool from GitHub:
uv tool install git+https://github.com/cyberchitta/cad-khanaexport_glb / export_animated_glb shell out to
gltf-transform for two post-processing
passes:
join— merges primitives within each named node. OCP'sRWGltf_CafWriteremits one primitive per face style (~30 per shape on real assemblies), which inflates the output glTF's JSON to multiples of the binary payload. Joining is mandatory and runs on every export.draco— re-encodes mesh attribute buffers with Draco compression. Optional (draco=Falseto skip).
Together they typically shrink a CAD glTF by ~10×. Install:
bun install -g @gltf-transform/cli # or: npm install -g @gltf-transform/cliWithout the tool on $PATH, export_glb raises a RuntimeError
naming the install command. No Python equivalent exists for the
join pass — it's the reason we shell out.
khana view pushes geometry to the OCP CAD Viewer, a standalone web
server. The easiest host is the
VS Code extension,
which embeds the viewer in an editor pane.
Any editor that can launch a task and open a browser tab also works:
run python -m ocp_vscode (from the cad-khana environment) to start
the viewer, then bind khana view to a task (e.g. a Zed
tasks.json).
The viewer is only needed for khana view; khana build, khana check, and khana draw work without it.
from build123d import *
from cad_khana.core.assembly import Assembly
from cad_khana.core.build import build
def housing(width: float = 40, depth: float = 30, height: float = 20):
with BuildPart() as p:
Box(width, depth, height)
return p.part
def lever(length: float = 25):
with BuildPart() as p:
Box(length, 5, 3)
return p.part
assembly = (
Assembly()
.with_part("housing", housing(), location=Location((0, 0, 0)))
.with_part("lever", lever(), location=Location((0, 0, 12)))
.assert_no_interference("lever", "housing")
.assert_clearance("lever", "housing", min_mm=0.2)
.assert_min_wall("housing", min_mm=1.5)
)
build(assembly, out="outputs/")The LLM-aided-CAD space is active. For a structured map see 60 Alternatives to CAD Khana (May 2026), which splits the landscape by who closes the feedback loop: agent-driven (the LLM iterates on structured diagnostics) vs. human-directed (you inspect renders and steer).
cad-khana sits in the agent-driven half: structured JSON diagnostics let an LLM iterate without human review.
CLAUDE.md— operational instructions for agents working on this repo.skills/cad-khana/SKILL.md— agent-facing guide to using the tool.skills/cad-khana/references/install.md— one-shot install steps the skill follows on first use.
Apache-2.0.