Build123dBLOCK
MCP server for build123d to improve AI cognition when creating 3D CAD models
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
[](https://pypi.org/project/build123d-mcp/) [](https://pepy.tech/project/build123d-mcp) [](https://pypi.org/project/build123d-mcp/) [](https://github.com/pzfreo/build123d-mcp/actions/workflows/ci.yml) [](LICENSE) [](https://registry.modelcontextprotocol.io/v0/servers?search=build123d) [](https://glama.ai/mcp/servers/pzfreo/build123d-mcp)
[](https://insiders.vscode.dev/redirect/mcp/install?name=build123d-mcp&config=%7B%22command%22%3A%22uv%22%2C%22args%22%3A%5B%22tool%22%2C%22run%22%2C%22--python%22%2C%223.12%22%2C%22build123d-mcp%40latest%22%5D%7D) [](https://cursor.com/en/install-mcp?name=build123d-mcp&config=eyJjb21tYW5kIjoidXYiLCJhcmdzIjpbInRvb2wiLCJydW4iLCItLXB5dGhvbiIsIjMuMTIiLCJidWlsZDEyM2QtbWNwQGxhdGVzdCJdfQ==)
Give your AI CAD eyes.
build123d-mcp is not a standalone chatbot or CAD program. It is a CAD toolbox that an AI/LLM app can use through MCP.
With an LLM app such as Claude, Cursor, VS Code, Continue, Cline, or Codex CLI, build123d-mcp lets the assistant create build123d CAD models, render previews, measure geometry, fix mistakes, and export files such as STEP, STL, SVG, and DXF. Instead of writing a whole CAD script blindly, the assistant can build a part in small steps and check the result as it goes.
On the public [CADGenBench](h
de8e6242de54OBSERVED · 2026-10-08Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control.
claude mcp add build123d-mcp -- None build123d-mcp==0.3.91
Exposed tools (44)
30 read · 12 write · 2 destructive. Blast radius: 2 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
analyze_printability | read | Analyse a build123d shape for FDM printability using augura (BREP-exact analysis). |
bank_candidate | read | Atomically promote a gate-clean STEP as the safe output/checkpoint. Writes the candidate to a private sibling file, runs the authoritative written-and-reimported STEP gate, and replaces filename only on a fully verified PASS; on FAIL or an unchecked mesh gate, the candidate is deleted and any existi |
compare | read | Unified comparison tool. |
crop_drawing | write | Save one model-selected raster drawing region at readable scale. bbox_px is exact source-image [x0,y0,x1,y1]; scale is 0.25..12. Returns the saved PNG path and an exact crop-pixel→source-pixel transform, so coordinates read from the enlargement remain usable. This is a mechanical crop only: it perfo |
cross_sections | read | 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 |
design_audit | read | Audit the current session program as a *design*, not just a shape: surface its named numeric parameters (Θ) and test how robust each is to editing. Parses the assembled program (see script()) for top-level numeric assignments (e.g. `plate_thickness = 5.0`), then rebuilds the program with each parame |
destroy_session | destructive | Close THIS client |
edit_feature | write | Transactionally resize one plain cylindrical through hole identified by a current @feature handle. Reject holes with counterbores, spotfaces, countersinks or multiple constituent faces. Predict the annular volume change, then check exact added/removed material, hole recognition, every other hole and |
execute | write | 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 |
execute_file | write | Execute a canonical build123d .py file in a clean namespace and atomically promote its result. The prior active model is restored if the source has a syntax/runtime error, times out, produces no shape, or does not produce result_name. Assign a Shape to `result` or call show(); optionally set result_ |
export | read | Export model. format: step, stl, 3mf, dxf, svg, or comma-separated list e.g. |
find_bored_bosses | write | Find candidate bored bosses and report target-selection/edit evidence: bore opening location, axis into the part, outward axis, bore diameter/depth, planar cap faces at the opening, whether the cap is split across multiple faces, and construction advice. Use this before lengthening any boss that car |
find_bosses | read | Recognise external cylindrical bosses on a session object (defaults to current shape), including a turned part |
find_candidates | read | List recognised instances of a hole, boss, polygonal boss, slot, chamfer or fillet. qualifiers is JSON with optional axis (X/Y/Z), side (+X/-X/+Y/-Y/+Z/-Z, relative to the part bounding-box centre), and value_field; matches are reported for the literal axes and grouped over all 24 proper rotations o |
find_countersinks | read | Recognise countersinks (conical screw-head recesses) on a session object (defaults to current shape) — the feature find_holes reports only as a plain opening. A countersink is an internal cone flaring from a drilled bore out to a larger opening, coaxial with the drill; drill-point cones and external |
find_hole_patterns | read | 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], cente |
find_holes | read | 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 d |
health_check | read | 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. |
import_cad_file | write | Import a STEP (.step/.stp), STL (.stl), or 3MF (.3mf) 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. A multi-object 3MF register |
inspect_part | read | Return one compact generation-checkpoint inventory: bbox, solid/topology counts, holes grouped by axis/diameter/depth/bottom, bosses grouped by axis/diameter/height, recognised patterns with member counts, and a cross-section area profile. expected is an optional JSON object derived from the drawing |
install_skill | write | Copy a b123d workflow skill into the current project. |
interface_features | read | Suggest planar mounting faces from recognised hole openings, with exact hole handles. These are geometric candidates, not a declaration of design intent. Pass chosen hole handles as protected_refs to edit_feature(); that edit also checks every other recognised hole and the outer envelope. |
last_error | write | 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 {\ |
list_sessions | read | Report how many CAD sessions this server process is holding, its configured limit, and how long each has been idle. Handles are secrets and are never returned. Operator/diagnostic tool for HTTP deployments — over stdio there is always exactly one session. |
load_part | read | 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. |
locate_gate_defects | read | Report WHERE a solid fails the validity gate, with 3D coordinates — so you can fix the exact edge/face instead of guessing. validate()/export() tell you WHAT is wrong (e.g. |
measure | read | Measure a shape and return a complete geometric summary: volume (mm3), surface area (mm2), 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 |
mesh_holes | read | Find fastener holes in a MESH by slicing it on all three axes. Returns JSON {count, holes:[{axis, diameter, location, span, depth, through}]} where axis is the drilling direction and location is the hole centre in world coordinates. This is the mesh counterpart to find_holes(), which needs real topo |
mesh_section | read | Loops on one cross-section plane of a mesh, largest first. Returns JSON {axis, position, loop_count, enclosed_passages, loops:[{points, center, size, min, max, enclosed}]}, all in the two axes that are not `axis`. enclosed_passages counts loops at odd nesting depth, representing passages through mat |
prepare_drawing | read | Prepare a raster engineering drawing for efficient inspection. Detects substantial spatial regions, saves one labelled overview plus readable PNG crops, and returns their pixel bounding boxes and paths. Region ids are layout evidence only: this tool does NOT label views, recognise CAD features, inte |
recognise_features | write | Run the shared quiddity inventory once and return exact, run-local edit evidence. With families= |
render_view | read | Render model. Auto-detects 3D vs 2D: solids use VTK; flat drawings use the 2D pipeline. Renders confirm appearance, not geometry. format: png, svg, dxf, or both. direction accepts top, bottom, front, rear, side, left, right, or iso. quality: preview, standard, or high; a timed-out standard/high PNG |
repair_advice | write | Return structured, field-proven repair/edit recipes for an agent to implement explicitly in execute(). Unlike repair_hints(), which gives short error-specific tips, this emits a sequenced plan with code-pattern names, acceptance checks, and stop conditions. Provide the full validate()/export()/last_ |
repair_hints | read | Given an error message or validity-gate reason, return targeted fix suggestions for common build123d mistakes and gate failures: wrong Location syntax, missing .part, CadQuery idioms, blocked imports, degenerate boolean results, fillet edge selection, B-rep defects, mesh non-manifold/open-edge failu |
reset | destructive | Clear the current session back to empty state, including all snapshots. |
resolve | read | 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. |
restore_snapshot | read | Restore geometric state from a previously saved snapshot (current_shape and the show() registry). |
save_snapshot | write | Save a named checkpoint of the current geometric state (current_shape and the show() object registry). |
script | read | Return a single Python script assembled from all successfully executed code blocks in this session. Prepends |
search_library | read | 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. |
session_state | read | 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 thi |
validate | read | Check whether a shape would pass a CAD validity gate before exporting it. Returns a PASS/FAIL verdict plus JSON (passes_gate, n_solids, volume, is_manifold, brep_valid, reasons). The gate mirrors what strict CAD and mesh consumers require: a well-formed (BRepCheck), watertight, manifold solid with n |
version | read | 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 buil |
workflow_hints | write | 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. |
Trust audit
BLOCKgrade F · trust 46/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | WARN |
| L1 | Static analysis of the code | FAIL |
| L2 | Instruction surface (what it tells the agent) | FAIL |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (5 observation(s))
- Network
- none-observed
- Shell
- declared (7 observation(s))
- Dependencies
- pinned
- Secrets in source
- none-found
Findings (25)
Report how many CAD sessions this server process is holding, its configured limit, and how long each has been idle. Handles are secrets and are never returned. Operator/diagnostic tool for HTTP deploy
args = pickle.load(f)
result = pickle.load(f)
exec(compiled, self.namespace) # noqa: S102
exec(compile(source, entry["path"], "exec"), namespace) # noqa: S102
result = eval(expression, namespace) # noqa: S307
.coverage
.claude/skills/b123d-drawing/SKILL.md
m = importlib.import_module(mod_name)
fn = getattr(importlib.import_module(module_name), func_name)
destroy_session, reset
.coverage
fn = getattr(importlib.import_module(module_name), func_name)
check_ast("open('/etc/passwd')")check_ast("open('/etc/passwd'); getattr(x, '__class__')") # must not raiseresult = execute_code(session, "data = open('/etc/passwd').read()")r"C:\Windows\System32\drivers\etc\hosts" if sys.platform == "win32" else "/etc/passwd"
r"C:\Windows\System32\drivers\etc\hosts" if sys.platform == "win32" else "/etc/passwd"
_TRAVERSAL = "../../etc/passwd"
export_file(session, "../../etc/passwd", "step")
render_view(session, "iso", save_to="../../etc/passwd")
assert mod._safe_filename("../../etc/passwd") == "passwd.glb" # cannot escapebody=$(curl -s -X POST http://127.0.0.1:3111/mcp \
--url http://127.0.0.1:3111/mcp \
png_bytes = base64.b64decode(img_data)
Gates applied: critical_finding, no_behavioural_pass, undeclared_transfer.
de8e6242de54full audit observations/trust-audit/mcp-server/pzfreo__build123d.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-08 | de8e6242de54 | BLOCK | F | 46 | first audit |
Questions
What is the Build123d MCP server?
MCP server for build123d to improve AI cognition when creating 3D CAD models
What tools does Build123d expose?
44 in total: 30 read-only, 12 that write, and 2 that can delete or overwrite (destroy_session, reset). Every one is listed on this page with its risk.
Is Build123d safe to connect to an agent?
No — not without reading the findings first. The audit graded it F (46/100) and found 6 critical or high issues in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 2 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does Build123d need?
No credential environment variables were found in its source, so it appears to need none.
How does Build123d run?
It speaks stdio and streamable-http, so it runs as a local process your client starts. It is published on PyPI as build123d-mcp.
How current is this page?
The grade is for one exact copy of the source (de8e6242de54), read on 2026-10-08. The repository is watched and re-audited when it changes.