Files
freecad-robust-mcp-fc111/docs/guide/connection-modes.md
T
8c338f6da7 feat: MCP Bridge Workbench, just command cleanup, testing, etc. (#24)
* fix: lots of fixes and name refactoring

* feat: Add workbench preferences

* fix: MCP bridge status widget and just command fixes

* fix(tests): Use the correct mesa-glx package

* fix(ci): Add fontconfig to GUI test dependencies

FreeCAD GUI was failing to start with:
"Fontconfig error: Cannot load default config file: No such file"

Added fontconfig and fonts-dejavu-core packages to the GUI test job
dependencies to resolve the font configuration issue.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(addon): Extract path utilities into shared module

Create path_utils.py module that consolidates duplicated path-finding
logic from commands.py and InitGui.py:
- get_addon_path(): Find addon directory with caching and fallbacks
- get_icon_path(): Get full path to an icon file
- get_icons_dir(): Get path to icons directory
- get_workbench_icon(): Get path to workbench main icon

This removes ~100 lines of duplicated code while preserving the same
behavior including _addon_path_cache and all fallback methods.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(addon): Prevent stale plugin state on startup failure

The StartMCPBridgeCommand.Activated method could leave _mcp_plugin in
a partially initialized state if FreecadMCPPlugin.start() failed after
the plugin was instantiated.

Changes:
- Create plugin in a local variable first
- Only assign to _mcp_plugin after start() succeeds
- Explicitly clear _mcp_plugin and _running_config in exception
  handlers to ensure clean state for subsequent retry attempts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Lot of broad improvements

* fix(ci): Use blocking headless_server.py for GUI tests

The GUI test was using startup_bridge.py which is non-blocking
(designed for interactive use). For CI, even in GUI mode, we need
the blocking headless_server.py that calls run_forever() to keep
FreeCAD running. GUI features are still available since we use
the 'freecad' executable instead of 'freecadcmd'.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(addon): Rename headless_server.py to blocking_bridge.py

The old name was misleading because:
- It works with both GUI (freecad) and headless (freecadcmd) modes
- The key characteristic is that it BLOCKS with run_forever()

New naming convention clarifies the difference:
- blocking_bridge.py: Starts bridge and blocks (for CI, servers)
- startup_bridge.py: Starts bridge and returns (for interactive GUI)

Updated all references across:
- GitHub workflow (macro-test.yaml)
- Just commands (freecad.just)
- Unit tests (test_addon_structure.py)
- Documentation (5 files)
- CLAUDE.md

Also improved the script to detect GUI mode dynamically using
FreeCAD.GuiUp and display the appropriate status message.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(just): Remove erroneous rm of startup_bridge.py on error

The startup script is now a permanent source file in the repository,
not a generated temporary file. The rm -f would have deleted source
code if FreeCAD wasn't found.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: General improvements

* fix: Lots of general fixes and only stable to PyPi

* fix: small cleanup

* fix: Small fixes and hopefully fixes the GUI tests

* fix: Add proper library paths for FreeCAD GUI in CI

- Create wrapper scripts instead of symlinks for AppImage binaries
- Set LD_LIBRARY_PATH, QT_PLUGIN_PATH for GUI mode
- Add diagnostic output to identify startup failures

* fix: Use apprun for GUI tests in CI

* fix: Improving Xvfb tests

* fix: GUI tests worlk

* chore: remove invalid --no-splash comments

* fix: ARM64 architecture support and other fixes

* fix: cleanup

* test: just commands test suite

* test: improve just command tests

* fix: more general improvements

* fix: more cleanup

* fix: more updates

* fix: small tweaks

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 15:26:33 -08:00

5.3 KiB

Connection Modes

The FreeCAD Robust MCP Server supports multiple ways to connect to FreeCAD. Choose the mode that best fits your workflow.


Overview

Mode Description Platform Best For
xmlrpc XML-RPC protocol (port 9875) All platforms Production use (recommended)
socket JSON-RPC over TCP sockets All platforms Alternative to XML-RPC
embedded FreeCAD imported into MCP process Linux only Fastest execution, CI/automation

XML-RPC mode is the default and recommended connection method. It works on all platforms and provides robust, reliable communication.

How It Works

MCP Client <--stdio--> Robust MCP Server <--XML-RPC:9875--> FreeCAD

The Robust MCP Server communicates with FreeCAD via XML-RPC protocol on port 9875.

Setup

  1. Start FreeCAD with the Robust MCP Bridge workbench
  2. Click Start Bridge (or it auto-starts if configured)
  3. Configure the Robust MCP Server:
export FREECAD_MODE=xmlrpc
export FREECAD_XMLRPC_PORT=9875  # default
freecad-mcp

Advantages

  • Works on all platforms (macOS, Linux, Windows)
  • Process isolation (FreeCAD crash doesn't affect Robust MCP Server)
  • Supports both GUI and headless FreeCAD

Socket Mode

Socket mode uses JSON-RPC over TCP sockets instead of XML-RPC.

How It Works

MCP Client <--stdio--> Robust MCP Server <--JSON-RPC:9876--> FreeCAD

Setup

export FREECAD_MODE=socket
export FREECAD_SOCKET_HOST=localhost
export FREECAD_SOCKET_PORT=9876
freecad-mcp

Advantages

  • JSON-based protocol (easier to debug)
  • Lower overhead than XML-RPC
  • Works on all platforms

Embedded Mode (Linux Only)

!!! danger "Platform Limitation" Embedded mode only works on Linux. On macOS and Windows, it causes crashes due to Python ABI incompatibility.

Embedded mode imports FreeCAD directly into the Robust MCP Server process, providing the fastest execution.

Why It Crashes on macOS/Windows

FreeCAD's FreeCAD.so library links to @rpath/libpython3.11.dylib (FreeCAD's bundled Python). When you try to import it from a different Python interpreter (even the same version), it causes a crash because the Python runtime state is incompatible.

Setup (Linux Only)

export FREECAD_MODE=embedded
export FREECAD_PATH=/usr/lib/freecad/lib  # Adjust for your system
freecad-mcp

Advantages

  • Fastest execution (no IPC overhead)
  • No need to start FreeCAD separately
  • Works in CI/CD environments on Linux

Limitations

  • Linux only - crashes on macOS and Windows
  • Headless only (no GUI features)
  • Minimal testing - embedded mode receives less testing than xmlrpc/socket modes
  • Cannot access FreeCAD GUI features (screenshots, colors, etc.)

Testing Status

Embedded mode is tested in the CI pipeline with unit tests that mock FreeCAD. However, full integration testing with actual FreeCAD is limited compared to the xmlrpc and socket modes which are tested with the FreeCAD AppImage.


Choosing a Mode

graph TD
    A[Need FreeCAD MCP?] --> B{Platform?}
    B -->|macOS/Windows| C[Use xmlrpc or socket]
    B -->|Linux| D{Need GUI features?}
    D -->|Yes| C
    D -->|No| E{Need fastest execution?}
    E -->|Yes| F[Consider embedded]
    E -->|No| C

Recommendations

Use Case Recommended Mode
General development xmlrpc
Interactive modeling with GUI xmlrpc
CI/CD pipelines on Linux embedded
Docker containers xmlrpc
Remote FreeCAD instance xmlrpc
Debugging connection issues socket

Headless vs GUI Mode

Independent of connection mode, FreeCAD itself can run in GUI or headless mode:

Feature Headless GUI
Object creation Yes Yes
Boolean operations Yes Yes
Export (STEP, STL, etc.) Yes Yes
Screenshots No Yes
Object colors/visibility No Yes
Camera control No Yes

Starting FreeCAD

GUI Mode:

# Using workbench - just start FreeCAD and click "Start Bridge"
just freecad::run-gui  # From source

Headless Mode:

FreeCADCmd /path/to/blocking_bridge.py
just freecad::run-headless  # From source

Troubleshooting

Connection Refused

Error: Connection refused on localhost:9875

Solution: Ensure FreeCAD is running with the Robust MCP Bridge started. Check the bridge status in FreeCAD's toolbar.

Embedded Mode Crash on macOS

SIGSEGV: Segmentation fault

Solution: Embedded mode doesn't work on macOS. Switch to xmlrpc or socket mode.

Timeout Errors

Error: Execution timed out after 30000ms

Solution: Increase the timeout with FREECAD_TIMEOUT_MS=60000 or optimize your operation.


Next Steps