Parametric CAD you write as code

For people and their AI agents. Select edges with a description like “hole rims on the top face”, get every part measured on an OpenCASCADE B‑rep, and give your agent the same tools over MCP.

Open ParCAD web›

Free · MIT or Apache-2.0 · Experimental

bracket.jspart.js
1const plate = box(80, 60, 8).tag("plate");2const wall = box(8, 60, 40).at(-36, 0, 20).tag("wall");3 4const body = union(plate, wall, { blend: 6 });   // the blend is the fillet5const drilled = body.cut(6  ...grid(2, 2, 36, 40).map(([x, y]) => cylinder(3, 32).at(x, y)),7);8 9return drilled10  .edges({11    curve: "circle",12    role: "hole",13    adjacentTo: { faceNormal: "+z" },14  })15  .expect({ count: 4 })   // four rims, or the build stops16  .fillet(0.8);

The selector matches the four hole rims on the top face. Move a hole and it matches them again; lose one and the build stops at .expect()

Loading mesh
Exported mesh · drag to orbit
Size
80 × 60 × 44 mm
Volume
55 231.168 mm³
Bodies
1
Watertight
yes

Free and open source · macOS, Linux, Windows, browser

Desktop appDownload from Releases›No installOpen ParCAD web›
Why ParCAD

Code-CAD that stops when an edit breaks the part

In a CAD script, moving one hole can shift a fillet onto a different edge while the build still succeeds. ParCAD describes geometry, checks each description on every build and measures the solid it made.

Select edges by description

Write what you mean: the circular rims that open onto the top face, the seam where the arm meets the hub. The description keeps matching after you move a hole or add three more.

The example bracket, rendered by the kernel

A drifted selector stops the build

Add .expect({ count: 4 }) to a selector. If an edit changes what it matches, the build stops and lists every edge it found, with its length and position, so you know what to change.

evaluate_part · refused
error expected 3 edge(s), but matched 4. The model's topology
changed; inspect the current edges and update the selector
or expectation. The edges matched, shortest first:
  18.84 mm arc at (-18.00, -20.00, 4.00), convex 90°
  18.84 mm arc at (-18.00, 20.00, 4.00), convex 90°
  18.84 mm arc at (18.00, -20.00, 4.00), convex 90°
  18.84 mm arc at (18.00, 20.00, 4.00), convex 90°

One OpenCASCADE model

Your script builds a small graph, and OpenCASCADE turns it into faces and edges. The viewport, the measurements and the STEP file all come from that one solid.

Fillet, chamfer, blended union, intersect, loft, sweep, helix, revolve, shell, draft, polar pattern and mirror

Every number is measured

Reports read volume, wall thickness, whether two bores meet and the gap between a lid and its base off the built solid. The jar and cap in the picture sit 0.25 mm apart on the thread.

A screw-top jar and its cap, 0.25 mm apart on the thread

See inside the part

Cut any part on a plane to check that bores meet and walls keep their thickness. An agent gets the same section views over MCP.

A manifold block in section

Built so models can make models

The running app serves MCP at 127.0.0.1:4242/mcp from the same service the window uses. An agent reads the language, builds, measures and exports parts, and works in the session you have open.

What an agent is shown: four views at one scale, two sections, and faces coloured by tag

Add it to your agent

One line for Claude Code or Codex, a plugin that brings a usage skill, or one click in Cursor and VS Code.

claude mcp add parcad -- parcad mcp

Pictures made for reading

Four views at one scale, sections through the inside, and faces coloured by the tag that built them, drawn for a model that reads images.

No install, one link

Open ParCAD web, choose Connect your AI and give your client the link. The browser tab is the server; the relay forwards messages and stores none.

Tested on small models

Each tool reply goes to a small model over MCP, in both thinking modes. A trial counts as SOUND only when the model reached the right answer by the route the case requires.

Free. Three ways to run it

Each one runs the same kernel, with the same tools and reports.

Desktop app

Free

Releases · winget on Windows

The editor, the viewport and the MCP server in one window.

What you get

  • macOS Apple silicon, Linux .deb and .AppImage, Windows .msi
  • Every build measures the whole eval corpus before upload
  • UI and MCP on 127.0.0.1:4242, shared live with your agent
  • Parts are plain .js files you can edit in any editor
  • Unsigned for now: macOS asks you to clear the quarantine flag after each install
Headless

Free

Homebrew, macOS and Linux

The same host without a window, for your browser or your agent.

What you get

  • parcad serve — the whole app at 127.0.0.1:4242
  • parcad mcp — stdio for clients that launch servers
  • parcad tools and parcad call — every tool from a shell
  • brew services start parcad keeps one up from login
ParCAD web

Free

Nothing to install

The desktop editor and kernel, compiled to WebAssembly, in a browser tab.

What you get

  • Every seed part, the op palette, sections and inspection
  • Export STEP, 3MF and STL as downloads
  • Connect an AI client with a link
  • Parts live in that browser's storage
  • Heavy parts get 60 s, or up to 600 when an agent asks

MIT or Apache-2.0, at your option. OpenCASCADE and its bindings are LGPL-2.1, so redistributing a binary carries obligations — NOTICE.md spells them out. Builds are unsigned for now; the README says how to open them.

Operations for small mechanical parts

Fillet, chamfer, blended union, intersect, loft, sweep, helix, revolve, shell, draft, patterns and mirror, plus threads, thickened surfaces and fitted curves.

Each operation lands with a case in eval/cases/ that records what it measured. When a change moves one of those numbers, a test fails before release.

Fillet, chamfer, blended union, intersect, loft, sweep, helix, revolve, shell, draft, polar pattern and mirror, each built by the exact kernel

Modelled threads

threadedRod on the neck, threadedHole in the cap, 0.25 mm clearance each. between_bodies reads the gap back off the built solids.

Curves from a formula

Every flank an involute the script certifies to a few millionths of a millimetre.

Lofts with a measured wall

A ruled loft through nine star sections, hollowed along the same twist to a 2 mm wall.

Twenty-eight example parts

Brackets, flanges, manifolds and heat sinks — parts you print or machine one of. Each opens as a seed part in the app, and most have a case in the eval corpus, so an example that stops building fails a test.

All examples›

Frequently asked questions

For anything else, open an issue on GitHub.

Open an issue›

Is it ready for real parts?

It's experimental: one author, and the DSL still changes. Every operation is checked against measured geometry in the eval corpus, but none of it has had years of use yet.

Measure a part before you machine it.

How does it compare to CadQuery, build123d and OpenSCAD?

Those projects are older and more mature. ParCAD differs in three ways: selectors describe geometry and check how many edges they match; the viewport, measurements and STEP export come from one B‑rep; and every report carries measured numbers an agent can read.

What is it for?

Small mechanical parts: brackets, flanges, manifolds, heat sinks, enclosures — things you print or machine one of. Units are millimetres.

Which agents can use it?

Any MCP client: Claude Code, Codex, Cursor, VS Code, the Claude app as a custom connector, or anything that connects to a URL. Start the agent on read_docs, which returns the whole language in one call.

What can I export?

STEP for exact surfaces, 3MF for a slicer with each body as its own named object, and STL for a bare mesh. Each export reports the file's size, volume, watertightness and the deflection of every triangle.

How is it licensed?

MIT or Apache-2.0, at your option. OpenCASCADE and its bindings are LGPL-2.1, so redistributing a binary carries obligations; NOTICE.md spells them out.