b123d-print-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@b123d-print-mcpDesign a 40 mm round spacer, 10 mm tall, with an M3 hole, and export STL."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
b123d-print
Design 3D-printable parts with an AI assistant — any assistant. You describe a part (photos, caliper readings); the model writes a build123d Python script; b123d-print builds it in a sandbox, renders it, cuts cross-sections, runs print checks, and exports the formats you pick: STEP, STL, 3MF, PNG.
|
|
Two-part box for an IR transceiver board, with the board stand-ins | Section through the LED: lid cone, board, clearances |
|
|
Outdoor sensor case: dovetail back plate + support-free cover | Wall plate: section just past the face, where the wall check looks |
Scope: parts for FDM 3D printing, nothing else. Everything is built around a printed part: print orientation with the bed at Z=0, hole compensation, mating clearance, and overhang, wall-thickness and overlap checks. It is not a general CAD framework.
What's in it
b123d-printpackage + CLI — export, 6-view renders, colored multi-part cross-sections, and print checks: overlap between mating parts, overhang in print orientation, wall thickness around cuts, probes ("is the roof closed?").b123d-print-mcp— an MCP server, so it works from Claude Desktop, Claude Code, Gemini CLI, Cursor, VS Code, Codex and other MCP clients. Part scripts are model-written code: they run in a sandbox with a timeout and no network.The workflow, model-neutral — MCP prompts plus an
AGENTS.mdany agent can read. The rules come from real prints; one exists because a part broke through a 0.05 mm skin that no render showed.Examples — four parts designed this way and printed, plus a hole calibration coupon, in
src/b123d_print/examples/.
Related MCP server: openscad-mcp
Quick start
Install uv. It fetches Python 3.12 and every pinned dependency for you.
Add the server to your MCP client — Claude Desktop shown, others below:
{ "mcpServers": { "b123d-print": { "command": "uvx", "args": ["--from", "git+https://github.com/KD5RYN/b123d-print", "b123d-print-mcp", "--workspace", "/Users/you/parts"] } } }Restart the client and ask: "Design a 40 mm round spacer, 10 mm tall, with an M3 hole." Files land in
/Users/you/parts/parts/<name>/out/.
The first start downloads a few hundred MB (mostly OpenCascade, the geometry kernel) and can take a few minutes; later starts are fast. See Troubleshooting if your client gives up waiting.
Images:
render_previewandsectionreturn PNG images. The model can only check its own work if your client passes tool-result images to the model. Claude Desktop and Claude Code do; check your client's docs for others. Without it the checks still run, but the model designs blind — look at the PNGs inout/yourself.
Ways to use it
Method | When | Sandbox |
MCP server via | any MCP client; the normal way | yes (macOS; Linux with bubblewrap) |
MCP server in Docker | strongest isolation, or Windows | the container |
Claude Code plugin | Claude Code; adds a skill that points at the workflow | yes |
CLI / Python | agents that run shell commands, or by hand | no — runs your own scripts |
Connect your MCP client
Every client runs the same command:
uvx --from git+https://github.com/KD5RYN/b123d-print b123d-print-mcp --workspace <folder>.
The workspace is the folder that holds your parts (parts/<name>/<name>.py); it is created
if missing. Without --workspace the server uses $B123D_PRINT_WORKSPACE, else the folder the
client starts it in.
Settings → Developer → Edit Config (claude_desktop_config.json): the block in
Quick start. Always pass --workspace. If the server fails with "uvx not
found", use the full path from which uvx as command (desktop apps don't see your shell's
PATH).
claude mcp add b123d-print -- uvx --from git+https://github.com/KD5RYN/b123d-print b123d-print-mcp --workspace ~/partsOr the plugin (MCP server + skill; uses the project folder as workspace), inside Claude Code:
/plugin marketplace add KD5RYN/b123d-print
/plugin install b123d-print@b123d-print~/.gemini/settings.json (or .gemini/settings.json in a project):
{
"mcpServers": {
"b123d-print": {
"command": "uvx",
"args": ["--from", "git+https://github.com/KD5RYN/b123d-print", "b123d-print-mcp", "--workspace", "/Users/you/parts"]
}
}
}~/.cursor/mcp.json, or .cursor/mcp.json in a project: the same mcpServers block as for
Gemini CLI.
.vscode/mcp.json:
{
"servers": {
"b123d-print": {
"type": "stdio",
"command": "uvx",
"args": ["--from", "git+https://github.com/KD5RYN/b123d-print", "b123d-print-mcp", "--workspace", "${workspaceFolder}"]
}
}
}~/.codex/config.toml:
[mcp_servers.b123d-print]
command = "uvx"
args = ["--from", "git+https://github.com/KD5RYN/b123d-print", "b123d-print-mcp", "--workspace", "/Users/you/parts"]Any client that can start a stdio MCP server: command uvx, arguments as above. To pin a
version, use git+https://github.com/KD5RYN/b123d-print@v0.1.0 once releases exist.
Docker
The container is the sandbox: no network, and it sees only the folder you mount.
git clone https://github.com/KD5RYN/b123d-print && cd b123d-printdocker build -t b123d-print-mcp .Then point your client at Docker instead of uvx (Claude Desktop shown):
{
"mcpServers": {
"b123d-print": {
"command": "docker",
"args": ["run", "-i", "--rm", "--network", "none",
"-v", "/Users/you/parts:/work", "b123d-print-mcp"]
}
}
}-iis required (MCP talks over stdin/stdout);--rmremoves the container afterwards.Your parts and exports appear in the mounted folder (
/Users/you/partsabove).On Linux, add
"--user", "1000:1000"(yourid -u:id -g) so exported files belong to you.Released images will also be on GitHub's registry as
ghcr.io/kd5ryn/b123d-print-mcp.
CLI and Python (no MCP)
For agents that run shell commands, and for you:
uv tool install git+https://github.com/KD5RYN/b123d-printb123d-print init ~/parts && cd ~/partsb123d-print new bracketEdit parts/bracket/bracket.py (or let your agent do it), then:
b123d-print build bracket --formats 3mf,pngb123d-print checkCommand | Does |
| create a workspace: |
| scaffold a part from the template or a bundled example |
| export + section views, report sizes |
| run the checks; exit code 1 on any failure |
| bundled examples / parts in the workspace / settings in effect |
AGENTS.md (written by init) carries the workflow for agents that read it, such as Codex and
Cursor; for Claude Code put @AGENTS.md in CLAUDE.md. Running a part script directly also
works: uv run parts/bracket/bracket.py. The CLI does not sandbox: it runs your scripts
like any Python.
How a session goes
Start with one of the MCP prompts where your client supports them —
design_part_from_photos, modify_part, verify_part, calibrate_hole_comp —
or just ask; the server's instructions and the b123d-print://guide resource carry the same
rules. An illustrative, shortened exchange:
You: A case for this PIR sensor, mounted on a wall outside. (photos with calipers)
Model: Dimensions I read: body 69.6 × 24.5 × 19.1 (photo 2, calipers), dome Ø18.6 (photo 3), dome center about 35.5 from the bottom (estimate). Nothing shows how far the dome sticks out. Please confirm or correct before I model.
You: Dome sticks out 8. The rest is right.
Model: (new_part, write_part, build_part, render_preview, three sections, check; fixes a thin wall the check found, checks again) Done: 35.1 × 38.8 × 76.6 mm, valid. The sensor gets 0.6 mm per side, the dovetail 0.2 per face. Prints on its floor without supports (one flat bridge over the groove). Exported 3MF and PNG.
Tool | What it does |
| parts, bundled examples, settings in effect, sandbox in use |
| scaffold from the template, or copy a bundled example |
| read / replace the script (syntax-checked before saving) |
| run it: bounding box, volume, validity, dimensions, errors |
| 6-view PNG; |
| colored cross-section PNG on |
| validity, overlap, overhang, wall and probe checks |
| files to |
Output formats
File | For |
| the parametric source: change a |
| editing in other CAD (Fusion, Onshape, FreeCAD, SolidWorks): an exact solid you can push/pull, fillet and cut, without feature history; changes there don't flow back to the script |
| any slicer |
| slicers that read it (Bambu Studio, OrcaSlicer, PrusaSlicer); keeps units |
| 6-view preview, assembly render, section views |
Pick them in your config (formats = ["3mf", "png"]), per run (--formats step,3mf), or with
formats= on the MCP export tool. Default: all four.
A part script
from dataclasses import dataclass
from build123d import Align, Box, Cylinder, Mode, Part
from b123d_print import View, Wall, hole_comp
BED = (Align.CENTER, Align.CENTER, Align.MIN)
@dataclass(frozen=True)
class Dims: # every dimension named, in mm, with its source
W: float = 30.0 # typed measurement
H: float = 8.0
HOLE_D: float = 3.4 # M3 clearance, target printed size
CBORE_D: float = 6.5
CBORE_DEPTH: float = 3.0
HOLE_COMP: float = hole_comp(__file__) # from YOUR config, default 0
VARIANTS = {"": {}, "wide": dict(W=40.0)} # overrides only
def build(d: Dims) -> Part: # print orientation, bed at Z=0
p = Box(d.W, d.W, d.H, align=BED)
p -= Cylinder((d.HOLE_D + d.HOLE_COMP) / 2, 50, mode=Mode.PRIVATE)
p -= Cylinder((d.CBORE_D + d.HOLE_COMP) / 2, d.CBORE_DEPTH, align=BED, mode=Mode.PRIVATE)
return p
def views(d): # sections saved with every export
return [View("XZ", 0.0, "through the hole")]
def checks(d): # how much material is left around the counterbore?
return [Wall("", "XY", d.CBORE_DEPTH / 2, near=(0, 0), radius=d.W, label="around the counterbore")]
if __name__ == "__main__":
from b123d_print import run
run(__file__)Optional assembly(d) returns the parts in assembled position plus stand-ins for what they
mate with (a PCB, a sensor); the overlap check makes sure nothing printed hits them. See
esp_ir_blaster and
tuya_motion_sensor_outdoor_case.
The modeling API itself is documented in the build123d docs.
Settings and hole compensation
FDM printers print small holes undersize, by an amount that depends on printer, nozzle,
material and slicer. b123d-print never assumes a value: hole_comp defaults to 0.

Print the coupon (new_part("coupon", example="hole_coupon") over MCP, or
b123d-print new coupon --from hole_coupon), measure each hole, and set the average error:
# ~/.config/b123d-print/config.toml (`b123d-print config` shows what is in effect)
[print]
hole_comp = 0.4 # mm added to hole diameters when cutting
clearance = 0.2 # default mating gap
min_wall = 0.8 # Wall checks fail below this unless they set their own limit
max_overhang = 45 # degrees from vertical
formats = ["step", "stl", "3mf", "png"]A workspace b123d-print.toml overrides the user config; environment variables
(B123D_PRINT_HOLE_COMP, B123D_PRINT_FORMATS, ...) override both.
Printer profile (optional)
By default b123d-print is in generic mode: no printer assumed, 0.8 mm minimum wall, 45° overhang limit. If you set your printer, the model also knows its build volume and nozzle:
b123d-print printer list bambu a1 # search 405 printer modelsb123d-print printer use bambu_lab_a1_mini --material petgParts must then fit the build volume in print orientation (
fitcheck; it fails otherwise).Minimum wall becomes 2 line widths of your nozzle; material notes (PLA vs PETG vs ASA …) reach the model.
b123d-print printer hole-comp 0.4stores your coupon result for that printer + material.b123d-print printer use genericgoes back. Over MCP: theuse_printertool.
Printer dimensions come from OrcaSlicer's printer
library (facts only; see THIRD_PARTY.md). Not listed, or modified? Add your own
~/.config/b123d-print/printers/<name>.toml:
label = "My Ender 3 with 0.6 nozzle"
bed_x = 220
bed_y = 220
height = 250
nozzle = 0.6
# round_bed = true # deltas: bed_x is the diameter
# max_overhang = 50Materials work the same way in materials/ (label, notes, optional clearance).
The checks
overlap — intersection volume between every pair of
assembly(d)parts; > 0.01 mm³ fails.overhang — downward faces in print orientation, angle from vertical (wall 0°, ceiling 90°); > 45° is reported, the bed face is ignored, flat ceilings are marked
bridge.Overhang(part, fail=True)for parts that must print without supports.wall — thinnest material in a cross-section, optionally only around one cut: across the wall along the surface normal, and between separate outlines (hole to edge). Tips of ordinary corners don't count as thin; knife edges sharper than about 25° do.
fit — only with a printer profile: the part fits the build volume in print orientation.
probe — material must be present (or absent) in a small box.
valid — every printable part is a valid, non-empty solid.
Sandbox
Platform | Isolation |
macOS |
|
Linux with bubblewrap | no network, read-only system, same writable folders, home hidden |
Linux without bubblewrap, Windows | separate process + audit hook only — install bubblewrap, or use Docker |
Docker | the container ( |
Every build also gets a timeout (default 120 s, --timeout) and a CPU limit. The audit hook
(blocks sockets, subprocesses, native libraries, writes elsewhere) is defense in depth, not a
boundary on its own.
Updating
b123d-print --version (or the version field of the MCP list_parts tool) shows what you run.
Releases and what changed: GitHub releases.
Installed with | Update |
| uvx caches the build: run |
a pinned version | change the tag in your client config, restart the client |
|
|
Docker |
|
Claude Code plugin |
|
After updating:
Workspaces keep your parts and settings. The workflow text in a workspace's
AGENTS.mdis a copy; refresh it withb123d-print init --update-agents(MCP clients always get the current text from the server).Printer profiles ship with the package and update with it; your own files in
~/.config/b123d-print/are never touched.Part scripts: while b123d-print is 0.x the script conventions may change; the release notes say when, and
b123d-print checktells you what breaks.
Troubleshooting
Symptom | Fix |
First start is very slow, or the client gives up | it is downloading the dependencies; run |
Client says | use the full path from |
Model never looks at the renders | your client doesn't pass tool images to the model; open |
| a slow or endless script; raise |
| the script tried the network, a subprocess or files outside the workspace; part scripts only need build123d |
Holes print small | calibrate |
Linux: sandbox says "audit hook only" | install bubblewrap ( |
Platforms and status
0.x — early. The part-script convention may still change. CI tests macOS and Ubuntu, the
built package via uvx, and the Docker image on every push. Windows is untested: the MCP
server should run there without the OS sandbox; Docker is the safe route.
Contributing
Issues and pull requests are welcome. To work on it:
git clone https://github.com/KD5RYN/b123d-print && cd b123d-print && uv syncuv run pytest && uv run b123d-print check && uv run python tests/mcp_smoke.pyThe printer table is generated: python tools/sync_orca_printers.py refreshes
src/b123d_print/data/printers_orca.json from OrcaSlicer (records the commit it used).
New checks and example parts should come from something that was actually printed.
Credits
b123d-print is a thin layer over:
build123d — the Python CAD API every part is written in (Apache-2.0)
Open CASCADE Technology, via OCP — the geometry kernel (LGPL-2.1 with exception; bindings Apache-2.0)
lib3mf — 3MF export (BSD)
OrcaSlicer — printer dimensions for the optional printer profiles (AGPL-3.0; facts only, no files copied)
matplotlib and NumPy — renders, sections, check math
Model Context Protocol and its Python SDK (MIT)
uv — packaging and
uvx
Details and redistribution notes: THIRD_PARTY.md.
License
MIT © KD5RYN and contributors.
This server cannot be deployed
Maintenance
Related MCP Connectors
- OwlCADOAuthcom.owlcad
Parametric 3D CAD for AI agents: build print-ready parts, check them, export STL, 3MF or STEP.
Design 3D-printable parts by chatting: create, edit, render and publish parametric forges.
OCR, transcription, file extraction, and image generation for AI agents via MCP.
3D printing: printable models, calculators, troubleshooting wiki, build guides, AI 3D + CAD design.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables Claude to create 3D-printable CAD models using build123d, with tools for modeling, modification, analysis, and publishing to platforms like Thingiverse and GitHub.14Creative Commons Attribution Non Commercial No Derivatives 4.0 International
- AlicenseNot gradedqualityDmaintenanceEnables LLMs to create and manipulate 3D models using OpenSCAD through MCP tools for code-based modeling, preview, and export.1MIT

gitcadofficial
AlicenseNot gradedqualityBmaintenanceEnables agents to create and manipulate 3D CAD models using natural language via MCP, with git-based versioning and manufacturing output generation.1Apache 2.0- AlicenseCqualityCmaintenanceEnables an agent to define parameters in millimeters, build and validate parts or assemblies in a live Autodesk Fusion session, then export STEP, STL, 3MF, and F3D files. It also supports inspection and verification workflows before and after generated geometry is produced.33MIT



