The Problem
Claude Desktop users who need to drive FreeCAD geometry require a bridge that translates natural‑language or tool‑call prompts into FreeCAD’s RPC interface. This repo provides that bridge, but the codebase has several structural weaknesses that make it hard to extend or trust in production.
What This Does
The repository implements a FreeCAD MCP server that exposes FreeCAD operations (create document, create object, edit, delete, FEM execution, etc.) as MCP tools consumable by Claude. Key files and their responsibilities (from the responsibility map) are:
| File | Functions / Classes | Calls into | Reads/writes files |
|---|---|---|---|
addon/FreeCADMCP/rpc_server/rpc_server.py | 33 f, 1 c | 10 | Yes |
src/freecad_mcp/freecad_client.py | 20 f, 2 c | 3 | No |
src/freecad_mcp/operations/core.py | 15 f | 4 | No |
src/freecad_mcp/server.py | 19 f | 3 | No |
addon/FreeCADMCP/rpc_server/gui_dispatch.py | 10 f, 1 c | 3 | No |
addon/FreeCADMCP/rpc_server/commands.py | 18 f, 5 c | 1 | No |
addon/FreeCADMCP/rpc_server/property_mapper.py | 4 f, 1 c | 2 | No |
addon/FreeCADMCP/rpc_server/settings.py | 3 f | 3 | No |
addon/FreeCADMCP/rpc_server/ip_filter.py | 4 f, 1 c | 3 | No |
addon/FreeCADMCP/rpc_server/fem_executor.py | 1 f | 2 | No |
addon/FreeCADMCP/rpc_server/parts_library.py | 2 f | 2 | No |
addon/FreeCADMCP/rpc_server/serialize.py | – | – | – |
addon/FreeCADMCP/rpc_server/view_manager.py | – | – | – |
addon/FreeCADMCP/InitGui.py | 6 f, 1 c | 3 | No |
The entry point is main in src/freecad_mcp/server.py:524, which reaches 23 other functions and is called from a single place (the server lifespan handler). Controlling flows start there, then branch through create_document, create_object, edit_object, delete_object, and execute_code before hitting the filesystem (e.g., os.remove via get_active_screenshot).
The internal call graph shows get_freecad_connection invoked from 15 places, text_response from 14, and dispatch_to_gui from 11 – these are the hubs any change ripples through.
How It Is Wired
Execution follows a short path: main → execute_code → execute_code_operation → get_active_screenshot; the screenshot step triggers os.remove to clean up temporary images. All RPC commands (ping, create_document, create_object, etc.) are defined in addon/FreeCADMCP/rpc_server/rpc_server.py and registered via register_commands in InitGui.py. The freecad_client module (src/freecad_mcp/freecad_client.py) manages the TCP‑like connection; load_settings/save_settings in settings.py persist configuration to freecad_mcp_settings.json. Remote connections are toggled through the UI (Configure Allowed IPs) which ultimately sets the IP filter in ip_filter.py.
How To Use It
Setup
# Clone the repository (use the exact URL)
git clone https://github.com/moses-y/freecad-mcp.git
cd freecad-mcp
# Install the addon into FreeCAD’s Mod directory (example for Linux Ubuntu)
cp -r addon/FreeCADMCP ~/.FreeCAD/Mod/
# Restart FreeCAD, select “MCP Addon” from the Workbench list,
# then click “Start RPC Server” (or enable “Auto‑Start Server”).
# Configure Claude Desktop
# Edit ~/.config/claude/claude_desktop_config.json
{
"mcpServers": {
"freecad": {
"command": "uvx",
"args": ["freecad-mcp"]
}
}
}
# Optional: add "--only-text-feedback" to the args if text‑only feedback is desired.
Running it
- In FreeCAD: switch to the MCP Addon workbench, click Start RPC Server.
- In Claude: invoke any MCP tool (e.g.,
create_document,create_object) and the server will translate the call into the corresponding FreeCAD operation.
Real‑World Use
A designer can ask Claude: “Create a 30 mm cube, fillet the top edge 5 mm, and export a STEP file.” Claude translates this into the MCP calls create_object (cube), edit_object (fillet), then execute_code (STEP export). The server runs the operations inside FreeCAD, returns a screenshot (or text if --only-text-feedback is set), and the designer iterates without leaving the chat.
Code Health & Issues
Measured static‑analysis findings (deterministic, from the pipeline):
- [HIGH/cognitive_load] Deep nesting x4 – files
addon/FreeCADMCP/rpc_server/property_mapper.py,addon/FreeCADMCP/rpc_server/gui_dispatch.py,examples/langchain/react.py. Max indentation depth 8 makes control flow hard to follow. - [MEDIUM/clarity] Duplicated code blocks – 11 repeated 6‑line segments across
addon/FreeCADMCP/rpc_server/object_factory.py,addon/FreeCADMCP/rpc_server/rpc_server.py,src/freecad_mcp/freecad_client.py,src/freecad_mcp/operations/__init__.py. - [MEDIUM/resilience] Broad exception handling x7 –
addon/FreeCADMCP/rpc_server/commands.py,addon/FreeCADMCP/rpc_server/fem_executor.py,addon/FreeCADMCP/rpc_server/gui_dispatch.py. Bareexceptclauses swallow errors indiscriminately.
SDLC / repository‑level observations (from the code‑health audit):
- [HIGH] Add a test suite – 22 source files, no test files exist. Any change ships with no signal that existing behaviour holds.
- [HIGH] Add a CI workflow – no
.github/CI configuration; every merge runs untested. - [HIGH] Remove the committed
.envand rotate its credentials –examples/adk/.envis tracked and loaded by the app, risking live key exposure. - [MEDIUM] Enable Dependabot or Renovate – one manifest present, no update bot configured.
- [MEDIUM] Add a pre‑commit secret gate – no hook scanning staged content; the same class of leak can recur.
The Bottom Line
This repo delivers a functional FreeCAD ↔ Claude bridge with a clear RPC surface and a small set of well‑defined entry points. However, the codebase suffers from deep nesting, duplicated logic, and bare exception handlers that raise maintenance risk. The absence of tests, CI, and a committed .env file means any production deployment must add those safeguards before relying on the integration for critical workflows. It is suitable for hobbyists and rapid prototyping, but teams needing stability should invest in the outlined test, CI, and secret‑management improvements.