# MAC — Multi-Agent CAD for Parts and Assemblies
> Generate editable CAD parts and multi-part assemblies from natural language.
> [简体中文](README_cn.md)
[](LICENSE)
[](https://www.python.org/)
[](https://github.com/gumyr/build123d)


MAC turns an ordinary design brief into editable engineering geometry. It can
generate a single printable part or decompose a mechanism into separately
generated components, assemble them, validate the result, and export the
artifacts needed for downstream inspection and simulation workflows.
MAC was originally released as a single-part Text-to-CAD workflow and has
since received nearly 1,000 GitHub stars. This release preserves that workflow
while adding visual verification, an independent Judge, and experimental
multi-part assembly generation.

## Assembly Gallery (Technology Preview)
Building on the original single-part workflow, MAC v2 introduces experimental
natural-language assembly generation. The examples below are curated outputs,
not a measured prompt-success rate, and the assembly workflow is not presented
as outperforming CAD-agent skills. Validate generated geometry and joints before
manufacturing or simulation use.
### Complex assemblies
| Three-Axis Gantry Metrology Cell | Telescopic Cinema Robot Crane |
|---|---|
| A bridge-style inspection platform with three orthogonal motion stages. | A multi-stage crane with an articulated support and telescopic payload arm. |
|  |  |
| Heavy-Duty Mobile Manipulator | Advanced Vision Inspection Robot Arm |
|---|---|
| A mobile base carrying a visually detailed articulated manipulator. | A multi-joint inspection arm with a framed vision payload. |
|  |  |
### Complex-gallery generation usage
| Assembly | Planning & mating | Part generation & repair | Judge & other workflow | Total tokens | Estimated cost |
|---|---:|---:|---:|---:|---:|
| Three-Axis Gantry Metrology Cell | about 178,000 | 461,811 | 260,157 | **about 900,000** | **about $2** |
| Telescopic Cinema Robot Crane | 535,407 | 663,427 | about 451,000 | **about 1,650,000** | **about $3** |
| Heavy-Duty Mobile Manipulator | about 520,000 | 2,678,005 | 2,602,142 | **about 5,800,000** | **about $13** |
| Advanced Vision Inspection Robot Arm | 85,016 | 160,367 | about 55,000 | **about 300,000** | **about $1** |
### Compact functional assemblies
| Hinged Twin-Claw Gripper | Guided Linear Plunger | Rotary Fork-Key Tool | Reusable Five-Digit Hand |
|---|---|---|---|
|  |  |  |  |
These curated compact examples exercise natural-language decomposition, joint
interfaces, repeated-part reuse, and mirrored geometry. The complex gallery
shows how the same workflow scales to larger visual assemblies. See the
[assembly workflow documentation](mac_assembly/README.md) for implementation
details and current limitations.
## URDF Simulation
The assembly workflow can export generated mechanisms as URDF files for
downstream robotics and physics simulation. The demonstrations below use an
AI-generated hand assembly to execute object rotation and pick-and-place tasks
in simulation.
| Object Rotation | Pick and Place |
|---|---|
|  |  |
## Part Gallery
MAC also generates standalone mechanical and creative parts. The examples
below are editable CAD results, not image-only generations.
| Honeycomb Organizer | Gyroscope Ornament | Lighthouse | Smartphone Stand | Ball-in-Cage |
|---|---|---|---|---|
|  |  |  |  |  |
| Articulable Gyroscope | Multi-Link Chain | Geneva Mechanism | Plasma Reactor | Brake Disc |
|---|---|---|---|---|
|  |  |  |  |  |
The [single-part workflow documentation](multi_agent_cad/README.md) covers
configuration, execution, caching, and QA. Benchmark prompts and per-model
data are linked from its benchmark-details section.
## Real-World Results

The printed collection above includes benchmark parts and original showcase
models generated by the single-part workflow. MAC can also produce
print-in-place mechanisms containing separate bodies and functional
clearances:
## Single-Part Benchmark
The following numbers apply specifically to the documented ten-prompt,
141-feature **single-part-workflow benchmark**. They are not assembly success-rate or
assembly-cost claims.
| Workflow | Model | In-loop verification | Tokens | Estimated cost | Feature pass rate |
|---|---|---|---:|---:|---:|
| CAD Skill reproduction | Qwen 3.7 | — | 103.95M | $18.59 | 138/141 (97.9%) |
| CAD Skill reproduction | Qwen 3.8 | Visual | 87.46M | $29.45 | 132/141 (93.6%) |
| MAC v1 | Qwen 3.7 | Geometric | 0.90M | $1.43 | 140/141 (99.3%) |
| **MAC v2** | Qwen 3.8 | Visual + geometric | **1.40M** | **$4.85** | **140/141 (99.3%)** |
Under the Qwen 3.7 setup, MAC v1 used 116× fewer recorded tokens and
had a 13× lower estimated cost than the reproduced Skill baseline. Under
Qwen 3.8 with visual verification, MAC v2 used 62.7× fewer recorded tokens
and had a 6.1× lower estimated cost.
MAC v1 refers to the original single-part workflow and its published benchmark
run. MAC v2 refers to the updated single-part workflow with visual verification
and the independent Judge. Assembly generation is presented separately as a
technology preview and is not included in these benchmark figures.
Across the two documented model configurations, MAC retained a 140/141 feature
pass rate while using substantially fewer recorded tokens and lower estimated
cost than the corresponding reproduced Skill runs.
Methodology and raw breakdowns:
[single-part README](multi_agent_cad/README.md),
[English evaluation](docs/quantified_quality.md), and
[Chinese evaluation](docs/quantified_quality_cn.md).
## Why MAC?
- **Natural-language input** — describe geometry, dimensions, interfaces, and
motion without writing CAD code or an internal schema.
- **Parts and assemblies** — use one project for standalone printable parts
and articulated, multi-component mechanisms.
- **Editable engineering outputs** — export STEP, STL, and GLB rather than a
render-only result; assemblies also provide a URDF handoff.
- **Auditable generation** — inspect structured briefs, geometry plans,
generated Python, measurements, QA reports, and repair history.
- **Automatic execution and repair** — generated CAD is executed and checked,
with bounded feedback loops for recoverable failures.
- **Reuse instead of regeneration** — repeated and mirrored components can be
derived from one source geometry.
- **Model-flexible stages** — configure different OpenAI-compatible models for
planning, geometry, coding, and repair.
- **Visual workflow** — the single-part pipeline includes a browser UI with 3D
preview and downloadable results.
- **Built on a proven workflow** — MAC v2 extends the original nearly
1,000-star single-part pipeline with visual verification and assembly
generation while retaining the existing part-generation workflow.
## Quick Start
### Install
```bash
git clone https://github.com/Pan-Chera/Multi-Agent-CAD.git
cd Multi-Agent-CAD
conda env create -f environment.yml
conda activate multi_agent_cad
pip install --no-deps "aider-chat==0.82.3"
export DASHSCOPE_API_KEY="your-key"
```
The final `pip install` is needed because `aider-chat` pins NumPy 1.x, which
conflicts with build123d's NumPy 2.x requirement. It is therefore omitted from
`environment.yml`; `--no-deps` avoids replacing the working NumPy version.
The default configuration targets an OpenAI-compatible DashScope endpoint.
Other providers are covered in the
[single-part configuration guide](multi_agent_cad/README.md#configuration-and-model-providers).
The bundled cadpy runtime currently requires OCP 7.x, so installation constrains
`build123d` to `<0.13`. Version 0.13 switches to OCP 8 and cannot load the current
STEP runtime. If an existing environment has already upgraded, run
`python -m pip install "build123d>=0.8,<0.13"` to restore compatible dependencies.
> **pip users (no conda)**: `aider-chat` pins `numpy==1.26.4`, but `build123d>=0.8` requires `numpy>=2,<3` — these conflict in pure pip. Use this workaround (verified on macOS arm64 + Python 3.11):
>
> ```bash
> python3.11 -m venv .venv
> source .venv/bin/activate # Windows PowerShell: .venv\Scripts\activate
> pip install --upgrade pip
> # Install aider first (pulls numpy 1.26.4 + transitive deps), then force-upgrade numpy.
> # Verified: aider 0.82.3 imports cleanly on numpy 2.x — the pin is over-cautious upstream.
> pip install "aider-chat==0.82.3"
> pip install --no-deps --force-reinstall "numpy>=2,<2.3"
> pip install "build123d>=0.8,<0.13" "langgraph>=0.2,<0.3" "langgraph-checkpoint>=2.0,<3.0" \
> "pydantic>=2.5" "openai>=1.20.0" "anthropic>=0.30" \
> "trimesh>=4.0" "rtree>=1.1" "scipy>=1.10" "scikit-learn>=1.3" \
> "fastapi>=0.110" "uvicorn[standard]>=0.27" "ipython>=8.15" "pytest>=7.4"
> # --no-deps skips re-checking the numpy pin in pyproject.toml; fastapi+uvicorn
> # are already installed by the previous step, so the [web] extras resolve.
> pip install --no-deps -e .
> ```
>
> The last step registers the `mac-config-reset` console script and lets you run `python -m multi_agent_cad.graph` from any directory. See [requirements.txt](requirements.txt) / [pyproject.toml](pyproject.toml) for the canonical dependency list.
> **Windows**: the same `conda env create` + `pip install --no-deps aider-chat==0.82.3` flow works — `trimesh` and `rtree` come from conda-forge prebuilt; `OCP` is pulled in transitively by `build123d` (via its PyPI dep `cadquery-ocp-novtk`). Don't use the pure-pip workaround below on Windows — native wheels for `trimesh`/`rtree` can be unreliable. Set the API key in PowerShell as `$env:DASHSCOPE_API_KEY = "sk-..."` (or `set DASHSCOPE_API_KEY=sk-...` in cmd.exe). For the Web UI under conda, `pip install -e ".[web]"` inside the activated env works — `uvloop` auto-skips on Windows. CI covers Windows with Python 3.11 and Linux with Python 3.11/3.12, including an isolated wheel installation check.
### Generate one part
Set `USER_REQUEST` in [`multi_agent_cad/config.py`](multi_agent_cad/config.py),
then run:
```bash
python -m multi_agent_cad.graph
```
For the single-part browser UI:
```bash
pip install -e ".[web]"
python -m multi_agent_cad.web
```
The provider selector includes OpenRouter (`https://openrouter.ai/api/v1`).
Switching presets fills suggested stage and Aider model names; models you have
edited manually are preserved. Existing endpoint and model settings are loaded
from `config.py` when the page opens. For OpenRouter, Aider uses an
OpenAI-compatible model name such as `openai/qwen/qwen3-max`.
If the key field is blank, the Web UI uses the server's `DASHSCOPE_API_KEY`,
then `DS_API_KEY` from `config.py`. Explicit form keys take priority; API clients
can also supply the existing `config.DS_API_KEY` request field. Server keys are
never included in the configuration schema response or written to job config
files. Use a key for the selected provider.
The UI listens on `127.0.0.1` by default. It executes generated Python with
your user account's permissions, so do not expose it directly to an untrusted
network. Copying results to an arbitrary local directory is disabled unless
`MAC_WEB_ALLOW_DEST_PATH=1` is explicitly set.
#### Web UI security and environment variables
State-changing API endpoints (`POST`, `PUT`, `PATCH`, `DELETE`) require a
custom `X-MAC-CSRF: 1` header. The browser frontend sends it automatically;
non-browser clients (curl, HTTP libraries) must add it manually or the server
returns `403`:
```bash
curl -X POST http://127.0.0.1:8000/api/run \
-H "X-MAC-CSRF: 1" \
-H "Content-Type: application/json" \
-d '{"prompt": "a 30 mm cube", "api_key": "YOUR_API_KEY"}'
```
`GET` endpoints (`/api/health`, `/api/jobs`, status polling) are unaffected.
The following environment variables control Web UI behavior:
- `MAC_WEB_HOST` — bind address. Loopback values (`127.0.0.1`, `localhost`,
`::1`, the default) also enable a loopback `Host` allowlist as a
defense-in-depth CSRF layer. Binding to a non-loopback address (LAN
deployment) disables that layer; the `X-MAC-CSRF` header remains required.
- `MAC_WEB_ALLOW_CUSTOM_ENDPOINT=1` — opt in to non-loopback
OpenAI-compatible `DS_BASE_URL` hosts: vLLM on a private hostname, a
corporate gateway, or Ollama / LM Studio on a non-loopback address. Default
off; otherwise the host must match the provider allowlist (loopback,
`api.openai.com`, `api.deepseek.com`, `openrouter.ai`, `generativelanguage.googleapis.com`,
`.aliyuncs.com`, `.googleapis.com`). Scheme (`http`/`https`) is always
enforced.
- `MAC_WEB_ALLOW_DEST_PATH=1` — opt in to the `dest_path` artifact-copy
feature. When set, `MAC_WEB_DEST_ROOT` must also be set to an absolute
directory, and each request's `dest_path` must be relative and resolve
under that root. Absolute `dest_path` and `..` traversal are rejected.
- `MAC_CHILD_ENV_ALLOW=VAR1,VAR2` — pass additional non-secret environment
variables through to the generated-Python subprocess (for example,
`HTTP_PROXY,HTTPS_PROXY` on a corporate network). The default allowlist is
`PATH`, `HOME`, `TMPDIR`, `TMP`, `TEMP`, `LANG`, `LC_ALL`, `LC_CTYPE`,
`PYTHONPATH`, `PYTHONIOENCODING`, `LD_LIBRARY_PATH`, `DYLD_LIBRARY_PATH`,
`SYSTEMROOT`, `WINDIR`, plus `ITERATION` set per child. This applies to
deterministic / Aider-assisted cadpy generation as well as the LLM fallback
and repair runners. **Never list API keys or credentials
here** — env-var stripping reduces secret leakage but does not sandbox
the subprocess; see [SECURITY.md](SECURITY.md).
Generated CAD execution, including the cadpy runner, uses `CAD_SCRIPT_TIMEOUT`
from `multi_agent_cad/config.py`. Increase it for models whose geometry or export
needs more time; execution failures continue through the existing repair flow.
### Generate an assembly
Assembly input is also ordinary natural language. Run an included request:
```bash
MAC_ASSEMBLY_REQUEST="$(cat mac_assembly/assembly_prompts/natural_language_benchmarks/01_hinged_twin_claw_gripper.md)" \
python -m mac_assembly
```
Or provide a brief directly:
```bash
MAC_ASSEMBLY_REQUEST="Create a two-part hinged clamp with a fixed base and one rotating jaw." \
python -m mac_assembly
```
Assembly jobs are written under `assembly_jobs/job_/`, including
separate-part geometry, assembled STEP/STL/GLB, URDF, manifests, and QA
artifacts. See the [assembly guide](mac_assembly/README.md) before relying on
an output for manufacturing or simulation.
## Documentation
- [Single-part workflow: setup, architecture, benchmarks, and Web UI](multi_agent_cad/README.md)
- [Assembly workflow: decomposition, mating, reuse, QA, and exports](mac_assembly/README.md)
- [单零件中文文档](multi_agent_cad/README_cn.md)
## Citation
If you find this project useful for your research, please consider citing:
```bibtex
@misc{mac2026,
author = {Guanxing Qu and Xueyan Zou},
title = {MAC (Multi-Agent CAD): A Decoupled Multi-Agent Framework for Text-to-CAD Generation},
year = {2026},
publisher = {GitHub},
journal = {GitHub repository},
howpublished = {\url{https://github.com/Pan-Chera/Multi-Agent-CAD}}
}
```
The quantitative single-part evaluation uses
[earthtojake/text-to-cad](https://github.com/earthtojake/text-to-cad) (CAD
Skills) as the comparison baseline. If you cite the benchmark comparison,
please also cite that project:
```bibtex
@misc{texttocad2026,
author = {earthtojake},
title = {CAD Skills: A skills library for CAD, robotics, and hardware design agents},
year = {2026},
publisher = {GitHub},
journal = {GitHub repository},
howpublished = {\url{https://github.com/earthtojake/text-to-cad}}
}
```
## License
MIT — see [LICENSE](LICENSE).
The vendored [`packages/cadpy`](packages/cadpy) STEP/GLB runtime is derived
from [earthtojake/text-to-cad](https://github.com/earthtojake/text-to-cad)
(CAD Skills) and is redistributed under its original MIT license — see
[`packages/cadpy/LICENSE`](packages/cadpy/LICENSE).
## Acknowledgements
- [Tsinghua University, IEI Lab](https://maureenzou.github.io/lab.html) — the
lab where this project was developed; provided the research environment and
advisor guidance.
- [earthtojake/text-to-cad](https://github.com/earthtojake/text-to-cad) (CAD
Skills) — source of the comparison baseline and the ten shared single-part
benchmark prompts. The vendored [`packages/cadpy`](packages/cadpy) runtime
also derives from this project and retains its original MIT copyright.
- [build123d](https://github.com/gumyr/build123d) — algebraic B-rep CAD kernel.
- [LangGraph](https://langchain-ai.github.io/langgraph/) — stateful agent
orchestration.
- [Aider](https://aider.chat/) — LLM-driven code repair.
- [Qwen Model Studio](https://www.alibabacloud.com/help/en/model-studio/) —
OpenAI-compatible models used in the documented experiments.