Skip to main content
Glama
b123d-print-mcp

b123d-print-mcp

by KD5RYN

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
B123D_PRINT_WORKSPACENoThe 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.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

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

Tools

Functions exposed to the LLM to take actions

NameDescription
read_guideA

The workflow and print rules (the b123d-print://guide resource). Call it once before the first part in a session: many clients never load that resource. essentials=True: only the short checklist of the rules most often skipped.

list_partsB

List the part scripts in the workspace, with the settings in effect.

use_printerA

Optional printer profile (default is generic mode). search: find printer names ("bambu a1", "prusa mk4"). name: make it active (saved in the user's config, or over HTTP and SSH in this workspace's b123d-print.toml; "generic" clears it); a nickname given before works too. nickname: only for two printers of the same model, e.g. name='bambu_lab_p2s_0_4_nozzle', nickname='p2s-garage': each nickname keeps its own calibration. material: pla, petg, asa, abs, tpu or the user's own. Only change the printer when the user asks for it.

save_setupA

Save the user's first-run answers (the setup_workspace prompt): printer (a name from use_printer's search, or a nickname), material, formats ("3mf,png"), default style; hole_comp=0 records that the slicer corrects holes (the default way); a nonzero, MEASURED hole_comp / hole_comp_h is an opt-in that builds the correction into every file; calibration: other coupon results, e.g. {"clearance": 0.18, "max_bridge": 15}. With a printer, measured values are stored for it and the material. Written where use_printer writes. A value already set there is kept and listed as a conflict: ask the user, then call again with overwrite=True. Empty arguments change nothing. move_flat=True (after asking the user) moves measured values set for every printer of a workspace under the active printer.

new_partA

Create parts//.py from the template (Dims dataclass, build(d), VARIANTS, views, checks). name: lower_snake_case. example: copy a bundled example instead (see list_parts), e.g. 'hole_coupon' to calibrate hole compensation. sketch_first: the template with a sketches(d) outline that build(d) extrudes, for a part that is mostly a 2D shape made solid (offer it per part, see the guide's Sketch first); check the outline with render_sketch. Returns a short confirmation; the template is the b123d-print://template resource (or read_part), show_code=True returns the new file's code here. Usually the next step is write_part with the whole script. If you haven't, call read_guide first; confirm the dimensions with the user before writing the script.

read_partC

Return the current code of a part script.

write_partA

Replace the whole part script with code (create the part with new_part first). The script must define build(d) (+ Dims, VARIANTS). If you haven't, call read_guide first; confirm the dimensions with the user before writing the script. Then call build_part.

paramsA

The part's named dimensions, read from the script without running it: each Dims field with its type, default as written, value (when the default is a literal), the comment saying where it came from, and its line; the derived values (@property) and the fields they use; and each variant's overrides in VARIANTS. Change one with set_params, not a whole rewrite.

set_paramsA

Change Dims values in the script in place, leaving every other character of the file as it was: values {"FIELD": new value, ...} replaces each field's default (only literal defaults: a default computed by an expression such as hole_comp(file) is refused with the reason; so are unknown fields, derived @property values and values of the wrong type). variant: change (or add) that variant's override in VARIANTS instead of the default. rebuild (default true): build before and after (the build cache makes "before" quick) and report what changed per piece: size and volume; parts: only those pieces. Saved like write_part (size limit, must compile). If the new build fails, the result has the diagnosis and the call to undo it.

build_partA

Run the part script (sandboxed, with a timeout) and report, per variant and part: bounding box size and min/max (mm), volume (mm^3), solid count, is_valid, the Dims values, and any error with its traceback; and under "timing" each piece's face count and build time, with a hint for a piece that is slow or dense. variant: key from VARIANTS ('standard' = ''). parts: comma-separated piece names from build(): build only those (lazy pieces: the others are never built). Built pieces are cached in out/.cache/, so render_preview, section, check and export reuse them while the script, its Dims and the settings stay the same; fresh=True builds again and replaces the cached pieces. Writes no other files. Ends with "before_printing": the review steps this version still needs, each with its call.

diagnose_failureA

The deeper look after a failed or broken build (failed results already carry a short DIAGNOSIS): builds one variant piece by piece, each on its own and without the build cache, and for each piece reports the error with its likely cause and specific fixes (where in the script, the piece, the numbers: e.g. the largest fillet radius that works on those edges), or for a piece that built, what makes it unprintable (invalid solid, zero volume, a 2D shape, not on the bed) and, for an invalid one, which faces and edges are bad, tiny edges and sliver faces left by booleans, and whether part.fix() repairs it. Then the assembly. parts: only those pieces. Stops before the time limit and names the pieces it did not get to.

render_previewA

Render six views (iso, top, front, right, iso from below, bottom) as a PNG image. parts: comma-separated part names from build() (several are laid out side by side; only those are built), 'assembly' (assembled position with stand-ins), or omit: the assembly if the script has one, else every printable part side by side. One variant (default: the first). size: 'normal' or 'small' (~800 px wide, cheaper). inline=False returns only the file (over HTTP: its download link), not the image itself. Uses the pieces cached by an earlier build; fresh=True builds them again. Remote server (HTTP/SSH): the files stay on the server, as a temporary working copy deleted when unused; bring the part home with download_part (one zip in the parts// layout). Never use ssh, scp or a shell on the server: there is none.

sectionA

Cross-section as a PNG image, each part in its own color. plane: 'XY' (at = Z height), 'XZ' (at = Y) or 'YZ' (at = X), in mm. parts: default the assembly if the script has one (shows fit and clearances), else all printable parts; or comma-separated names (only those are built). size: 'normal' or 'small' (~800 px wide). inline=False returns only the file (over HTTP: its download link), not the image itself. Uses the pieces cached by an earlier build; fresh=True builds them again. Remote server (HTTP/SSH): the files stay on the server, as a temporary working copy deleted when unused; bring the part home with download_part (one zip in the parts// layout). Never use ssh, scp or a shell on the server: there is none.

render_sketchA

Sketch first: one 2D shape from the script's sketches(d) hook, drawn flat on a mm grid as a PNG, with automatic dimensions (overall size, hole diameters, slot widths, inside corner radii, hole and slot centres from the lower-left corner) and the sketch checks: one closed region, the narrowest neck against min_wall, inside corners under R0.5 (BP-R1), holes under 1 mm, the outline against the bed. Show it to the user and get an OK before build(d) extrudes, revolves or sweeps it. sketch: its name in sketches(d) (default: the first). dims=False draws the shape and grid only. Nothing 3D is built. size: 'normal' or 'small'. Remote server (HTTP/SSH): the files stay on the server, as a temporary working copy deleted when unused; bring the part home with download_part (one zip in the parts// layout). Never use ssh, scp or a shell on the server: there is none.

checkA

Run the print checks: validity, overlap between assembly parts (incl. stand-ins), overhangs > 45 deg from vertical in print orientation (bed face ignored) and bridge spans, thin features (walls under one line width fail), round-topped horizontal holes, fillets on bed edges, gaps between parts printed in place, the script's Wall checks (thinnest material around deep cuts) and Probes. The fit between an assembly's pieces (hole alignment, gaps) is a separate tool, check_fit, unless the script lists Mates() in checks(d). Fix every FAIL; report every WARN. On a remote server (HTTP/SSH) the part is not on the user's machine until download_part brings it home. Uses the pieces cached by an earlier build, and each unchanged piece's findings of the per-piece checks; fresh=True builds and checks everything again. A passing result ends with the review steps this version still needs, each with its call.

design_metricsA

Design numbers for the design review, per printable part: size and proportions, filament (simple estimate, roughly +-20 %) and cost, print time (rough estimate), supports, shallow slopes that show layer steps, edge treatment (sharp / filleted / chamfered shares, distinct radii and chamfer sizes), mirror symmetry, screw sizes, seam corners, water traps, inside corners, hole edge distance, slenderness across the layers, vase-mode layers and lean (and the thinnest walls for a style that asks); then the suggestions the part's style triggers, each citing its DS-* rule. ALWAYS before export, after check passes; report its suggestions to the user. style: override the part's STYLE (functional, modern, least_cost, rugged, soft, structural, organic, decorative, toy, or a style file of the user's: list_parts shows them). up: the direction that points up in use for the water-trap check (+X, -Y, ...; default the script's UP, else +Z). as_json: the full numbers as JSON instead of the text report. Changes nothing.

suggest_orientationA

Rank the ways to put the part on the bed, so it does not print upside down or on a thin edge: the six axis-aligned orientations and the large flat faces of its convex hull, each scored on supports (area and grams under overhangs past max_overhang, bridges apart), bed contact, height and print time (rough estimates), bridges, tip-over risk (as the check) and, with a load or the structural style, whether the load runs along the layers (DS-T1). Returns a ranked table with the Rot(x, y, z) to apply in build(d) and how. ALWAYS before export (a part already flat on the bed: it says so in a second). piece: one printable part (default: each). load: the bending or tension direction as build(d) returns the part ('X', 'along Y', 'XZ', '1,0,1'). image: also render the top choice (of the first part). Changes nothing. Remote server (HTTP/SSH): the files stay on the server, as a temporary working copy deleted when unused; bring the part home with download_part (one zip in the parts// layout). Never use ssh, scp or a shell on the server: there is none.

exportA

Export printable parts to parts//out/, sorted: print/ (3MF, STL, print sheet: for the slicer), cad/ (STEP, GLB), images/, docs/ (BOM, view HTML), README.md. Default: every part, all variants. The files must reach the user: on a remote server download_part brings them home. parts: comma-separated part names from build() to build and export only those; variant: one variant. Uses the pieces cached by an earlier build and leaves files already up to date as they are (templates too); fresh=True builds and writes everything again. formats: comma-separated from step (other CAD: Onshape, Fusion, FreeCAD), stl and 3mf (slicers; 3MF keeps units), png (6-view preview + section views), glb (binary glTF, for web and 3D apps), print (the print sheet, [_]print.md: size, filament and time estimates, supports, tip-over, walls and infill, fits and hole compensation, PRINT_NOTES, for the slicer, including declared hardware), hardware (versioned whole-assembly BOM JSON, []hardware.json), bom and bom_csv (the shopping list of that hardware as a Markdown table, []_bom.md, and as CSV, bom.csv; hardware_list returns it in the result), spec (the replication spec from MEASURE.md, []_spec.md, for a part copied from a physical original; replication_spec returns it), or 'all'. Omit to use the user's formats setting (default: step, stl, 3mf and png). Ask the user which they want if unclear. view: a 3D view the user can turn in a browser, per variant: 'print' (default: the printable parts on the bed), 'assembly' (assembly(d) with its stand-ins) or 'none'. Over HTTP it is a signed link (no token, expires like the downloads); locally a self-contained HTML file in out/docs/ (works offline). Offer it to the user after an export. Over HTTP (a remote server) each file comes with a download link (no token needed, expires) and a b123d-print://files/ resource link; download_part gets the whole part (script, out/, ref/) in one zip. embed=True also puts files up to 2 MB into the result itself, for clients that can neither fetch URLs nor read resources. Before export, ALWAYS: check passes, design_metrics(name, style=...), suggest_orientation(name) (the "Before printing" block of build_part and check lists what is missing). With the review setting "warn" (default) export says what was skipped, here and on the print sheet; with "required" it refuses until the steps are done. skip_review: only when the user said to export without them, their reason (recorded on the print sheet). Remote server (HTTP/SSH): the files stay on the server, as a temporary working copy deleted when unused; bring the part home with download_part (one zip in the parts// layout). Never use ssh, scp or a shell on the server: there is none.

list_facesA

The flat faces of a printable part, for picking one for a face fit-test template (make_template kind='face'): stable ids (1 = the largest; the same geometry always gets the same ids, changed geometry may renumber), outward normal and side (bottom, top, front, back, left, right), area, center, bounding box, round holes (diameter, center) and other openings; curved faces are only counted. part: which printable part (default: the only one). highlight: a face id or side; also returns a picture of the part with that face in red, to confirm the choice with the user before making the template. size: 'normal' or 'small'. Remote server (HTTP/SSH): the files stay on the server, as a temporary working copy deleted when unused; bring the part home with download_part (one zip in the parts// layout). Never use ssh, scp or a shell on the server: there is none.

list_edgesA

The edges of a printable part, to pick the ones for a fillet or chamfer by id instead of guessing a selector: stable ids (1 = the longest; changed geometry may renumber), type (line, circle, arc, ellipse, spline), length, start and end (or center and radius), convexity (convex: an outside edge; concave: an inside corner; tangent: a smooth joint such as a fillet's side; seam), the turn between its faces and the two faces it joins (flat faces by their list_faces id, curved ones by type). Filters: face (an id, side or 'x,y,z' as in list_faces: its edges), kind, convexity, near ('x,y,z': edges within radius mm, nearest first); limit caps the list. part: which printable part. highlight: edge ids ('3,4,7', '3-6' or a list): also returns a picture with them in red and selector, a build123d expression (filter_by/group_by/sort_by on part.edges(), one face's edges or convex_edges/concave_edges(part)) that selects exactly those edges, verified on the part; put that in the script, never the ids (they change when the model changes). size: 'normal' or 'small'. Remote server (HTTP/SSH): the files stay on the server, as a temporary working copy deleted when unused; bring the part home with download_part (one zip in the parts// layout). Never use ssh, scp or a shell on the server: there is none.

measureB

Precise measurements on the built part, in mm, with the points where they were taken: check fits with numbers instead of guessing from pictures. kind: 'distance' (a, b: piece names from build() or assembly labels, stand-ins included): the smallest gap and its two points, or when they overlap the interference volume, its box and depth. Two assembly labels are measured where assembly(d) puts them (the fit). 'wall' (at: x,y,z on or in the material; direction: optional x,y,z): the thickness along a line through the point (default: into the part along the nearest face's normal), with the gaps and walls beyond it. 'faces' (face, face2: ids or sides from list_faces): the distance between two parallel flat faces (a wall, a slot), or the angle between them, and their closest points. 'hole' (face: a flat face id or side, and/or at: a point at the hole): each round hole's modeled diameter, what it prints at after hole_comp, center, axis, through or blind depth. a: the piece for wall, faces and hole (default: the only one). frame: 'auto' (default), 'print' (as build() returns it) or 'assembly' (as assembly(d) places it); points are in that frame. image: also a picture of the part with what was measured in red. Uses the build cache.

make_templateA

A fit-test template: a quick thin print cut from the real part (same hole compensation and clearances) to check size, hole pattern and mating fits before printing the whole part. kind: 'slice' (plane XY/XZ/YZ at = Z/Y/X: the part between two planes thickness apart, centered on at), 'face' (face: an id from list_faces, a side such as 'bottom', or 'x,y,z' on it: that flat face with its holes as a plate; a side means the largest face facing that way) or 'crop' (center, size: x,y,z in mm: the part inside that box, with a thin base plate where it needs one; base=False: never). thickness: mm (default 1.2). label: engrave ' ' (default), your own text, or false; skipped when there is no room. The template is laid flat (template face down, Z=0) and checked like a part. Writes template.* in formats (default: the formats setting): 3MF/STL in parts//out/print/templates/, STEP in out/cad/; with png also out/images/<...>_where.png, the part with the template's source in red (returned as the image; inline=False: only the file). Confirm the face or region with the user first (list_faces with highlight). Remote server (HTTP/SSH): the files stay on the server, as a temporary working copy deleted when unused; bring the part home with download_part (one zip in the parts// layout). Never use ssh, scp or a shell on the server: there is none.

download_partA

Bring a whole part home from a remote server, in the same layout a local install writes: parts//.py, parts//out/ (exports, renders, sections) and parts//ref/ (reference models). Over HTTP: ONE signed link (no token needed, expires) to a zip of all of it; run curl -fLo <name>.zip '<link>' and unzip it in the project folder, then check the files are there. Over SSH: the b123d-print pull command that writes the same files. Locally (stdio): says where the files already are. variant: only that variant's out/ files ('standard' = ''); formats: only those out/ files (step, stl, 3mf, png, glb, print, hardware, bom, bom_csv, spec); the script and ref/ always come. Over HTTP it also gives the 3D view links of the views export wrote (in a browser, no token). embed=True also puts the zip (up to 8 MB) into the result (over HTTP and SSH), for clients whose shell has no network (Antigravity/agy) or that can neither fetch URLs nor read resources: unzip it from where the client saved it. Call it as the last step of remote work, before reporting: a part is not done until its files are on the user's machine. Remote server (HTTP/SSH): the files stay on the server, as a temporary working copy deleted when unused; bring the part home with download_part (one zip in the parts// layout). Never use ssh, scp or a shell on the server: there is none.

compareA

Compare a part with a reference model: bounding box, volume and surface area differences, surface distances (mean, Hausdorff) after aligning orientation, an F-score, a 0-100 score and pass/fail. reference, candidate: STL, 3MF or STEP files inside the workspace, as paths relative to it (e.g. 'refs/bracket.stl', 'parts/bracket/out/print/bracket.3mf'). thresholds: optional overrides, comma-separated name=value (e.g. 'hausdorff_mm=2,volume_rel=0.05'). image: also return a view of the reference colored by deviation (green = matches, red = off); size: 'normal' or 'small' (~800 px wide); inline=False returns only its file (over HTTP: a link). Remote server (HTTP/SSH): the files stay on the server, as a temporary working copy deleted when unused; bring the part home with download_part (one zip in the parts// layout). Never use ssh, scp or a shell on the server: there is none.

save_versionA

Save a version of the project in its version history (git, on the user's machine): each part's script, its ref/ folder, MEASURE.md and the .py files beside it, and b123d-print.toml; never out/. Only when the user said yes: after a change that built and passed its checks, OFFER "Save this version? (: )", never save on your own. message: what changed, in the user's words ("arm 115 -> 130 mm"); part: only that part (default: all). The result says what was saved and the changed Dims values. start=True first makes the project folder a git repository with a .gitignore: only after the user agreed to keep a version history. On a shared (HTTP/SSH) server it runs nothing and returns the commands for the user's own project folder.

list_versionsB

The saved versions, newest first: date, id, message and the Dims values that changed. With part: numbered versions of that part (for restore_version), and what is not saved yet. On a shared (HTTP/SSH) server: the command for the user's own project folder.

restore_versionA

Bring a part (script, ref/, MEASURE.md) back to a saved version: a number from list_versions(part), or a commit id. It is saved as a NEW version, so nothing is lost: no reset, no deleted history, files added later are kept. Refused while the part has changes not saved yet (offer save_version first). Ask the user before restoring; then build_part and check. On a shared (HTTP/SSH) server: the commands for the user's project folder (version = the commit id), then write_part to put the restored script back on the server.

upload_referenceA

Get an original model (STL, 3MF or STEP) onto the server, into parts//ref/, to remix it, or a scan or photo (PNG, JPEG, TIFF, BMP) to trace with trace_outline (the part folder may not exist yet). With data_base64 (the whole file, base64) it is stored now, up to 50 MB; that is only practical for small files, since the model has to write out every byte. Without it, the result says how the USER copies the file: over HTTP a signed upload link for curl -fT <file> '<link>' (no token needed, expires), over SSH the b123d-print push command, locally the folder to copy it into. Then describe_model.

describe_modelA

Inspect an original model before remixing it: format, units (and whether they look wrong), size, volume, triangles and faces before/after merging coplanar triangles, how much is curved (faceted), round holes (diameter, axis, center), repairs needed, the designer/license metadata the file carries, and a suggestion: MODIFY it or REDRAW it. part: the part it is for. file: a name in parts//ref/ (or a workspace path such as 'refs/x.stl'). scale: '' (as the file says), a factor, or the unit the file was drawn in ('inch', 'cm'). image: also a 6-view render (saved as parts//out/images/_original.png).

before_afterB

For a remix: the original and the remix side by side, and the original colored by how far the remix is from it (compare's deviation view: green = unchanged, red = changed), with compare's score and metrics. The original is what build() loads with import_model, or what the script's original(d) returns. export writes the same two images when it writes PNGs.

check_fitA

How the pieces of assembly(d) fit together, as placed (stand-ins count as obstacles): interference (pairs that overlap: the volume and where; pairs closer than the clearance without touching: the gap and where; faces resting on each other are contact) and hole alignment (round holes of two pieces on one axis are partners: offset beyond hole_tol mm, default 0.2, fails; their diameters read as screw holes, clearance + pilot / insert / nut, and a pair no single screw explains warns; a hole whose axis runs into solid material of the next piece has no partner). Male/female joint pairs from the script's joints(d) (or a Mates(joints=...) in checks(d)) are intentional fits measured against their own clearance. Stand-ins: labels saying stand-in or dummy, or matching no piece of build(). verbose: list the passing pairs too. One variant, or all. Uses the build cache (fresh=True rebuilds).

hardware_listA

What to buy: the bought hardware the script declares in hardware(d) (screws, inserts, magnets, bearings), as one Markdown table to show the user: Qty | Item | Specification | Used for | Source/link | Status ("check before ordering" where the specification is not confirmed: ask the user, never guess it). Identical items are merged and summed. Offer it when a part declares hardware. name: one part; parts: comma-separated part names to merge into one list (each may be part:variant); neither: every part in the workspace. variant: the variant (default: the standard one). count: how many assemblies ("for 4 brackets"), which multiplies every quantity. format: 'table' (Markdown) or 'csv' (for a spreadsheet or cart). Reads only hardware(d): builds nothing. The bom and bom_csv export formats write the same list next to the exports. Changes nothing.

replication_specA

The replication spec of a part copied from a physical original (the replicate_part prompt): its MEASURE.md table (Feature | Value | Method | Accuracy | Status | Class | Source | Field | Why changed) joined with the script's Dims values, as one Markdown table (Feature | Field | Class | Source | Measured | Tol | Modeled | Δ | Why changed) plus flags: a critical value still an estimate or not measured, readings spread wider than their accuracy (draft, an oval hole, warp), a critical value modeled differently with no reason, a Field the script lacks. Several readings in a Value cell ("4.21, 4.19, 4.22") are averaged. variant: whose Dims (default: the standard one). Reads MEASURE.md and the Dims only: builds nothing, changes nothing. The spec export format writes the same table to out/docs/.

trace_outlineA

Trace a flat object in a scan or photo (parts//ref/, from upload_reference) into a 2D outline in mm for a part script: the largest object's outline and its holes, simplified to tolerance mm (few points: dense polylines build slowly), or with smooth=True through-points for a periodic spline. Scale, one of: dpi (a flatbed scan; omit everything to read it from the file), grid (cell size in mm of a grid or cutting mat under the object), reference ('card' = a credit card 85.60 x 53.98 mm beside the object, or 'L,S' mm of another rectangle), or points ('x1,y1,x2,y2' pixels, origin top left) with distance (mm between them). pick: 'x,y' pixel inside the object to trace when it is not the largest. threshold (0..1) and invert (object lighter than the background) override the automatic threshold. Writes out/docs/_outline.json (the points), out/docs/_outline.py (a snippet with OUTLINE, OUTLINE_HOLES and a face function) and out/images/_trace.png (the outline on the image: show it to the user to confirm). A scan is accurate to about a pixel; a photo only as far as it is square-on, flat and undistorted: check a known dimension before trusting it. Remote server (HTTP/SSH): the files stay on the server, as a temporary working copy deleted when unused; bring the part home with download_part (one zip in the parts// layout). Never use ssh, scp or a shell on the server: there is none.

recipeA

Tested build123d recipes for common printable features, with printing notes and sources: teardrop holes, counterbores and countersinks, nut traps, magnet pockets, snap arms (with strain sizing), living hinges, print-in-place hinges, lids with a lip, text, bed-edge chamfers, zip-tie and cable slots, ribs and gussets. name: '' lists them; a recipe (or one of its function names) gives its code, an example and the notes. Use one before improvising the feature; part scripts import them: from b123d_print.recipes import snap_arm.

Prompts

Interactive templates invoked by user choice

NameDescription
design_part_from_photosDesign a new part from photos and measurements: confirm dimensions first, then model, verify and report.
modify_partChange an existing part, keeping its conventions, and re-verify.
remix_partRemix someone else's model (STL, 3MF or STEP): inspect it, choose MODIFY or REDRAW, confirm the changes, then build, check (inherited vs new findings) and export.
replicate_partCopy a physical part (often injection-molded) as a printable one: a measurement plan, each dimension critical or free, molding features changed for FDM, a replication spec in MEASURE.md checked against the Dims, and a check of the copy against the original.
verify_partReview an existing part against the rules and report findings.
design_reviewReview a part that passes the print checks for its purpose and design style: metrics, renders, 3-7 concrete suggestions with rule IDs. Changes nothing without the user's OK.
fit_testMake a fit-test template of a part: a quick thin print of a face, slice or region, to check size, hole pattern and mating fits before the full print.
setup_workspaceFirst-run setup: ask the user for the printer, material, export formats and default style, save them with save_setup, then offer the calibration coupons in order.
calibrate_hole_compWalk through measuring HOLE_COMP with the calibration coupon.

Resources

Contextual data attached and managed by the client

NameDescription
guideThe workflow and print rules (same text as AGENTS.md).
templateThe part-script template new_part starts from.
recipes_indexThe recipe library: tested build123d functions for common printable features.

TDQS

A3.6/5.0

Scored across 35 tools

Disambiguation4/5

Most tools have clearly distinct jobs across the design-to-print lifecycle, and descriptions explicitly separate close pairs such as check vs check_fit and build_part vs diagnose_failure. A few boundaries remain fuzzy, notably save_setup vs use_printer for configuration, compare vs before_after for reference comparison, and measure vs check_fit for fit numbers.

Naming Consistency4/5

The dominant pattern is snake_case verb_noun, as in read_part, build_part, check_fit, save_version, and upload_reference. Some names break the pattern with single verbs/nouns such as section, export, recipe, params, check, and measure, and hardware_list reverses the verb_noun order, but the convention remains mostly readable and predictable.

Tool Count2/5

At 35 tools, the surface is well above the rubric's well-scoped range and feels heavy for an agent to manage. The broad CAD/printing workflow justifies many specialized operations, but several fine-grained tools could likely be consolidated under action parameters.

Completeness4/5

The set covers an unusually complete workflow: onboarding and recipes, part authoring/editing, build and diagnosis, print checks and fit measurement, rendering/export, version history, remote transfer, reference inspection/tracing, and hardware BOMs. Minor gaps remain, such as no explicit delete/rename part operation and some workspace/file administration left implicit.

Maintenance

ActivityNo data
ResponsivenessSyncing