Metadata-Version: 2.5
Name: zenve3d-mcp
Version: 0.6.3
Summary: Model parametric CAD parts for Zenve 3D from an MCP client
Project-URL: Homepage, https://zenve3d.com
Author: Zenve
License: Proprietary
Keywords: 3d-printing,cad,mcp,parametric
Classifier: Environment :: Console
Classifier: License :: Other/Proprietary License
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Multimedia :: Graphics :: 3D Modeling
Requires-Python: >=3.10
Requires-Dist: mcp>=2.0.0
Description-Content-Type: text/markdown

# zenve3d-mcp

Model **parametric CAD parts** for [Zenve 3D](https://zenve3d.com) from Claude,
or from any other MCP client.

Ask for a box and you get a *project* — a sketch, its dimensions, an extrude, a
timeline you can go back and edit — not a mesh someone has to live with.

## Install

```jsonc
// Claude Desktop ▸ Settings ▸ Developer ▸ Edit Config
{
  "mcpServers": {
    "zenve3d": { "command": "uvx", "args": ["zenve3d-mcp"] }
  }
}
```

macOS on Apple silicon, and nothing else installed: the wheel carries the
engine. Zenve 3D itself is a separate install from the App Store — you need it
to open what the agent builds, but not to build it.

## The four tools

| Tool | What it does |
|---|---|
| `guide` | The complete `.zcmd` language reference. The agent reads it once, then writes parts. |
| `run` | Runs a script through the real engine and reports what it saw — regions, faces, edges, solver state, the body table, every feature's state. Saves the script (and, on request, an STL) into `~/Downloads/Zenve`. |
| `describe` | The same report for the project you have **open in the app**, so the agent can work from what you already have. |
| `apply` | Edits that project, live in your viewport, as one undoable step. |

`run` is the loop, and the loop is the point. A script cannot predict the
enumerations a kernel produces — *a plate with a hole is two regions* — so the
agent writes a few lines, runs them, reads back what exists, and writes the
next few against the truth instead of a guess. A refusal names its line and
still prints everything before it, which is usually what says what the right
answer was.

Each call gets a fresh engine and nothing is remembered between them. The
script is the state: to change a part, the agent sends it again with the change
in it.

## Getting the part into the app

The finished script is already on disk: `run` saves it as
`~/Downloads/Zenve/<name>.zcmd` and names the path in what it reports back. One
file per part, rewritten on every run, so what is in the folder at the end is
the finished thing rather than a dozen numbered attempts. Open it with
**File ▸ New from Script…** in Zenve 3D. On iPad, send the file over AirDrop or
through Files and import it there.

Ask for an STL alongside it once the part is right, and it lands beside the
script ready to slice.

Set `ZENVE_OUTPUT_DIR` to put those files somewhere else.

## Working on the project you have open

Turn on **AI mode** — the lock beside the panel buttons — and the agent can
read your open project with `describe` and edit it with `apply`. The edit
appears in the viewport straight away and ⌘Z takes the whole thing back, however
many commands were in it.

The lock is the whole contract. It stops the app's own editing while an agent
is working, which is what keeps the part it is picking faces and edges off from
moving underneath it, and it is what puts the app's pointer to the open project
where this server can find it. Turn it off and both tools say so instead of
guessing.

Nothing lands silently. `apply` refuses if the lock is off or if the document
has moved since the agent last read it, and if the app does not take the edit
within ten seconds it withdraws it and says which of the three likely reasons
to check.

The projects folder is `~/zenve3d` by default — the one the app asks you to
pick on first launch. If you picked somewhere else, set `ZENVE_SESSION_DIR` to
it.

## Building from a checkout

```sh
./scripts/build-zenve3d.sh     # stages the binary and the guide
cd clients/mcp && uv build --wheel
```

The binary is built against the static OCCT slice in `prebuilt/occt/`, so it
depends on nothing but macOS — checked by the build script rather than assumed.
