Skip to main content
Glama
pzfreo

build123d-mcp

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault

No arguments

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
executeA

Execute build123d Python code in the persistent session. Errors include automatic fix hints — read them before retrying. Use show(shape, name) to register named objects (name defaults to 'shape'); show() immediately prints volume and face count confirming the shape is non-empty. After any boolean operation (-, +, &) call measure() to confirm it succeeded (check topology.faces). named_face(shape, name) is a built-in helper: named_face(box, 'top') returns the highest-Z face, 'bottom'/'front'/'back'/'left'/'right' work similarly. find_edges(shape, geom='circle', radius=4.25, at_z=10.2, length=None, tol=0.05) filters edges for fillet/chamfer selection and prints what matched. save_json(name, obj) writes structured analysis data (face inventories, hole tables) to a server scratch file and returns its path — use it instead of printing large results; open()/os stay blocked.

render_viewA

Render model. Auto-detects 3D vs 2D: solids use the VTK tessellation path; 2D shapes (Sketches, edge Compounds, dimensioned drawings) use the ezdxf+matplotlib raster path — review dimensioned drawings the same way as 3D parts. Renders confirm appearance, not geometry — verify booleans with measure() first. format: 'png' (raster, default), 'svg' (HLR line drawing, works without a display), 'dxf' (HLR projection as parseable polylines for downstream 2D CAD), or 'both' (PNG + SVG together). If the PNG path fails (headless host), falls back to SVG automatically. direction: top, front, side, iso. azimuth/elevation: camera rotation in degrees applied after the direction preset. objects: comma-separated names or name:color pairs e.g. 'u_frame:blue,roller:red' (default: all, auto-coloured). quality: standard, high. clip_plane: x, y, z to slice; clip_at: absolute world coordinate along that axis (default: each mesh's midpoint). save_to: optional file path; for format='both' writes .png and .svg. mode: 'auto' (default; no solids + flat in Z = 2D), or '2d'/'3d' to force a pipeline when auto-detection picks wrong (e.g. a Compound mixing a Sketch and a solid routes to 3D); the path used is reported as 'Rendered via pipeline.' colors: optional dict mapping object names and special layer keys (_dims, _labels) to colour names or '#aabbcc'; overrides name:color syntax and the default dimension colour (2D PNG/SVG only; ignored for 3D and DXF). label_objects: when true, each named object is labelled at its centroid in the PNG. highlights: optional list of entities to label, e.g. [{"object": "bracket", "type": "edge", "index": 5, "label": "hinge_edge"}]; type is 'face', 'edge', or 'vertex', index matches shape.faces()/edges()/vertices(); the object must be registered with show() and in the rendered set. Labels are PNG-only.

measureA

Measure a shape and return a complete geometric summary: volume (mm³), surface area (mm²), topology (face/edge/vertex counts), bounding box with per-axis size and center, volumetric center of mass, 6-component inertia tensor (Ixx/Iyy/Izz/Ixy/Ixz/Iyz), and a face-type inventory classifying every face as Plane/Cylinder/Cone/Sphere/Torus/BSpline with area and type-specific params (e.g. cylinder diameter and axis); identical faces are collapsed with a count, non-analytic sliver faces folded into one summary line. Prefer measure over render_view for verifying geometry — numbers are unambiguous. topology is the fastest confirmation that a boolean operation succeeded: a failed cut leaves face/edge/vertex counts unchanged. object_name: named object from show() (default: current shape). density (g/cm³) or material preset (steel, stainless, aluminum/6061, brass, copper, titanium, abs, pla, petg, nylon) adds mass_g and scales inertia to true mass moments in g·mm².

clearanceA

Spatial relationship between two named shapes. Returns JSON with clearance (mm), status (one of: apart, touching, containing, interpenetrating), containment (a_in_b, b_in_a, or neither), and intersection_volume / a_volume_outside_b / b_volume_outside_a for overlap quantification. Reads clearance differently per status: apart=gap, containing=wall thickness from inner surface to outer hull (use this to verify a pocket fits inside a plate), touching=0, interpenetrating=0 (check intersection_volume + a_volume_outside_b for the wall-piercing case). object_a, object_b: names from show().

analyze_printabilityA

Analyse a build123d shape for FDM printability using augura (BREP-exact analysis).

Checks: overhangs, manifold/watertight, tip-over risk, brim/raft need,
minimum vertical feature (→ max layer height), and thin walls. Optionally
checks bed-fit against a declared build volume.

Returns a plain-text summary followed by a JSON report with per-finding
detail (kind, severity, message, area/location where applicable).

object_name: named object from show() (default: current shape).
support_angle: faces shallower than this many degrees from horizontal need
    support (default 45).
nozzle: nozzle diameter in mm for wall-thickness check (default 0.4).
min_perimeters: walls thinner than min_perimeters × nozzle are flagged
    (default 2).
build_volume: optional build envelope as 'X Y Z' in mm, e.g. '256 256 256';
    omit to skip the bed-fit check.
bed_tol: Z tolerance in mm for identifying bed-contact faces (default 0.001);
    raise it for parts whose bottom faces sit slightly off Z=0.
min_feature: minimum vertical feature size in mm to flag (default 0.5).
cross_sectionsA

Compute cross-sectional areas at evenly spaced planes along an axis. Returns a list of {position, area} pairs. axis: X, Y, or Z (default Z). num_slices: number of planes (default 10, minimum 2). Useful for detecting internal voids, wall-thickness variation, or verifying that a shape's cross-section profile matches a reference. object_name: named object from show() (default: current shape).

exportA

Export model. format: step, stl, dxf, svg, or comma-separated list e.g. 'step,stl' or 'dxf,svg'. 3D shapes (solids) export to step/stl; 2D shapes (Sketches and dimensioned drawings composed via build123d.drafting) export to dxf/svg. Mixing 2D and 3D formats for the same shape errors with a clear message. object_name: named object from show(), '' to export all named shapes as a combined assembly (default: current shape). STEP exports carry the session names as labels — single-object exports use the object_name, '' exports produce a Compound labelled 'assembly' with each child labelled by its show() name. Downstream CAD tools (FreeCAD, Fusion) will see the structured assembly with named bodies. Use dxf for engineering-drawing handoff to other CAD tools; svg for embedding in docs/wikis. The result echoes the exported shape's volume/bbox/face count (or bbox/edge count for 2D) as a final sanity check that the right, non-degenerate object was written.

inspect_drawingA

Structured bbox and annotation report for a 2D drawing.

Two modes:

1. Session mode (default): inspects objects registered via annotate()/show().
   Returns per-object bounding boxes, face/edge counts, annotation metadata
   (label string, measured length, Leader tip/elbow), and structural lint.

2. SVG mode (svg_path set): parses an SVG file from disk and reports page
   size, layer ids, text content + positions, and element counts. Decouples
   inspection from the build-and-register ceremony — works on SVGs from any
   source (CI artifacts, third-party exports, prior runs).

Use annotate(result, name) instead of show(result.shape, name) when building
with build123d_drafting so metadata is captured:

    from build123d_drafting import Dimension, Draft
    draft = Draft(font_size=2.5, decimal_precision=1)
    w = Dimension((-20, -10, 0), (20, -10, 0), "below", 8, draft, label="40")
    annotate(w, "width_dim")

For vanilla build123d.ExtensionLine/DimensionLine, pass the label explicitly:

    w = ExtensionLine(border=[...], offset=6, draft=draft, label="40")
    annotate(w, "width_dim", label="40")

Args:
    objects: comma-separated object names (default: all). Session mode only.
    svg_path: path to an SVG file on disk. Switches to SVG mode.
view_axesA

Return the world→page axis mapping for a project_to_viewport call, computed analytically (no projection performed). Use this BEFORE rendering a projected view to confirm which world axis ends up on which page axis and with what sign — catches bottom-view/side-view axis swaps before they show up in the render.

Returns JSON like {"world_X": ["page_X", -1.0], "world_Y": ["page_Y", 1.0],
"world_Z": ["depth", 0.0]} — for a bottom-view origin (0,0,-100), world-X
flips to negative page-X.

Args:
    viewport_origin: camera position, same arg as project_to_viewport.
    viewport_up: up vector. Defaults to (0,1,0).
    look_at: target point. Defaults to origin.
lint_drawingA

Run structural drawing-quality checks and return JSON {violations: [...]}.

Session mode (default): reconstructs the session's annotations and delegates
to build123d-drafting-helpers (lint_drawing + find_interferences) — single
source of truth. Surfaces label-vs-measured divergence (axis swap), Leader
line through its own label, annotation/label overlap, a witness/extension
line piercing a neighbour's label, redundant collinear lines, and page-bounds
overshoot.

SVG mode (svg_path set): scans an SVG file for export-only pathologies — most
importantly native <text> elements (build123d renders glyph paths, so any
<text> won't DXF-export and won't scale with the model).

drawing_scale: when the geometry was scaled up before projecting — e.g. a
7.5 mm feature drawn at 5:1 via part.scale(5) — pass the same factor (5.0)
so the label-vs-measured check divides each measured path length by it
before comparing to the label. This lets labels carry the *real* dimension
while the geometry is drawn enlarged, instead of every dim tripping a false
axis-swap warning. Session mode only; defaults to 1.0 (no scaling).

view_shape_names: list of shape names (from show()) representing the placed
view outlines. Used to detect view_annotation_overlap (annotation bbox
overlaps a view outline) and view_overlap (two view outlines overlap).
Pass the visible-side placed compounds from each projection, e.g.
["front_placed", "side_placed", "plan_placed", "iso"]. Session mode only.

Each violation is {severity, check, object, message}. Run this after major
drawing additions; running it BEFORE rendering catches the bug at the source.
render_drawingA

Rasterise an existing SVG file to PNG via resvg-py.

Complements render_view (which takes build123d shapes from the live
session) by accepting an SVG written outside the sandbox — typically by
a short Python script that does the ExportSVG call directly. The PNG is
returned inline so the LLM can see the drawing without you having to
open the file in another tool.

Args:
    svg_path: path to an SVG file on disk.
    width: output pixel width (default 1200); height set by SVG aspect ratio.
    save_to: optional path to write the PNG. If empty, PNG bytes are
        delivered inline only.
save_drawing_annotationsA

Write a .dims.json sidecar file alongside an SVG with label metadata.

build123d renders Text as filled glyph paths, not <text> SVG elements, so
label strings are irrecoverable from a finished SVG. Call this tool after
completing a drawing (annotate all dims/leaders with annotate()) and before
or after exporting the SVG. The sidecar is read automatically by
inspect_drawing(svg_path=...) to restore annotation content.

Workflow:
    1. Build your drawing with Dimension / Leader / annotate()
    2. Export SVG:  execute("exporter.write('drawing.svg')")
    3. Save metadata: save_drawing_annotations("drawing.svg")
    4. Inspect later: inspect_drawing(svg_path="drawing.svg")
       → includes full annotations dict from the sidecar

Args:
    svg_path: path to the SVG file (sidecar written as <svg_path>.dims.json).
search_libraryA

Search the part library. query: keywords matched against name, description, tags, category (empty returns all). Returns name, category, description, tags, and full parameter specs including types, defaults, and descriptions.

load_partA

Load a named part from the library into the session. name: part name from search_library. params: optional JSON object of parameter overrides e.g. '{"od": 8.0, "length": 20.0}' — unspecified params use their defaults. The part is registered as a named object and becomes current_shape.

save_snapshotA

Save a named checkpoint of the current geometric state (current_shape and the show() object registry). The Python variable namespace is NOT saved — only geometry. Call this before risky experiments so you can restore known-good geometry without re-running all prior execute() calls.

restore_snapshotA

Restore geometric state from a previously saved snapshot (current_shape and the show() registry). The Python variable namespace is NOT restored — execute() calls made after the snapshot are still in scope, but current_shape and all show() objects revert to what they were at snapshot time. Raises an error if the snapshot name does not exist.

diff_snapshotA

Compare two snapshots by geometry metrics (volume, topology, bounding box). snapshot_b defaults to current session state if omitted. format: 'text' (default, human-readable) or 'json' (structured, for programmatic consumption).

session_stateA

Return a structured JSON snapshot of the current session: current_shape metrics, all named objects (replaces list_objects) with geometry stats, snapshot names, and a variables summary of the Python namespace (type + volume for shapes, type + length for collections, type + value for scalars). Use this to orient after a reset, restore, or multi-step build to confirm what geometry and variables are active.

health_checkA

Verify that render and export dependencies are working. Tests PNG render (VTK), SVG render (build123d HLR), STEP export, and STL export with a trivial shape. Returns JSON with ok/error per capability. Run at session start if you suspect a missing dependency.

resetA

Clear the current session back to empty state, including all snapshots.

shape_compareA

Compare two named shapes (from show()) by geometry metrics: volume delta, bbox delta, topology delta (faces/edges/vertices), and center offset. Useful when you have an intended design and a reference/test shape and want to verify they match — or to quantify how a modification changed the geometry.

find_holesA

Recognise drilled holes on a session object (defaults to current shape). Coaxial internal cylinders are grouped into one record per hole: drill + counterbore + spotface stacks, keyway-split bores, and bores interrupted by crossing holes all count once. Returns JSON: {count, holes: [{axis (drilling direction, unit vector), location (opening point), diameter, depth (bore top to deep end; drill-point cone excluded), bottom: through|flat|drill_point|unknown, cbore: {diameter, depth}|null, spotface: {diameter, depth}|null}]}. Countersinks read as openings (not steps); threads and non-cylindrical features are not recognised.

find_hole_patternsA

Recognise hole patterns on a session object (defaults to current shape): ≥3 identical-spec holes equally spaced on a circle → bolt_circle (center, diameter/BCD), collinear at constant pitch → linear_array (pitch, direction). Returns JSON: {count, patterns: [{type, holes: [HoleFeature records], center/diameter | pitch/direction}]}. Each hole belongs to at most one pattern; make_drawing already annotates these automatically.

find_bossesA

Recognise external cylindrical bosses on a session object (defaults to current shape), including a turned part's OD — filter on diameter against the part envelope for local bosses only. Returns JSON: {count, bosses: [{axis (base toward free end), location (free-end point), diameter, height}]}.

align_checkA

Check alignment between two named objects along an axis. axis: X, Y, or Z. mode: flush (signed distance between bbox extremes — positive=A extends further), center (offset between bbox centroids), clearance (gap between nearest faces — positive=apart, negative=overlap). Returns JSON: {delta, axis, mode, object_a, object_b, interpretation}.

resolveA

Evaluate a selector expression against a named object and return a geometry descriptor. selector is a Python expression suffix applied to the object, e.g. '.faces().filter_by(Axis.Z).last()'. If label is given, the descriptor is stored in session.geometry_refs[label] and appears in session_state(). Returns JSON: {label, ref, object, selector, type, area/length, center, normal (for Face)}. The ref field uses @cad[object#label] format.

scriptA

Return a single Python script assembled from all successfully executed code blocks in this session. Prepends 'from build123d import *' if not already present. If save_to is given, writes the script to that path and returns {script_path, blocks}; otherwise returns {script, blocks}. Useful for exporting a reproducible script after an interactive session.

import_cad_fileA

Import a STEP (.step/.stp) or STL (.stl) file as a named object in the session. path: absolute or relative path to the file. name: name to register the shape under (defaults to the filename stem). The shape becomes both the named object and the current_shape. Returns volume, topology, and bounding box of the imported shape. After importing, use render_view() to visualise the shape, measure() for geometry queries, or shape_compare() to diff against a show() object. Note: STL imports produce a shell (volume=0) rather than a solid — render_view and measure still work, but clearance() and boolean operations require a solid. If you have both the original built shape and an imported copy in session.objects, render the imported one by name (e.g. objects='mypart') to avoid Z-fighting artifacts from two co-located shapes.

repair_hintsA

Given an error message from execute(), return targeted fix suggestions for common build123d mistakes: wrong Location syntax, missing .part, CadQuery idioms, blocked imports, degenerate boolean results, fillet edge selection, and more. Pass the full error string from execute() or last_error().

last_errorA

Return details of the last failed execute() call: exception type, message, and (for runtime and syntax errors) line number and a 5-line excerpt around the failing line. Security errors include a message but no line/excerpt. Returns {"error": null} if the last execute() succeeded or no execute() has failed yet. Call this immediately after an execute() error to get the exact failing line — much faster than re-reading the submitted code.

versionA

Return the installed versions of the build123d-mcp server, its key dependencies (build123d, build123d-drafting-helpers), and the companion packages importable inside execute() (bd_warehouse for threads/fasteners/gears/bearings, augura for printability analysis). Use this to confirm which server build is running — e.g. to check whether a feature or fix is present, or whether the client is talking to a stale install.

workflow_hintsA

Return guidance on how to use these tools effectively. Call this at the start of a session or whenever unsure which tool to reach for.

suggest_view_layoutA

Auto-calculate safe VIEW_X / VIEW_Y positions for a multi-view engineering drawing.

Measures the named shape's bounding box and returns per-view page positions
(VIEW_X, VIEW_Y), look_at values, and camera/up vectors for a standard
third-angle layout:

    [plan ]  [      ]
    [front]  [ side ] [ iso ]
                      [ title block (bottom-right) ]

Returns JSON with:
  views: {name: {VIEW_X, VIEW_Y, half_w, half_h, look_at, camera, up}}
  free_space: {name: {above/below: {x, y, h}, left/right: {x, y, w}}} — the
    empty rectangle outside each view edge, bounded by neighbouring views,
    the title block, and the margins; budget dimension tiers (n × tier
    pitch must fit in h/w) before placing annotations
  warnings: list of layout problems (out-of-bounds, title-block overlap)
  suggestion: recommended page_w/page_h/scale if the layout does not fit

object_name: name from show() — use "" to measure the current shape
page_w/page_h: sheet size in mm (default A4 landscape 297×210)
scale: drawing scale factor (default 1.0; use 2.0 for 2:1)
views: subset of ["front","plan","side","iso"] to place
title_block_w/h: reserved bottom-right area (default 150×30 mm)
margin: page margin in mm (default 10)
extents: [x, y, z] part sizes in mm — lays out from these numbers instead
    of a session object (use when the part isn't loaded, e.g. import failed)
centroid: [x, y, z] look_at origin when using extents (default [0, 0, 0])

Accuracy: front/plan/side positions are exact for orthographic projection.
Iso position is approximate (75% of 3-D diagonal as half-extent) — verify
with render_view() and adjust manually if the iso overlaps a neighbour.
install_skillA

Copy a b123d workflow skill into the current project.

Writes the appropriate config file for the requested agent so the
step-by-step workflow is available in future sessions.

skill: which workflow to install (default "drawing")
  - drawing   → multi-view engineering drawings from build123d geometry
  - modeling  → build 3D parts/assemblies (incl. from technical drawings)
target: one of "claude" (default), "agents-md", "cursor", "windsurf"
  - claude     → .claude/skills/<skill-dir>/SKILL.md  (Claude Code)
  - agents-md  → AGENTS.md  (Codex CLI, Antigravity, GitHub Copilot, Cline)
  - cursor     → .cursor/rules/<skill-dir>.mdc
  - windsurf   → .windsurfrules
force: overwrite existing installation (default False)

Prompts

Interactive templates invoked by user choice

NameDescription
start-cad-sessionPrime a new CAD design session with the task description and workflow reminders.

Resources

Contextual data attached and managed by the client

NameDescription
build123d_quickrefbuild123d API quick reference: primitives, booleans, positioning, sketch-to-3D, selectors, fillets.
build123d_selectors_cookbookTask-indexed cookbook of selector patterns: get the top face, find circular edges, filter by area/length/radius, Select.LAST in builder context, fillet detection, and the operator shortcuts.
build123d_drafting_cookbookCode-first 2D engineering drawings cookbook: project a 3D part to a 2D view, dimension with ExtensionLine/DimensionLine, add tolerances, compose a TechnicalDrawing title block, multi-view sheet layout, hole-table pattern, export to DXF/SVG.
build123d_drafting_apiAuto-generated API reference for build123d-drafting-helpers: exact signatures and one-line descriptions for every public class (Dimension, Leader, TitleBlock, Drawing, ...) and function, generated from the installed library so it always matches what execute() imports.
build123d_presentation_cookbookCode-first design-discussion diagrams: per-group colour via ExportSVG layers, filled feature highlights, legends with swatches, reference axes, titles, and Draft scaling for small parts. Sister cookbook to build123d://drafting (which targets fabrication handoff).
build123d_session_stateLive session state: current shape diagnostics, named objects, snapshots, and user-defined variables.
build123d_bd_warehouseCatalogue of pre-built parametric parts in bd_warehouse: bearings, fasteners, gears, pipes, threads, and more.
build123d_drawing_skillThe b123d-drawing engineering workflow skill: step-by-step guide for creating multi-view engineering drawings from build123d geometry (views, scale, annotation, lint, SVG/DXF/PDF export).
build123d_modeling_skillThe b123d-modeling workflow skill: step-by-step guide for building 3D parts and assemblies with build123d via this server — including extracting a spec from a technical drawing, the incremental build/measure/render loop, snapshots, and export.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pzfreo/build123d-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server