Configuration
Environment variables
Section titled “Environment variables”| Variable | Default | Purpose |
|---|---|---|
MAX_FILE_SIZE_MB |
100 |
Upper bound on input file size. Every file-reading tool checks it and returns a size error rather than loading an oversized file. |
TEMP_DIR |
/tmp/cad_processing |
Scratch space for intermediate processing. Converted DWGs are cached in TEMP_DIR/dwg-cache. |
OUTPUT_DIR |
/app/output |
Where every tool that writes (conversions, renders, exports) puts its files. Tools return absolute paths under this directory. |
FREECAD_PATH |
/usr/lib/freecad/lib |
Appended to sys.path so the FreeCAD Python modules import. Only relevant when running the FreeCAD tier outside the Docker image. |
DWG2DXF_PATH |
dwg2dxf |
libredwg converter used for on-demand DWG input. A bare name is resolved on PATH; set an absolute path to pin a specific build. |
DWG_CONVERT_TIMEOUT |
300 |
Seconds a single DWG conversion may run before it is abandoned with a timeout error. |
RENDER_INLINE_MAX_BYTES |
262144 |
Ceiling for returning SVG markup inline from render_svg with return_content: "auto". Larger renders report their size and a fetch hint instead. |
RENDER_BASE_URL |
(unset) | Public base URL for the /renders/<name>.svg HTTP route, e.g. https://cad.example.com. When set, render_svg returns a url field. |
PUBLIC_DOMAIN |
(unset) | Fallback for the above: the render URL becomes https://$PUBLIC_DOMAIN/renders/<name>.svg. With neither set, url is omitted rather than guessed as localhost. |
Directory fallback: if a configured directory can’t be created (the /app/* defaults outside a container, say), the server falls back to a per-user temp directory and logs a warning — rather than leaving every later export to fail mysteriously.
The cad-mcp-server console script (installed from pyproject.toml):
cad-mcp-server [--transport {http,stdio}] [--host HOST] [--port PORT]| Flag | Default | Notes |
|---|---|---|
--transport |
http |
stdio for local subprocess clients |
--host |
0.0.0.0 |
HTTP transport only |
--port |
8000 |
HTTP transport only |
The version banner and all diagnostics print to stderr; stdout is reserved for the JSON-RPC stream in stdio mode.
For development with hot reload, use the FastMCP CLI directly instead of the console script:
fastmcp run src/freecad_server.py:app --transport http \ --host 0.0.0.0 --port 8000 --reload --reload-dir src(The legacy --reload flag on cad-mcp-server exits with instructions to use the command above.)
Transports
Section titled “Transports”Standard MCP subprocess transport. The client spawns the server and owns its lifecycle. See Getting started for the claude mcp add incantation.
The default. FastMCP serves the MCP endpoint at /mcp, and the server enables two options that matter for deployment:
json_response=True— plain JSON responses instead of SSE streamsstateless_http=True— no session ID required between requests
Together these keep remote clients (Claude’s remote connectors among them) working behind TLS-terminating reverse proxies, where SSE accept-header negotiation and sticky sessions are the classic failure points.
FreeCAD availability
Section titled “FreeCAD availability”FreeCAD is probed at startup, not required:
- Present — all 19 tools work. Core modules (Part, Mesh, Import) are all-or-nothing; optional workbenches (Draft, Sketcher, TechDraw, PartDesign, Assembly4, CAM, Arch, Material, the DXF importer) degrade individually, so one missing addon doesn’t poison the session.
- Absent — the six DXF analysis tools work fully; FreeCAD-backed tools return a per-call error.
In Docker, FreeCAD is opt-in at build time via WITH_FREECAD=1 — see Run with Docker.
DWG availability
Section titled “DWG availability”DWG input is converted on demand by libredwg’s dwg2dxf, which is probed per call rather than required at startup:
- Present on
PATH(or atDWG2DXF_PATH) — every DXF-reading tool accepts DWG transparently. - Absent — DWG input returns an error naming the missing binary and suggesting external conversion. DXF paths are unaffected.
Debian does not package libredwg, so the Docker image builds it from source only when WITH_DWG=1 is passed as a build argument — see Run with Docker and Handle DWG.