Skip to main content
Glama
theosib

FreeCAD MCP Server

by theosib
README.md
# FreeCAD MCP Server

An [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server that bridges Claude with a live FreeCAD instance. It gives Claude deep access to FreeCAD's runtime state — document structure, object properties, shape topology, sketch constraint health, and more — enabling AI-assisted CAD work and FreeCAD development debugging.

## What It Does

Unlike simple script-execution MCP servers, this project provides **rich context extraction** that lets Claude genuinely understand what's happening inside FreeCAD:

| Tool | What It Returns |
|---|---|
| `list_documents` | All open documents with names, file paths, object counts |
| `get_document_graph` | Full feature tree — every object with TypeId, properties, dependency links, validity state |
| `inspect_object` | Complete property dump for a single object, with shape metadata |
| `analyze_shape` | Topological analysis — face classifications (Plane/Cylinder/Cone/...), edge details, bounding box, volume |
| `get_sketch_diagnostics` | Constraint health — DOF, conflicts, redundancies, every constraint and geometry element with coordinates |
| `tracked_recompute` | Recompute with before/after diff — new errors, resolved errors, persistent errors |
| `execute_script` | Run arbitrary Python inside FreeCAD (escape hatch for anything not covered above) |
| `get_screenshot` | Capture the 3D viewport as a base64 PNG |
| `reload_handlers` | Hot-reload handler code without restarting FreeCAD |

## Architecture

```
Claude (Code/Desktop)  ←stdio MCP→  Bridge Server  ←TCP:9876→  FreeCAD Addon
                                     (this project)              (inside FreeCAD)
```

The project has two components:

1. **FreeCAD addon** (`freecad_addon/`) — runs inside FreeCAD as a workbench. Starts a threaded TCP server that accepts JSON-RPC requests and executes them on FreeCAD's main thread via a QTimer-polled work queue.

2. **MCP bridge server** (`src/freecad_mcp_agent/`) — spawned by Claude via stdio. Connects to the addon over TCP and translates MCP tool calls into JSON-RPC requests.

## Installation

### 1. Install the MCP bridge

```bash
# Clone the repo
git clone https://github.com/theosib/FreeCAD-MCP-Server.git
cd FreeCAD-MCP-Server

# Create a venv and install
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
```

### 2. Install the FreeCAD addon

FreeCAD doesn't reliably follow symlinks on macOS, so we use a thin loader file.

**Find your FreeCAD Mod directory:**
- macOS: `~/Library/Application Support/FreeCAD/Mod/` (or `~/Library/Application Support/FreeCAD/v1-2/Mod/` for weekly builds)
- Linux: `~/.local/share/FreeCAD/Mod/`
- Windows: `%APPDATA%/FreeCAD/Mod/`

> Tip: Run `FreeCAD.getUserAppDataDir()` in FreeCAD's Python console to find the exact path.

**Create the loader:**

```bash
mkdir -p "<your-mod-dir>/FreeCADMCPAgent"
```

Create `<your-mod-dir>/FreeCADMCPAgent/InitGui.py` with:

```python
import sys
_ADDON_DIR = "/absolute/path/to/FreeCAD-MCP-Server/freecad_addon"
if _ADDON_DIR not in sys.path:
    sys.path.insert(0, _ADDON_DIR)
_project_init = _ADDON_DIR + "/InitGui.py"
_ns = dict(globals())
_ns["__file__"] = _project_init
with open(_project_init) as _f:
    exec(compile(_f.read(), _project_init, "exec"), _ns)
```

Replace `/absolute/path/to/FreeCAD-MCP-Server` with the actual path to your clone.

### 3. Configure Claude Code

Add a `.mcp.json` to your working directory (or FreeCAD source tree):

```json
{
  "mcpServers": {
    "freecad-debug": {
      "command": "/absolute/path/to/FreeCAD-MCP-Server/.venv/bin/freecad-mcp-agent",
      "env": {
        "FREECAD_MCP_HOST": "127.0.0.1",
        "FREECAD_MCP_PORT": "9876"
      }
    }
  }
}
```

## Usage

1. **Start FreeCAD.** The RPC server auto-starts on port 9876 (you'll see "MCP Debug Agent: RPC server auto-started" in FreeCAD's console). Set `FREECAD_MCP_NO_AUTOSTART=1` to disable auto-start.

2. **Launch Claude Code** in a directory with the `.mcp.json` config.

3. **Use the tools.** Claude can now inspect your FreeCAD model:

> "What objects are in the current document?"
>
> "The Pocket001 feature looks wrong — can you diagnose it?"
>
> "Is Sketch003 fully constrained? Are there any conflicts?"
>
> "Recompute the document and tell me what changed."

## Use Case: FreeCAD Development Debugging

This project was designed for debugging FreeCAD itself. When the `.mcp.json` is placed in a FreeCAD source tree, Claude Code gets simultaneous access to:

- **Source code** — C++ and Python files, git history, build system (via Claude Code's native file access)
- **Live runtime state** — object properties, shape topology, constraint solver state (via MCP tools)

This lets Claude correlate what the code *should* do with what the runtime *actually* produced. See [docs/freecad-fork-instructions.md](docs/freecad-fork-instructions.md) for detailed workflows and a TypeId-to-source-file mapping table.

## Environment Variables

| Variable | Default | Purpose |
|---|---|---|
| `FREECAD_MCP_HOST` | `127.0.0.1` | RPC server host |
| `FREECAD_MCP_PORT` | `9876` | RPC server port |
| `FREECAD_MCP_NO_AUTOSTART` | *(unset)* | Set to `1` to disable auto-start of the RPC server |

## Project Structure

```
FreeCAD-MCP-Server/
├── pyproject.toml                  # Python package config
├── src/freecad_mcp_agent/
│   ├── server.py                   # MCP server (stdio, all tool definitions)
│   └── bridge.py                   # TCP client connecting to FreeCAD addon
├── freecad_addon/
│   ├── InitGui.py                  # Workbench registration + auto-start
│   ├── mcp_commands.py             # Start/Stop commands, handler registration
│   ├── rpc_server.py               # Threaded TCP server + main-thread dispatch
│   ├── package.xml                 # FreeCAD addon metadata
│   └── handlers/
│       ├── document.py             # list_documents, get_document_graph
│       ├── inspection.py           # inspect_object, analyze_shape
│       ├── sketcher.py             # get_sketch_diagnostics
│       ├── recompute.py            # tracked_recompute
│       ├── execution.py            # execute_script
│       └── viewport.py             # get_screenshot
└── docs/
    └── freecad-fork-instructions.md
```

## License

LGPL-2.1-or-later (same as FreeCAD)

TDQS

A4.1/5.0

Scored across 9 tools

Disambiguation4/5

The tools are largely distinct: document listing, feature-tree inspection, single-object property dumps, shape analysis, sketch diagnostics, recompute tracking, scripting, and screenshots all have clear purposes. Minor overlap exists between inspect_object and analyze_shape, but the descriptions separate basic shape metadata from detailed topological analysis.

Naming Consistency4/5

Most tool names follow a clear verb_noun pattern: list_documents, get_document_graph, inspect_object, analyze_shape, execute_script, get_screenshot, reload_handlers. The one notable deviation is tracked_recompute, which reads as an adjective-noun phrase rather than an imperative verb_noun name.

Tool Count5/5

Nine tools is a well-scoped set for a FreeCAD server. Each tool covers a meaningful capability, and there is no significant bloat or obvious redundancy in the overall surface.

Completeness3/5

The inspection/diagnostic side is thorough, covering documents, feature graphs, object properties, shape topology, sketch constraints, and recompute effects. However, there are no dedicated creation, modification, or deletion tools; execute_script is the only generic escape hatch for those operations, which is a notable first-class coverage gap for a general FreeCAD server.

Maintenance

ActivityInactive
ResponsivenessUnresponsive