Files
freecad-robust-mcp-fc111/docs/guide/macros.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

4.8 KiB

FreeCAD Macros

This project includes standalone FreeCAD macros that work independently of the MCP server, plus MCP tools for creating and managing macros programmatically.


Included Macros

CutObjectForMagnets

Cut an object along a plane and add aligned magnet holes with surface collision detection. Perfect for creating 3D printed parts that snap together with embedded magnets.

Features:

  • Interactive plane selection via GUI
  • Automatic magnet hole placement with configurable grid
  • Surface collision detection to avoid invalid hole positions
  • Configurable magnet dimensions and tolerances

Usage:

  1. Select an object in FreeCAD
  2. Run the macro
  3. Define the cutting plane interactively
  4. Configure magnet parameters
  5. The macro creates two halves with aligned magnet holes

See CutObjectForMagnets documentation for detailed usage.

MultiExport

Export selected bodies to multiple file formats simultaneously with configurable mesh options.

Supported Formats:

  • STL (ASCII and Binary)
  • STEP
  • 3MF
  • OBJ
  • IGES
  • BREP
  • PLY
  • AMF

Usage:

  1. Select one or more bodies/parts
  2. Run the macro
  3. Select output formats and configure mesh options
  4. Choose output directory
  5. All exports are created with consistent naming

See MultiExport documentation for detailed usage.


Installing Macros

Via FreeCAD Addon Manager

When you install the "FreeCAD MCP and More" addon, the macros are installed automatically.

Manual Installation

  1. Download macros from GitHub Releases
  2. Copy .FCMacro files to your macro directory:
    • Linux: ~/.local/share/FreeCAD/Macro/
    • macOS: ~/Library/Application Support/FreeCAD/Macro/
    • Windows: %APPDATA%\FreeCAD\Macro\

MCP Macro Tools

The MCP server provides tools for working with macros programmatically:

list_macros

List available macros in FreeCAD's macro directories.

list_macros() -> list[dict]

Returns: List of macros with name, path, description, and whether it's a system macro.

run_macro

Execute a macro by name with optional arguments.

run_macro(
    macro_name: str,
    args: dict | None = None
) -> dict

Example prompt:

"Run the MultiExport macro"

create_macro

Create a new macro programmatically.

create_macro(
    name: str,
    code: str,
    description: str = ""
) -> dict

Example prompt:

"Create a macro called 'CreateBox' that makes a 10x10x10 box"

read_macro

Read the source code of an existing macro.

read_macro(macro_name: str) -> dict

Example prompt:

"Show me the code for the MultiExport macro"

delete_macro

Delete a user macro (system macros are protected).

delete_macro(macro_name: str) -> dict

create_macro_from_template

Create a macro from predefined templates.

create_macro_from_template(
    name: str,
    template: str = "basic",
    description: str = ""
) -> dict

Available templates:

Template Description
basic Minimal macro with imports
part Part workbench operations
sketch Sketcher operations
gui GUI/dialog template
selection Selection handling template

Example prompt:

"Create a new macro from the 'sketch' template called 'DrawGear'"

Macro Development with AI

The MCP server excels at helping develop FreeCAD macros. Example workflows:

Debugging an Existing Macro

"Read the macro 'MyMacro' and explain what it does"
"Run the macro and show me any errors from the FreeCAD console"

Creating a New Macro

"Create a macro that:
1. Gets all selected objects
2. Calculates their combined bounding box
3. Creates a box around them with 5mm clearance"

Modifying a Macro

"Read the 'ExportSTL' macro and modify it to also export STEP files"

Best Practices for Macro Development

  1. Use templates - Start from create_macro_from_template for proper imports
  2. Test incrementally - Use execute_python for testing snippets before creating full macros
  3. Check console output - Use get_console_output to debug issues
  4. Document your macros - Add docstrings that explain parameters and usage
  5. Handle errors gracefully - Wrap operations in try/except blocks

Next Steps