Create a new document in FreeCAD.
Args:
name: The name of the document to create.
Returns:
A message indicating the success or failure of the document creation.
Examples:
If you want to create a document named "MyDocument", you can use the following data.
```json
{
"name": "MyDocument"
}
```
Create a new object in FreeCAD.
``obj_type`` must name a type registered in FreeCAD's C++ type system, such
as "Part::", "PartDesign::" or "Fem::" types. A number of FreeCAD features
are implemented in Python rather than C++ and so are not registered types;
of those, these are supported here through dedicated factories, and each
requires the properties listed beside it:
Part::Tube InnerRadius, OuterRadius, Height
Draft::Circle Radius
Draft::Rectangle Length, Height
Draft::Polygon FacesNumber, Radius
Draft::Wire Points (list of {x, y, z}), optional Closed
Any other Python-implemented type (Draft::Point, Draft::Ellipse, ...) must
be built with ``execute_code`` instead.
Note that the Draft factories name objects themselves, so for those the
returned object_name will differ from the requested obj_name, which is
applied to the object's Label instead. Always use the returned name in
later get_object/edit_object calls.
Args:
doc_name: The name of the document to create the object in.
obj_type: The type of the object to create (e.g. 'Part::Box', 'Part::Cylinder', 'Part::Cut', 'PartDesign::Body', etc.).
obj_name: The name of the object to create.
obj_properties: The properties of the object to create.
include_screenshot: Whether to return a screenshot of the model (default True).
Set to False to save tokens when visual feedback is not needed,
e.g. for intermediate steps in a longer sequence of changes.
view_name: The view orientation of the returned screenshot (default "Isometric").
Pick the view that best shows the change being made.
Returns:
A message indicating the success or failure of the object creation and a screenshot of the object.
Examples:
If you want to create a cylinder with a height of 30 and a radius of 10, you can use the following data.
```json
{
"doc_name": "MyCylinder",
"obj_name": "Cylinder",
"obj_type": "Part::Cylinder",
"obj_properties": {
"Height": 30,
"Radius": 10,
"Placement": {
"Base": {
"x": 10,
"y": 10,
"z": 0
},
"Rotation": {
"Axis": {
"x": 0,
"y": 0,
"z": 1
},
"Angle": 45
}
},
"ViewObject": {
"ShapeColor": [0.5, 0.5, 0.5, 1.0]
}
}
}
```
If you want to cut one solid out of another, create both solids first,
then reference them by name as 'Base' and 'Tool'.
```json
{
"doc_name": "MyPart",
"obj_name": "Cut",
"obj_type": "Part::Cut",
"obj_properties": {
"Base": "Box",
"Tool": "Cylinder"
}
}
```
If you want to create a pipe with an outer diameter of 250, a 10 wall
and a length of 500, you can use the following data.
```json
{
"doc_name": "MyPipe",
"obj_name": "Pipe",
"obj_type": "Part::Tube",
"obj_properties": {
"OuterRadius": 125,
"InnerRadius": 115,
"Height": 500
}
}
```
If you want to create a FEM analysis, you can use the following data.
```json
{
"doc_name": "MyFEMAnalysis",
"obj_name": "FemAnalysis",
"obj_type": "Fem::AnalysisPython",
}
```
If you want to create a FEM constraint, you can use the followi…
Edit an object in FreeCAD.
This tool is used when the `create_object` tool cannot handle the object creation.
Args:
doc_name: The name of the document to edit the object in.
obj_name: The name of the object to edit.
obj_properties: The properties of the object to edit.
include_screenshot: Whether to return a screenshot of the model (default True).
Set to False to save tokens when visual feedback is not needed,
e.g. for intermediate steps in a longer sequence of changes.
view_name: The view orientation of the returned screenshot (default "Isometric").
Pick the view that best shows the change being made.
Returns:
A message indicating the success or failure of the object editing and a screenshot of the object.
Delete an object in FreeCAD.
Args:
doc_name: The name of the document to delete the object from.
obj_name: The name of the object to delete.
include_screenshot: Whether to return a screenshot of the model (default True).
Set to False to save tokens when visual feedback is not needed,
e.g. for intermediate steps in a longer sequence of changes.
view_name: The view orientation of the returned screenshot (default "Isometric").
Pick the view that best shows the change being made.
Returns:
A message indicating the success or failure of the object deletion and a screenshot of the object.
Execute Python code in FreeCAD without waiting for completion.
Use this ONLY for long-running background computations that do NOT touch the
FreeCAD GUI or mutate the FreeCAD document tree directly.
This tool runs the submitted code in a background thread and returns
immediately. Because it does not run on FreeCAD's main GUI thread, the code
must NOT directly call FreeCADGui APIs, manipulate the active view or
selection, create or edit document objects, change object properties, call
doc.recompute(), or save documents. FreeCAD documents and the Coin3D
scenegraph are not thread-safe: writing to them from this thread races the
GUI thread and can wedge FreeCAD's event loop, after which the RPC server
stops responding entirely and FreeCAD must be restarted.
Every document or view write must instead be handed to the GUI thread through
the injected commit() helper:
commit(fn, timeout=120) -> fn's return value
Scripts share a live namespace. Saved functions can use commit() in later
async calls; calling it from execute_code or a GUI callback raises immediately.
Coordinate concurrent scripts that intentionally modify the same variables.
commit() queues fn on the GUI thread, waits for it, and raises RuntimeError if
dispatch fails or times out. Example:
fused = base.fuse(addition).removeSplitter() # slow, safe in background
def apply(): # runs on the GUI thread
obj.Shape = fused
doc.recompute()
commit(apply)
For code that is not dominated by heavy geometry computation, use execute_code
instead. execute_code runs entirely on the FreeCAD GUI thread and is the safe
default for normal FreeCAD automation.
Use execute_code_async only when the heavy part is long-running OCCT geometry
(e.g. fuse/cut/loft on already-fetched shapes) or other CPU-bound computation
that would exceed execute_code's 90 s GUI-thread budget.
Typical usage pattern:
1. Fetch shapes into module-level variables first (via execute_code).
2. Run the heavy computation via execute_code_async.
3. Apply the result inside commit(), or store it in a module-level Python
variable (not in the FreeCAD document) for a later execute_code call.
Performance note: boolean operations against shapes with many faces (e.g. a
ribbed lid) are expensive. Fuse the additions together first, then apply a
single boolean against the heavy shape, and avoid doc.recompute() unless the
dependency graph really needs it.
Args:
code: Background-safe Python code to execute. Use commit(fn) for all
document and view writes.
Returns:
A message with the job_id of the started background execution.
Run a FreeCAD Python script in a separate headless `freecadcmd` process.
Use this for OCCT work that can crash or block FreeCAD: helical threads
(makeHelix + makePipeShell), lofts and sweeps, booleans with many or
B-spline tools, long parametric rebuilds. A native OpenCascade crash
here only kills the helper process; the GUI and its open documents
survive, and the tool reports the crash signal and the script's output.
The script runs on the MCP server machine, independently of --host, in a
fresh process without GUI: import FreeCAD/Part
yourself, open documents from disk (FreeCAD.openDocument(path)), save
results with doc.save()/saveAs() or Shape.exportBrep(). Nothing from the
execute_code namespace is available. Print progress to stdout; it is
returned when the process ends. After the script saved a .FCStd that is
open in the GUI, call reload_document(doc_name) to show the result.
Args:
code: Complete Python script for freecadcmd.
timeout: Positive finite seconds to wait before killing the process
(default 600). Partial output is preserved on timeout.
Returns:
Exit status, crash/timeout diagnosis and the script's printed output.
Report the state of background jobs started by execute_code_async.
Does not use the FreeCAD GUI thread, so it answers even while a job runs.
Args:
job_id: The id returned by execute_code_async. Empty lists all running
jobs and up to 20 recently completed jobs.
Returns:
For one job: its state (running/done/failed), the error and traceback
when it failed. History is held in memory until FreeCAD exits.
Execute arbitrary Python code in FreeCAD.
Args:
code: The Python code to execute.
include_screenshot: Whether to return a screenshot of the model (default True).
Set to False to save tokens when the code does not change the model's
appearance, e.g. analytical or computational scripts whose result is
printed output, or intermediate steps in a longer sequence of changes.
view_name: The view orientation of the returned screenshot (default "Isometric").
Pick the view that best shows the change being made.
timeout: Positive finite seconds for each of the queue and GUI execution
budgets, overriding the 90 s default for this call (capped at 1800).
Raise it for slow work that must
run on the GUI thread, such as importing or exporting a large STEP
assembly. Without it the call reports a timeout while the task keeps
running, and the result is lost even though the work finishes. Prefer
execute_code_async for heavy pure-geometry work that touches neither
the document nor the GUI.
Returns:
A message indicating the success or failure of the code execution, the output of the code execution, and a screenshot of the object.
Get a screenshot of the active view.
Args:
view_name: The name of the view to get the screenshot of.
The following views are available:
- "Isometric"
- "Front"
- "Top"
- "Right"
- "Back"
- "Left"
- "Bottom"
- "Dimetric"
- "Trimetric"
width: The width of the screenshot in pixels. If not specified, uses the viewport width.
height: The height of the screenshot in pixels. If not specified, uses the viewport height.
focus_object: The name of the object to focus on. If not specified, fits all objects in the view.
Returns:
A screenshot of the active view.
Insert a part from the parts library addon.
Args:
relative_path: The relative path of the part to insert.
include_screenshot: Whether to return a screenshot of the model (default True).
Set to False to save tokens when visual feedback is not needed,
e.g. for intermediate steps in a longer sequence of changes.
view_name: The view orientation of the returned screenshot (default "Isometric").
Pick the view that best shows the change being made.
Returns:
A message indicating the success or failure of the part insertion and a screenshot of the object.
Get all objects in a document.
You can use this tool to get the objects in a document to see what you can check or edit.
Args:
doc_name: The name of the document to get the objects from.
include_screenshot: Whether to return a screenshot of the document (default True).
Set to False to save tokens when only the object data is needed.
view_name: The view orientation of the returned screenshot (default "Isometric").
Returns:
A list of objects in the document and a screenshot of the document.
Get an object from a document.
You can use this tool to get the properties of an object to see what you can check or edit.
Args:
doc_name: The name of the document to get the object from.
obj_name: The name of the object to get.
include_screenshot: Whether to return a screenshot of the document (default True).
Set to False to save tokens when only the object data is needed.
view_name: The view orientation of the returned screenshot (default "Isometric").
Returns:
The object and a screenshot of the object.
Get the list of parts in the parts library addon.
Close and re-open a document to pick up external file changes.
Use this AFTER the document's .FCStd file has been modified by
something outside of FreeCAD's GUI process — for example, a
headless `freecadcmd` script that edited and saved the file. The
open GUI document is otherwise unaware of on-disk changes; this
tool closes the stale in-memory copy and reopens the file from
disk so the GUI shows current geometry.
Args:
doc_name: The name of the open document to reload. Must match
the name shown by ``list_documents``.
Returns:
A message confirming the document was reloaded, or describing
the failure (document not loaded, no associated file, etc).
FreeCAD names the reopened document after the file stem, which
can differ from ``doc_name`` ("HandleConcept3D" saved as
handle-concept-3d.FCStd reopens as handle_concept_3d); the reply
names the document you should use from then on.
Examples:
```json
{
"doc_name": "chassis"
}
```
Get the list of open documents in FreeCAD.
Returns:
A list of document names.
Get RPC and FreeCAD GUI-dispatch health.
This tool does not use FreeCAD's GUI thread, so it remains available after
a GUI operation times out. A ``stuck`` state identifies the operation that
is still running and indicates that FreeCAD may need to be restarted.
``version_check`` is "ok" or says whether the addon or the server needs
updating.
Run the CalculiX solver on an existing Fem::FemAnalysis container and return summary results.
Prerequisites in the document:
- A Part-derived solid (e.g. Part::Box, PartDesign::Body) acting as the geometry.
- A Fem::AnalysisPython container created via `create_object`.
- A Fem::MaterialCommon assigned to the geometry, added to the analysis.
- A Fem::FemMeshGmsh referencing the geometry, added to the analysis (the
mesh is generated automatically when created via `create_object`).
- At least one Fem::ConstraintFixed and one Fem::ConstraintForce (or
ConstraintPressure) bound to faces of the geometry, added to the analysis.
A SolverCcxTools is auto-created if the analysis has none.
The solver runs synchronously on the FreeCAD GUI thread and blocks all
other RPC calls for its duration; do not fan out parallel requests.
Returns max von Mises stress (MPa), max/min displacement (mm), node count,
and the working directory CalculiX wrote to. On failure, returns the
prerequisite-check or solver error along with the working directory for
triage.
Args:
doc_name: Name of the FreeCAD document.
analysis_name: Name of the Fem::AnalysisPython object.
timeout: Seconds to wait for the solver (default 600).
include_screenshot: Whether to return a screenshot of the model (default True).
Set to False to save tokens when only the numeric results are needed.
view_name: The view orientation of the returned screenshot (default "Isometric").
概览
What is FreeCAD MCP?
FreeCAD MCP is a Model Context Protocol (MCP) server that enables you to control FreeCAD, the open-source parametric 3D CAD modeler, directly from Claude Desktop. It is designed for users who want to automate CAD design tasks, generate parts from descriptions or drawings, or integrate FreeCAD with AI-based workflows.
How to use FreeCAD MCP?
Install the FreeCAD MCP addon by copying the addon/FreeCADMCP directory to your FreeCAD Mod folder (paths differ by OS). Then restart FreeCAD, switch to the “MCP Addon” workbench, and click “Start RPC Server” in the toolbar. Configure Claude Desktop by editing claude_desktop_config.json to use uvx freecad-mcp as the MCP server command. Optionally enable auto-start of the RPC server via the FreeCAD MCP menu, or set up remote connections with --host and allowed IPs.
Key features of FreeCAD MCP
Create, edit, and delete FreeCAD objects via natural language
Execute arbitrary Python code in FreeCAD’s environment
Insert parts from the FreeCAD parts library
Capture screenshots of the active 3D view
Run CalculiX FEM analysis and retrieve summary results
Support for remote connections over a network
Auto-start RPC server on FreeCAD launch
Use cases of FreeCAD MCP
Design mechanical parts (e.g., a flange or toy car) from user descriptions
Generate 3D models from 2D technical drawings
Automate repetitive CAD operations with AI-driven prompts
Perform finite element analysis (FEM) on models and inspect results
Manage multiple documents and objects in FreeCAD remotely via Claude
常见问题
1
What tools are available in FreeCAD MCP?
The server provides 11 tools: `create_document`, `create_object`, `edit_object`, `delete_object`, `execute_code`, `insert_part_from_library`, `get_view`, `get_objects`, `get_object`, `get_parts_list`, and `run_fem_analysis`.
2
How do I enable remote connections to FreeCAD MCP?
In the FreeCAD MCP toolbar, check **Remote Connections** to bind to `0.0.0.0`. Then use **Configure Allowed IPs** to specify comma-separated IP addresses or CIDR subnets. On the Claude Desktop side, pass the `--host` flag with the FreeCAD machine’s IP address or hostname.
3
How can I make the RPC server start automatically?
Switch to the MCP Addon workbench, open the FreeCAD MCP menu, and check **Auto-Start Server**. The setting is saved to `freecad_mcp_settings.json` and persists across sessions.
4
Is a Python environment required to run FreeCAD MCP?
Yes. Pre-installation of `uvx` (from the Astral uv tool) is required for the Claude Desktop configuration.
5
Can I receive only text feedback without image data?
Yes. Add the `--only-text-feedback` flag in the `claude_desktop_config.json` args to disable image-based feedback and use only textual responses.
评论