Skip to content

ghbalf/freecad-ai

FreeCAD AI

Alpha software — this project is in early development. Expect rough edges, breaking changes, and the occasional FreeCAD crash from LLM-generated code. Use with caution and save your work frequently.

An AI-powered assistant workbench for FreeCAD that generates and executes Python code to create 3D models from natural language descriptions.

Features

  • Chat interface — dock widget with streaming LLM responses
  • Plan / Act modes — review code before execution (Plan) or auto-execute (Act)
  • Tool calling — 48 structured FreeCAD operations (Act mode) for safer, more reliable modeling
  • Skills — reusable instruction sets the model invokes autonomously or via /command (enclosure, gear, fastener holes, etc.)
  • Skill optimizer — automatically improve skill instructions via iterative test-evaluate-modify loop (/optimize-skill)
  • Hooks — user-defined Python hooks for lifecycle events (block tools, modify input, log activity, convert file attachments)
  • User extension tools — register your own Python functions as LLM-callable tools (.py or .FCMacro)
  • Vision routing — auto-detects LLM vision capability; non-vision models use MCP fallback via llm-vision-mcp, no-vision-path disables image controls
  • File attachments — attach images, text files, and documents to chat messages (capture, attach, drag-drop, paste); extensible via file_attach hook for binary formats (PDF, DOCX) or MCP servers for rich conversion
  • Image support — viewport screenshots and images sent as vision blocks; auto-detected binary format rejection (PDF, ZIP, Office docs)
  • Thinking mode — enable LLM reasoning for complex multi-step tasks (Off / On / Extended)
  • Context compacting — automatically summarizes older messages when approaching context limits
  • Session resume — save and load chat sessions to continue work later
  • 20 LLM providers — Anthropic, OpenAI, Ollama, Gemini, OpenRouter, Moonshot, DeepSeek, Qwen, Groq, Mistral, Together, Fireworks, xAI, Cohere, SambaNova, MiniMax, Llama, GitHub Models, HuggingFace, Zhipu, plus any OpenAI-compatible endpoint via Custom
  • Context-aware — automatically includes document state (objects, properties, selection) in prompts
  • Error self-correction — failed code is sent back to the LLM for automatic retry (up to 3 attempts)
  • AGENTS.md support — project-level instructions with include directives and variable substitution
  • Dark mode — chat widget automatically adapts to FreeCAD's light/dark theme (theme changes require FreeCAD restart)
  • Zero external dependencies — uses only Python stdlib (urllib, json, threading, ssl)

Requirements

  • FreeCAD 1.0+ (tested with 1.0.2 and 1.1.0)
  • An LLM provider (local Ollama, or an API key for a cloud provider)

Installation

Clone or copy this repository into FreeCAD's Mod directory:

Linux

ln -s /path/to/freecad-ai ~/.local/share/FreeCAD/Mod/freecad-ai

macOS

ln -s /path/to/freecad-ai ~/Library/Application\ Support/FreeCAD/Mod/freecad-ai

Windows

# Run as Administrator
New-Item -ItemType SymbolicLink -Path "$env:APPDATA\FreeCAD\Mod\freecad-ai" -Target "C:\path\to\freecad-ai"

Or manually copy the repository into %APPDATA%\FreeCAD\Mod\freecad-ai.


Restart FreeCAD. The FreeCAD AI workbench will appear in the workbench selector.

Configuration

  1. Switch to the FreeCAD AI workbench
  2. Click the gear icon to open settings
  3. Select your LLM provider and enter your API key (if needed)
  4. Click Test Connection to verify

Configuration is stored at ~/.config/FreeCAD/FreeCADAI/config.json.

Supported Providers

Provider API Key Required Notes
Ollama No Local models, default http://localhost:11434
Anthropic Yes Claude models via native API
OpenAI Yes GPT models
Gemini Yes Google AI via OpenAI-compatible endpoint
OpenRouter Yes Multi-provider gateway
Moonshot Yes Kimi models (default params pre-configured)
DeepSeek Yes DeepSeek-V3
Qwen Yes Alibaba DashScope (international)
Groq Yes Ultra-fast inference
Mistral Yes Mistral models
Together Yes Open model hosting
Fireworks Yes Fast inference
xAI Yes Grok models
Cohere Yes Command models
SambaNova Yes Fast inference
MiniMax Yes MiniMax models
Llama Yes Meta's official Llama API
GitHub Yes (PAT) GitHub Models marketplace
HuggingFace Yes (hf_...) Serverless inference API
Zhipu Yes GLM models (z.ai international)
Custom Varies Any OpenAI-compatible endpoint

Model Parameters

The Model Parameters table in Settings lets you set arbitrary sampling parameters (temperature, top_p, top_k, etc.) that are sent with each API request. Parameters are saved per model name — when you switch models, the saved parameters for that model are loaded automatically.

Click Load Defaults to reset to the provider's recommended values. For most providers the only default is temperature: 0.3. Moonshot ships with pre-configured values required by Kimi-K2.5.

Strip thinking from history

The "Strip thinking from conversation history" checkbox in Settings controls whether thinking/reasoning content is removed from previous turns before sending to the API. Some models (e.g. Gemma 3/4) reject thinking content in multi-turn conversations, while others (e.g. Kimi-K2.5) require it.

The checkbox is tristate: partially checked = auto-detect by model name (Gemma models strip automatically), checked = always strip, unchecked = never strip.

Usage

Plan Mode

Type a request like "Create a box 50mm x 30mm x 20mm". The AI generates Python code and displays it for review. Click Execute to run it, or Copy to copy to clipboard.

Act Mode

Same workflow, but with two execution paths:

  • Tool calling (default): The LLM invokes structured tools like create_primitive, boolean_operation, fillet_edges, etc. These are pre-validated operations wrapped in undo transactions — safer and more reliable than raw code.
  • Code generation (fallback): When tools are disabled or the LLM generates code blocks instead, code executes with the same safety layers as before (static validation, subprocess sandbox, undo transactions).

Tool calling is enabled by default. Disable it by setting enable_tools: false in ~/.config/FreeCAD/FreeCADAI/config.json.

Available Tools

Tool Description
create_primitive Box, Cylinder, Sphere, Cone, Torus
create_body Create a PartDesign Body for parametric modeling
create_sketch Sketch with lines, circles, arcs, rectangles + constraints (supports plane offset)
pad_sketch Extrude a sketch
pocket_sketch Cut a pocket from a sketch (auto-detects correct direction)
revolve_sketch Revolve a sketch around an axis (vase, wheel, bottle)
loft_sketches Loft between sketches for tapered/organic shapes
sweep_sketch Sweep a profile along a spine path (pipe, tube)
boolean_operation Fuse, Cut, or Common between two objects
transform_object Move and/or rotate an object
fillet_edges Round edges
chamfer_edges Chamfer edges
shell_object Hollow out a solid (PartDesign::Thickness)
mirror_feature Mirror a PartDesign feature across a plane
create_wedge Create a wedge/ramp shape
scale_object Scale an object uniformly or per-axis
section_object Cross-section through a plane or another object
linear_pattern Repeat a feature in a line
polar_pattern Repeat a feature in a circular pattern
multi_transform Chain linear pattern + polar pattern + mirror in one feature
create_inner_ridge Add a snap-fit ridge inside a rectangular hollow
create_snap_tabs Add snap tabs on a lid lip (pairs with ridge)
create_enclosure_lid Generate a snap-fit enclosure lid with correct dimensions
measure Volume, area, bounding box, distance, edge listing
describe_model Comprehensive geometry summary: dimensions, wall thickness, hollow/solid detection
list_faces List all faces with names, labels, normals, areas (optional filter)
list_edges List all edges with names, labels, lengths (optional filter)
list_documents List all open documents with object counts and active indicator
switch_document Switch the active FreeCAD document by name or label
get_document_state Inspect current objects and properties
create_variable_set Create a VarSet with named variables for parametric modeling
create_spreadsheet Create a Spreadsheet with named variables for parametric modeling
set_expression Bind object properties to expressions (parametric relationships)
modify_property Change any object property (supports relative: +10%, *1.5)
export_model Export to STL, STEP, or IGES
execute_code Fallback: run arbitrary Python
undo Undo last N operations, or undo until a named transaction
redo Redo previously undone operations
undo_history Show the undo/redo stack with named transactions
capture_viewport Save a screenshot of the 3D viewport
set_view Set camera orientation (front, top, isometric, etc.)
zoom_object Zoom the viewport to a specific object
use_skill Load a skill's instructions for complex tasks (enclosure, gear, etc.)
create_assembly Create an Assembly with grounded base part
add_assembly_joint Joint two parts (Fixed, Revolute, Cylindrical, Slider, Ball)
add_part_to_assembly Add a part to an existing assembly
select_geometry Interactive viewport picking for edges, faces, vertices

Skills

Skills are reusable instruction sets stored in ~/.config/FreeCAD/FreeCADAI/skills/. Invoke them by typing /command in the chat.

Built-in skills:

Command Description
/enclosure Parametric electronics enclosure with base, lid, screw posts
/thread-insert Heat-set thread insert holes (M2–M5) with correct dimensions
/gear Involute spur gear from module and tooth count
/fastener-hole Clearance, counterbore, or countersink holes (ISO dimensions)
/lattice Grid, honeycomb, or diagonal infill patterns
/skill-creator Create new skills interactively from the chat

Creating custom skills:

You can create skills manually (see below) or use /skill-creator in the chat to have the AI walk you through it.

~/.config/FreeCAD/FreeCADAI/skills/
  my-skill/
    SKILL.md          # Instructions injected into the LLM prompt
    handler.py        # Optional: Python handler with execute(args) function

The SKILL.md file contains instructions for the LLM. When invoked, these are injected into the prompt along with any arguments you provide. For example:

/enclosure 100x60x40mm, 2mm walls, snap-fit lid

If a handler.py exists with an execute(args) function, it runs directly instead of prompting the LLM.

User Extension Tools

You can register your own Python functions as tools that the LLM can call. Place .py or .FCMacro files in ~/.config/FreeCAD/FreeCADAI/tools/. Functions with type hints are automatically discovered and registered:

import math

def bolt_circle(diameter: float, count: int = 8, bolt_size: float = 6.5) -> str:
    """Create a bolt hole circle pattern on the XY plane."""
    import Part
    import FreeCAD as App
    # ... create geometry ...
    return f"Created {count} bolt holes on {diameter}mm PCD"

Requirements:

  • Public functions (no _ prefix) with type-hinted parameters
  • Supported types: float, int, str, bool
  • Return a str (success message) or dict with output/data keys
  • Docstring first line becomes the tool description

User tools are prefixed with user_ and available to the LLM, skills, and MCP server. Manage them in Settings → User Tools (Add, Remove, Reload). Enable "Scan FreeCAD macro directory" to also pick up compatible macros from FreeCAD's macro folder.

Thinking Mode

Enable LLM reasoning in Settings (gear icon). Three levels:

Level Description
Off Standard responses (default)
On LLM shows reasoning before responding
Extended Longer reasoning budget for complex tasks

Thinking is displayed dimmed in the chat. Provider support varies — Anthropic Claude, OpenAI o-series, and some Ollama models (qwen3) support thinking. Models that don't support it will silently ignore the setting.

Session Resume

Conversations are auto-saved after each LLM response. Click the Load button in the chat footer to resume a previous session from the last 20 saved conversations.

File Attachments

Attach files to chat messages via the Attach button, drag-and-drop, or paste:

File type Handling
Images (PNG, JPG, etc.) Sent as vision blocks (requires vision-capable model or MCP fallback)
Text files (TXT, MD, CSV, PY, JSON, etc.) Read as text and included in the message
Binary files (PDF, DOCX, XLSX, etc.) Converted via file_attach hook or MCP server

Why no built-in PDF/DOCX support? FreeCAD AI has a strict zero-external-dependencies policy — it uses only Python stdlib and runs inside FreeCAD's bundled Python. PDF/DOCX parsing requires external C libraries that cannot be bundled portably. Instead, two extensibility paths are provided:

  1. Hooks — lightweight, user-installed shell commands. Create a file_attach hook that calls CLI tools like pdftotext or pandoc. See docs/hooks/file-attach-example/ for a ready-to-use example. Text-only output.
  2. MCP servers — for rich conversion with images and structure preservation. Install a server like markdownify-mcp in Settings → MCP Servers.

To install the example PDF hook:

cp -r docs/hooks/file-attach-example/ ~/.config/FreeCAD/FreeCADAI/hooks/file-attach/
# Requires: sudo apt install poppler-utils  (provides pdftotext)

Binary files are detected by magic bytes (PDF, ZIP/Office, PNG, JPEG, ELF, etc.) and null-byte content scanning.

AGENTS.md

Place an AGENTS.md or FREECAD_AI.md file next to your .FCStd file to provide project-specific instructions:

# AGENTS.md
This project uses metric units (mm).
All parts should have 1mm fillets on external edges.
Use PartDesign workflow (Body -> Sketch -> Pad), not Part primitives.

Search order: document directory → parent directories (up to 3 levels) → ~/.config/FreeCAD/FreeCADAI/AGENTS.md

Include directives — split instructions across files:

<!-- include: materials.md -->
<!-- include: conventions.md -->

Variable substitution — use live document values:

Document: {{document_name}}
Objects: {{object_count}}
Active body: {{active_body}}

Translations

The UI supports internationalization via Qt's .ts/.qm translation system. Currently available:

Language Status
English Default (built-in)
German Complete

To add a new language, copy translations/freecad_ai_de.ts to freecad_ai_<lang>.ts, translate the strings (or use Qt Linguist), and compile with lrelease.

To re-extract strings after code changes:

cd translations && bash update_translations.sh

Project Structure

freecad-ai/
├── Init.py                    # Non-GUI init
├── InitGui.py                 # Workbench registration + commands
├── package.xml                # FreeCAD addon metadata
├── freecad_ai/
│   ├── config.py              # Settings (provider, API key, mode, tools, thinking)
│   ├── i18n.py                # Internationalization helpers
│   ├── paths.py               # Path utilities
│   ├── llm/
│   │   ├── client.py          # HTTP client with SSE streaming + tool calling
│   │   └── providers.py       # Provider registry
│   ├── tools/
│   │   ├── registry.py        # Tool abstractions + registry
│   │   ├── freecad_tools.py   # 39 FreeCAD tool handlers
│   │   └── setup.py           # Default registry factory
│   ├── ui/
│   │   ├── compat.py          # PySide2/PySide6 shim
│   │   ├── chat_widget.py     # Chat dock + agentic tool loop
│   │   ├── message_view.py    # Message + tool call rendering
│   │   ├── code_review_dialog.py
│   │   └── settings_dialog.py
│   ├── core/
│   │   ├── active_document.py # GUI-aligned active document resolution
│   │   ├── executor.py        # Code execution with safety layers
│   │   ├── context.py         # Document state inspector
│   │   ├── system_prompt.py   # System prompt builder
│   │   └── conversation.py    # Conversation history + compacting + save/load
│   ├── hooks/
│   │   ├── __init__.py        # Hooks package
│   │   └── registry.py        # Hook lifecycle event dispatch
│   └── extensions/
│       ├── agents_md.py       # AGENTS.md loader (multi-location, includes, vars)
│       ├── skills.py          # Skills registry + execution
│       └── user_tools.py      # User extension tools (discover, validate, register)
├── translations/
│   ├── freecad_ai_de.ts       # German translation source
│   └── update_translations.sh # Re-extract strings with pylupdate5
├── skills/                    # Built-in skill definitions
│   ├── enclosure/SKILL.md
│   ├── gear/SKILL.md
│   ├── fastener-hole/SKILL.md
│   ├── thread-insert/SKILL.md
│   ├── lattice/SKILL.md
│   └── skill-creator/SKILL.md
├── hooks/                     # Built-in hook examples
│   └── log-tool-calls/
└── resources/
    └── icons/
        └── freecad_ai.svg

Contributing

Contributions are welcome! See CONTRIBUTING.md for how to set up a dev environment, submit pull requests, and create new skills or providers.

License

About

AI-powered assistant workbench for FreeCAD — generate 3D models from natural language

Resources

License

LGPL-2.1, CC0-1.0 licenses found

Licenses found

LGPL-2.1
LICENSE-CODE
CC0-1.0
LICENSE-ICON

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors