Skip to main content
Glama
maximedns5

freecad-mcp

by maximedns5
README.md
[![MseeP.ai Security Assessment Badge](https://mseep.net/pr/neka-nat-freecad-mcp-badge.png)](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

![demo](./assets/freecad_mcp4.gif)

### Design a toy car

![demo](./assets/make_toycar4.gif)

### Design a part from 2D drawing

#### Input 2D drawing

![input](./assets/b9-1.png)

#### Demo

![demo](./assets/from_2ddrawing.gif)

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.

![workbench_list](./assets/workbench_list.png)

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

![start_rpc_server](./assets/start_rpc_server.png)

### 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

A3.7/5.0

Scored across 36 tools

Disambiguation4/5

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.

Naming Consistency3/5

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.

Tool Count2/5

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.

Completeness3/5

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.

Maintenance

ActivitySlowing
ResponsivenessNo issues