dcc-mcp-freecad
Production FreeCAD adapter for typed, durable parametric modeling and CAD exchange through DCC-MCP.
Illustrative workflow based on the live OpenSCAD → FreeCAD → Blender/Godot acceptance run; generated source is retained in docs/images/dcc-mcp-freecad-showcase-source.png.
Capabilities
- Detect FreeCADCmd and report the actual FreeCAD/Python runtime.
- Create, inspect, recompute, validate, copy, and dependency-safely edit FCStd documents.
- Add and update boxes, cylinders, spheres, cones, and tori with typed dimensions and placements.
- Create parametric union, cut, and intersection features.
- Import or export STEP, IGES, BREP, STL, and OBJ geometry.
- Return object links, placements, shape/mesh topology counts, volume, area, bounding boxes, file size, and SHA-256 provenance.
No arbitrary Python, macros, module paths, or FreeCAD command-line flags are accepted. The adapter invokes only its packaged method-dispatch driver.
Requirements
This adapter spans two separate Python interpreters. They have different
versions, different sys.path, and different site-packages:
| Side | What runs there | Python version | Who owns that version |
|---|---|---|---|
| Wrapper (service side) | the dcc-mcp-freecad CLI, server, and doctor, plus the process that launches FreeCADCmd |
3.7+ (requires-python = ">=3.7") |
the environment you pip install dcc-mcp-freecad into |
| Host (FreeCAD side) | src/dcc_mcp_freecad/freecad_driver.py and every skill script |
3.10+ — the interpreter FreeCAD is built against and ships (3.11 in both release lines CI exercises) | your FreeCAD installation |
dcc-mcp-core0.20.36+ in the wrapper environment.- A FreeCAD version covered by the compatibility matrix below, with either a working
FreeCADCmd/freecadcmdor an explicitly configured compatible executable Python interpreter and installed native FreeCAD library for the opt-inpython-modulebackend. See native-library configuration.
Because the two interpreters are separate:
- Do not create a Python 3.7 virtualenv and expect
import FreeCADto work in it. The wrapper runs fine on 3.7, but FreeCAD's modules exist only inside FreeCAD's own Python, which is 3.10 or newer in every supported release. - Installing the wheel into FreeCAD's interpreter is neither required nor
supported; the wrapper drives the host by launching
FreeCADCmdwith the packaged driver. dcc-mcp-freecad doctor --jsonreports the host interpreter aschecks.runtime.python_version, next tochecks.runtime.freecad_version. See install.md for how to read and cross-check both.
FreeCAD compatibility matrix
Supported host versions are declared in
compat_matrix.json — that file is the
contract, this section only points at it:
| FreeCAD | Status |
|---|---|
| 1.0.x | supported |
| 1.1.x | supported |
| anything else | rejected with an explicit error code |
Both supported lines are exercised end-to-end on real FreeCAD in CI —
1.0.2 and 1.1.4, the two pinned AppImages in
.github/workflows/ci.yml — and both ship Python
3.11 as the host interpreter. A version outside the matrix is not silently
downgraded to "probably fine":
dcc-mcp-freecad doctor --json fails with an error_code
(freecad_host_version_unsupported, freecad_host_version_unverified,
freecad_host_version_unlisted, or freecad_host_version_unparsable), the
supported ranges, and the command that pins a supported one. The same matrix is
re-checked inside FreeCAD before any geometry work, so a skipped preflight does
not turn into a silent modelling bug.
Install
Install the published wheel, prove the standalone FreeCAD runtime, then start the service:
python -m pip install --upgrade dcc-mcp-freecad
dcc-mcp-freecad doctor --json
dcc-mcp-freecad verify --json
dcc-mcp-freecad
See install.md for Windows, macOS, and Linux discovery, stable doctor exits, configuration, wheel upgrades, uninstall, and troubleshooting. FreeCAD remains OS/package-manager owned; the adapter does not download or cache external binaries.
Configuration
| Variable | Purpose | Default |
|---|---|---|
DCC_MCP_FREECAD_EXECUTABLE |
Exact FreeCADCmd executable or install directory | PATH and standard locations |
DCC_MCP_FREECAD_ALLOWED_ROOTS |
os.pathsep-separated document/import/export roots |
server working directory |
DCC_MCP_FREECAD_MAX_DOCUMENT_BYTES |
Maximum FCStd input size | 2 GiB |
DCC_MCP_FREECAD_MAX_TIMEOUT_SECS |
Maximum per-call deadline | 1800 seconds |
DCC_MCP_FREECAD_PORT |
Fixed adapter port when direct addressing is required | OS-assigned |
The service is a standalone DCC-MCP instance with no GUI PID. Every operation launches a clean FreeCADCmd process in safe mode with a temporary user config.
Agent workflow
dcc-mcp-cli list
dcc-mcp-cli search --query "FreeCAD create boolean export STEP"
dcc-mcp-cli load-skill freecad-session --dcc-type freecad --instance-id <instance-short>
dcc-mcp-cli load-skill freecad-modeling --dcc-type freecad --instance-id <instance-short>
Typical sequence: create_document → add_primitive → transform_object →
boolean_operation → validate_document → export_geometry.
Safety contract
- Requested documents and geometry stay under configured allowed roots.
- Existing outputs require explicit
overwrite=true. - Every
save_copycall withoverwrite=false, plain or presentation, publishes exclusively: a sibling hard link where the output filesystem supports one, otherwise an exclusive create (O_CREAT|O_EXCL) plus copy on volumes without hard-link support (FAT/exFAT, some SMB/FUSE mounts). Both refuse a destination created during the native call; only the hard link is a single atomic inode commit. Publication fails if neither is available — retry withoverwrite=trueor publish to a filesystem with hard-link support. Explicit overwrite uses atomic replacement. - FCStd mutations happen on sibling staging copies and replace the original only after a successful, non-empty save.
- Failed mutations leave the original document byte-for-byte unchanged.
- Object names, dimensional fields, placements, formats, tessellation, result size, process output, and deadlines are bounded.
- Cancellation and timeouts terminate the owned FreeCADCmd process.
- Cascade removal is explicit and reports every removed dependent.
FreeCAD Python API reference: https://www.freecad.org/api/
Optional native-library backend
The default is still FreeCADCmd. A separately configured python-module backend runs the same typed driver in a fresh compatible interpreter and installed FreeCAD library, with isolated temporary user directories. It is opt-in and has no automatic fallback. See configuration and exact qualification.
Native presentation copies
save_copy accepts an optional bounded visible_objects list and a standard
view (isometric, front, top, right). With this explicit opt-in it uses
FreeCAD's installed GUI library to save view-provider visibility and an
orthographic camera. Selections must be top-level non-container objects;
Groups, LinkGroups, Parts, Bodies and their members are rejected before changing visibility because a
hidden parent can hide or override a child's local state. Other objects remain
editable but hidden. The original
file stays unchanged; presentation mode refuses replacing the source even when
overwrite is set. GUI-library availability is required; this is not a claim of
offscreen OpenGL rendering.
The isolated native process disables view animation before selecting the camera, verifies visibility, orthographic type and native quaternion orientation against the request, then saves and reopens its staging file. It verifies camera values (single-precision serialization tolerance of 1e-6), object names, links, topology counts, placement, volumes and analytic bounds (double precision tolerance 1e-10 relative, 1e-9 absolute). Analytic bounds explicitly exclude GUI triangulation caches. A cancellation check precedes final publication. No FCStd XML or binary data is rewritten outside native FreeCAD APIs. Native raster thumbnails are disabled in this isolated process because an offscreen host may lack an OpenGL context.
No-overwrite copy publication uses a sibling hard link to publish the complete
native file without replacing a destination created during the native call;
the output filesystem must support this operation. Where it does not, the same
exclusive publication falls back to an exclusive create plus copy, which keeps
the refusal but not the single atomic inode commit; a failure names hard links
and the overwrite=true escape hatch. Explicit overwrite continues to use
atomic replacement. These readbacks cover recorded geometry metrics,
not full BRep or mesh connectivity equivalence. Source qualification and the
supported-host GUI persistence gate are recorded in
presentation-copy validation.
Metadata
Release files for dcc-mcp-freecad 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dcc_mcp_freecad-0.6.0.tar.gz | 102.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dcc_mcp_freecad-0.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 160.3 kB
Release files / dcc_mcp_freecad-0.6.0.tar.gz
| Download URL | dcc_mcp_freecad-0.6.0.tar.gz |
|---|---|
| Size | 102.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e4d6fe1327ac0f2390ac4cf25392971aa316bb6c7799886b73780375db9125ca
|
|
BLAKE2b-256 checksum How to use checksums |
74103f62c70fff86103a140ea0015c0191aa88360948f80541c55cbd757049a4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / dcc_mcp_freecad-0.6.0-py3-none-any.whl
| Download URL | dcc_mcp_freecad-0.6.0-py3-none-any.whl |
|---|---|
| Size | 57.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
aa4bbeda490f94e855b2eccc1f655bd9fb7f9b0ac8b080aadc471da4537384cc
|
|
BLAKE2b-256 checksum How to use checksums |
1b129df7e607e6c15f41c680c692273c0478b1b960780d5f44327ccfcbd44fa1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency log