freecad-mcp
[](https://mseep.ai/app/neka-nat-freecad-mcp)
# FreeCAD MCP
This repository is a FreeCAD MCP that allows you to control FreeCAD from Claude Desktop.
## Demo
### Design a flange

### Design a toy car

### Design a part from 2D drawing
#### Input 2D drawing

#### Demo

This is the conversation history.
https://claude.ai/share/7b48fd60-68ba-46fb-bb21-2fbb17399b48
## Install addon
FreeCAD Addon directory is
* Windows: `%APPDATA%\FreeCAD\Mod\`
* Mac:
* FreeCAD 1.1: `~/Library/Application\ Support/FreeCAD/v1-1/Mod/`
* FreeCAD 1.0: `~/Library/Application\ Support/FreeCAD/v1-0/Mod/`
* Linux:
* Ubuntu: `~/.FreeCAD/Mod/` or `~/snap/freecad/common/Mod/` (if you install FreeCAD from snap)
* Debian: `~/.local/share/FreeCAD/Mod`
* Arch / CachyOS (FreeCAD 1.1 from `extra/freecad`): `~/.local/share/FreeCAD/v1-1/Mod/`
Please put `addon/FreeCADMCP` directory to the addon directory.
```bash
git clone https://github.com/neka-nat/freecad-mcp.git
cd freecad-mcp
# For Linux (Ubuntu/Debian)
cp -r addon/FreeCADMCP ~/.FreeCAD/Mod/
# For Linux (Arch/CachyOS, FreeCAD 1.1 from extra/freecad)
mkdir -p ~/.local/share/FreeCAD/v1-1/Mod/
cp -r addon/FreeCADMCP ~/.local/share/FreeCAD/v1-1/Mod/
# For macOS (FreeCAD 1.1)
cp -r addon/FreeCADMCP ~/Library/Application\ Support/FreeCAD/v1-1/Mod/
```
When you install addon, you need to restart FreeCAD.
You can select "MCP Addon" from Workbench list and use it.

And you can start RPC server by "Start RPC Server" command in "FreeCAD MCP" toolbar.

### Auto-Start RPC Server
By default, the RPC server must be started manually each time FreeCAD opens. To start it automatically:
1. Open the **FreeCAD MCP** menu (switch to the MCP Addon workbench first)
2. Check **Auto-Start Server**
The setting is saved to `freecad_mcp_settings.json` and persists across sessions. On the next FreeCAD launch, the RPC server will start automatically once the application finishes loading.
You can disable it at any time by unchecking **Auto-Start Server** in the same menu.
## Setting up Claude Desktop
Pre-installation of the [uvx](https://docs.astral.sh/uv/guides/tools/) is required.
And you need to edit Claude Desktop config file, `claude_desktop_config.json`.
For user.
```json
{
"mcpServers": {
"freecad": {
"command": "uvx",
"args": [
"freecad-mcp"
]
}
}
}
```
If you want to save token, you can set `only_text_feedback` to `true` and use only text feedback.
```json
{
"mcpServers": {
"freecad": {
"command": "uvx",
"args": [
"freecad-mcp",
"--only-text-feedback"
]
}
}
}
```
For developer.
First, you need clone this repository.
```bash
git clone https://github.com/neka-nat/freecad-mcp.git
```
```json
{
"mcpServers": {
"freecad": {
"command": "uv",
"args": [
"--directory",
"/path/to/freecad-mcp/",
"run",
"freecad-mcp"
]
}
}
}
```
## Remote Connections
By default the RPC server does not accept remote connections and listens on `localhost`. To control FreeCAD from another machine on your network:
### 1. Enable remote connections in FreeCAD
In the **FreeCAD MCP** toolbar:
1. Check **Remote Connections** — the RPC server will bind to `0.0.0.0` (all interfaces) on the next restart. For security reasons, it only accepts connections from the IP addresses or CIDR subnets specified in the **Allowed IPs** field. By default this is `127.0.0.1`.
2. Click **Configure Allowed IPs** and enter a comma-separated list of IP addresses or CIDR subnets that are allowed to connect, e.g.:
```
192.168.1.100, 10.0.0.0/24
```
`127.0.0.1` is always the default. Invalid entries are rejected with an error dialog. Restart the RPC server after changing these settings.
### 2. Point the MCP server at the remote host
Pass the `--host` flag with the IP address or hostname of the machine running FreeCAD:
```json
{
"mcpServers": {
"freecad": {
"command": "uvx",
"args": [
"freecad-mcp",
"--host", "192.168.1.100"
]
}
}
}
```
The `--host` value is validated on startup — it must be a valid IPv4/IPv6 address or hostname.
## Tools
* `create_document`: Create a new document in FreeCAD.
* `create_object`: Create a new object in FreeCAD.
* `edit_object`: Edit an object in FreeCAD.
* `delete_object`: Delete an object in FreeCAD.
* `execute_code`: Execute arbitrary Python code in FreeCAD. See [Security model](#security-model) below.
* `insert_part_from_library`: Insert a part from the [parts library](https://github.com/FreeCAD/FreeCAD-library).
* `get_view`: Get a screenshot of the active view.
* `get_objects`: Get all objects in a document.
* `get_object`: Get an object in a document.
* `get_parts_list`: Get the list of parts in the [parts library](https://github.com/FreeCAD/FreeCAD-library).
* `run_fem_analysis`: Run the CalculiX solver on an existing `Fem::FemAnalysis` and return summary results (max von Mises stress, max displacement, node count, working directory). Auto-creates a `SolverCcxTools` if the analysis has none. See [`examples/cantilever_fem.py`](examples/cantilever_fem.py) for an end-to-end usage example.
### Verified geometry tools
Every tool above reports "success" once the underlying FreeCAD call didn't
raise — which a CAD kernel will do for a lot of operations that don't
actually accomplish anything (a pocket cut over empty space, a pattern with
an axis reference that silently resolves to nothing, a placement that gets
reverted by its owning body on the next recompute). The tools below instead
report measured geometry (volume, bounding box, `isValid`) so a caller can
tell the difference between "the call succeeded" and "the call did what I
wanted":
* `measure`: Volume, area, bounding box, `isValid`, and face/edge/vertex counts for any object.
* `probe_material_at`: Checks whether solid material actually exists inside a given box — "is there a floor/wall here?"
* `place`: Positions an object by its real bounding-box corner (not a derived offset), and automatically moves the owning `PartDesign::Body` when needed, since a feature's own `Placement` is silently reverted by its Body otherwise.
* `create_sketch`, `add_rectangle`, `add_circle`, `add_polygon`: Build sketches that are fully constrained as they're drawn (no separate dimensioning step, and no "closed but unpinned" loops that PartDesign refuses to pad).
* `pad`, `pocket`: Extrude/cut a sketch, reporting `volumeBefore`/`volume`/`isValid`. `pocket` fails loudly if no material was removed. Through-holes always cut from the midplane so they penetrate regardless of which side the material is on.
* `linear_pattern`, `polar_pattern`: Repeat features along/around a sketch axis, resolving the axis reference correctly so a pattern doesn't silently pattern nothing.
* `fillet`, `chamfer`: Round/bevel a solid feature's edges; reject a sketch as the base outright (with an explanation) instead of poisoning the feature tree.
* `measure_gap`: Measures the real gap between two parts along one axis, so a spanning part (e.g. a shelf between two supports) can be sized from measured geometry instead of a number derived independently of where those parts actually ended up.
* `instantiate_family`: Builds a parametric part from a small library of part-family templates (`l_bracket`, `flanged_disc`, `box_enclosure`) instead of a manual op sequence.
* `apply_material`: Maps a material name (steel, oak, glass, ...) to concrete ShapeColor/Transparency/Shininess values from a small deterministic table, applies them, and reports what was actually read back off the object's ViewObject afterward — instead of leaving a part default-gray or trusting an unverified assignment. Falls back to setting ShapeColor/Transparency through `edit_object` on an addon older than this tool.
* `get_views`: Captures Isometric/Front/Top/Right (plus an optional object-centred fifth) of a document in one call, each image labeled, alongside a per-object bounding-box summary that's measured from the real shapes rather than derived. Prefer this over `get_view` when you need to understand or verify a whole document/assembly's structure; prefer `get_view` for one specific angle or a quick re-check.
## Strategy prompt
The server ships an `asset_creation_strategy` MCP prompt that tells the client model which tools to prefer and in what order. It now includes a clarification policy: state an assumption and keep going for cheap-to-change choices like dimensions, materials, and colors; ask before building only when the ambiguity is structural (component count, topology, what the thing is for); batch any remaining questions into a single turn instead of drip-feeding them; and reach for `find_similar_builds` or `get_views` before reaching for a question.
## Security model
* **`execute_code`/`execute_code_async` run unsandboxed Python** on the machine hosting FreeCAD — `exec(code, globals())` with no import allowlist, AST restrictions, or resource limits. Anything reachable from this tool (`import os; os.system(...)`, `subprocess`, arbitrary file access) is reachable by anyone who can call it. This is a deliberate design choice, not an oversight, but it means **connecting to the RPC port is equivalent to full shell access to that machine** — treat network exposure accordingly (see [Remote Connections](#remote-connections) below). The MCP server blocks a denylist of known-dangerous patterns (`import os`, `import subprocess`, `subprocess.`, `os.system(`, `eval(`, `exec(`, `open(`, `__import__`) plus three Sketcher calls observed to hang FreeCAD's solver indefinitely on an already-constrained sketch (`.solve(`, `deleteAllGeometry(`, `movePoint(`) before running code — this raises the bar against accidental misuse, it is **not** a security sandbox against an adversarial caller.
* **`execute_code`'s Python namespace is shared and persists** across every `execute_code`/`execute_code_async` call for the life of the FreeCAD process (it is the `rpc_server` module's own `globals()`, not a fresh namespace per call). This is what lets `execute_code_async` stash a result in a module-level variable for a later `execute_code` call to read — but it also means a variable, import, or class defined by one call remains visible (and can collide) in every later, unrelated call, with no reset short of restarting FreeCAD or the RPC server.
* **`edit_object`'s property assignment is partial, not atomic.** If several properties are passed and one fails to apply, the properties that *did* succeed remain applied on the object — only the failure is reported. Always re-check with `get_object`/`measure` after an edit rather than assuming all-or-nothing semantics.
* **The only network access control is an IP allowlist** (see [Remote Connections](#remote-connections)) — there is no authentication token and no TLS. It stops connections from unlisted addresses; it does not stop a request that is merely spoofed or already inside the same trusted network.
## Contributors
<a href="https://github.com/neka-nat/freecad-mcp/graphs/contributors">
<img src="https://contrib.rocks/image?repo=neka-nat/freecad-mcp" />
</a>
Made with [contrib.rocks](https://contrib.rocks).
TDQS
Scored across 36 tools
Most tools have clearly distinct purposes, aided by detailed descriptions. However, 'fillet' vs 'fillet_edges' and 'execute_code' vs 'execute_code_async' are close pairs that could cause misselection, as the names don't immediately convey their different scopes.
The tool names mix patterns: verb_noun (create_object, list_documents), bare verbs (pad, pocket, loft), and noun_noun (linear_pattern, measure_gap). While each name is readable and mostly intuitive, the lack of a consistent convention makes the set feel less predictable.
With 36 tools, the surface is large and exceeds the 25+ threshold that typically signals bloat. Several tools overlap in purpose (fillet/fillet_edges, measure/measure_gap, execute_code/execute_code_async), inflating the count without adding distinct value, though the complexity of CAD does justify a larger set.
The server covers a broad range of CAD workflows—sketching, padding, pocketing, patterning, booleans, fillets, lofts, sweeps, part families, measurement/verification, and FEM. However, common operations like revolve, mirror/shell, and document lifecycle management (e.g., close/delete document) are missing, leaving notable gaps for a full-featured CAD tool.