Skip to main content
Glama
graphgrow

root-ext-cad

by graphgrow
README.md
# root-ext-cad

CAD-engineering MCP tool server — code-CAD builds (build123d/CadQuery),
model inspection, meshing, DFM-lite validation, and mechanical
calculators. Built as the mechanical-engineering pack for
[ROOT Workspace], but it speaks plain MCP stdio and works with any MCP
host.

The workspace client stays domain-free by doctrine; **this repo is
where the CAD knowledge lives.** Tools reach both ROOT runtimes (the
brain-governed deployment and the lite Tier-0 harness) through the
client's mcp-bridge, and every call is governed — write-class tools
gate like any write; network tools park for approval.

## The charter (binding)

**Source is truth; artifacts are derived.** The pack never overwrites
a user's file in place: geometry writes land in a caller-named output
directory (default `derived/` beside the source), and every write tool
refuses an output path that collides with its input.
`tests/test_server.py::test_no_inplace_mutation_tools_exist` and the
collision-refusal tests enforce this in CI, not just in prose.

Parametric **source** (a build123d or CadQuery `.py` script) is the
model; STEP/STL/glTF/3MF are exports. `model_build` executes scripts —
it says so plainly, runs them in this pack's own venv as a
resource-capped subprocess, and is classed write, never read.

## Tools

| Tool | Class* | What it does |
|---|---|---|
| `model_inspect` | read | STEP/BREP/STL → bounding box, volume/area, mass (given density), topology counts, per-solid summary |
| `model_validate` | read | DFM-lite lint: open (non-watertight) shells, invalid B-rep, tiny edges/faces, pairwise interference & clearance — every finding carries its evidence and threshold |
| `model_build` | **write** | Run a build123d/CadQuery parametric script (sandboxed subprocess, CPU/memory/wall caps) → STEP/STL/glTF/3MF into the output dir + a build report |
| `model_mesh` | **write** | STEP/BREP → tessellated STL/glTF/3MF with linear + angular tolerance controls |
| `calc_fits` | read | ISO 286 limits & fits (hole-basis subset), clearance/interference verdicts |
| `calc_fastener` | read | Metric coarse threads: pitch, stress area, tap & clearance drills, preload/torque first-cut |
| `calc_beam` | read | Beam bending first-cut: cantilever / simply-supported, point / UDL, rect / round / tube sections |
| `calc_mass_rollup` | read | Assembly mass + 3D center of gravity from a component list, envelope check |
| `model_diff` | read | Geometric diff of two revisions: volume/area/bbox deltas, bodies unchanged/moved/added/removed by shape signature — geometry, not a feature tree, and the report says so |
| `drawing_project` | **write** | Named-view (front/top/…/iso) SVG or DXF projection: visible edges + dashed hidden layer — a silhouette for hand-off, not a dimensioned drawing |
| `text_to_cad` | **external** | Starter model from a text prompt via Zoo's ML-ephant API (+ its editable KCL source when returned); needs `ZOO_API_KEY`, refuses by name without it |

\* Classes derive fail-safe from annotations in the ROOT client:
read tools declare `readOnlyHint: true, openWorldHint: false`; write
tools declare `readOnlyHint: false, openWorldHint: false` (the
closed-world write class); network tools (Phase CAD-D: `text_to_cad`)
will declare `openWorldHint: true` and refuse by name without their
key.

## Connect it to ROOT Workspace

Settings → **Connected tools** → the connect form:

- **Name:** `cad-eng`
- **Command:** `uv run --project /path/to/root-ext-cad root-ext-cad`
  (a local checkout), or once published: `uvx root-ext-cad`

Run the row's **Check** (doctor) after connecting. Keep model files
and build scripts inside granted folders so the agent can cross-read
them with `fs.*`. Builds must finish inside the bridge's call ceiling
(120 s; 90 s once promoted) — the default subprocess wall cap is 75 s.

## Development

```sh
uv venv .venv
uv pip install --python .venv/bin/python -e ".[dev]"
.venv/bin/pytest
```

Layering rule: `server.py` is wiring only; every capability lives in a
plain-Python module (`inspection.py`, `meshing.py`, `validate.py`,
`buildrun.py`, `calc.py`, `geometry.py`) with logic separated from
I/O so the rules stay unit-testable on synthetic shapes — no fixture
model files required.

## Roadmap

- Later, each behind its own ADR: FreeCAD GUI-bridge companion,
  Onshape connector, KCL as a second source dialect, FEA hand-off
  recipes, PMI/GD&T presence reporting

TDQS

A4.1/5.0

Scored across 11 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: model_inspect summarizes, model_validate checks manufacturability, model_build executes scripts, model_mesh tessellates, model_diff compares, drawing_project projects to 2D, text_to_cad generates from text, and the calc_* tools cover specific engineering calculations with no overlap.

Naming Consistency4/5

Tool names consistently use a verb_noun pattern with model_ and calc_ prefixes. Minor deviations: drawing_project uses noun_verb, and text_to_cad uses a different form, but they are still clear and fit the overall scheme.

Tool Count5/5

11 tools is well-scoped for a CAD server covering both model operations and engineering calculations. Each tool serves a specific need without being overwhelming or too sparse.

Completeness4/5

Covers core CAD workflows: inspect, validate, build, mesh, diff, project, and text generation. Calculation tools cover common mechanical engineering needs. Minor gaps like direct export to common formats or more advanced analysis, but overall complete for its stated purpose.

Maintenance

ActivityMaintained
ResponsivenessSyncing