{"name":"io.github.KD5RYN/b123d-print","slug":"kd5ryn-b123d-print","title":"b123d-print","description":"Vibe CAD for 3D printing: design, check and export printable parts with build123d.","url":"https://mcp.market/server/kd5ryn-b123d-print","rating":null,"grade":"A","score":85,"certified":false,"status":"active","category":"media","tags":["media"],"presence":{"score":37,"stars":1,"forks":0,"downloads_week":1842,"last_push_at":"2026-10-25T01:05:30.000Z","license":"MIT"},"uptime":null,"claimed":false,"transport":"pypi","callable_via_gateway":false,"default_price_micros":0,"repository":"https://github.com/KD5RYN/b123d-print","website":"https://kd5ryn.github.io/b123d-print/","version":"0.3.13","remotes":[],"packages":[{"registryType":"pypi","registryBaseUrl":"https://pypi.org","identifier":"b123d-print","version":"0.3.13","runtimeHint":"uvx","transport":{"type":"stdio"},"packageArguments":[{"value":"mcp","type":"positional"},{"description":"Folder for your parts (parts/<name>/...); default: the folder the client starts the server in","format":"filepath","type":"named","name":"--workspace"}]}],"tools":[{"name":"before_after","description":"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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"build_part","description":"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 b","write_action":true,"price_micros":0,"input_schema":null},{"name":"check","description":"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 betwee","write_action":true,"price_micros":0,"input_schema":null},{"name":"check_fit","description":"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","write_action":false,"price_micros":0,"input_schema":null},{"name":"compare","description":"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","write_action":false,"price_micros":0,"input_schema":null},{"name":"describe_model","description":"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/<part>/ref/","write_action":false,"price_micros":0,"input_schema":null},{"name":"design_metrics","description":"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 and slende","write_action":false,"price_micros":0,"input_schema":null},{"name":"diagnose_failure","description":"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","write_action":false,"price_micros":0,"input_schema":null},{"name":"download_part","description":"Bring a whole part home from a remote server, in the same layout a local install writes: parts/<name>/<name>.py, parts/<name>/out/ (exports, renders, sections) and parts/<name>/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 `b1","write_action":false,"price_micros":0,"input_schema":null},{"name":"export","description":"Export printable parts to parts/<name>/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 cac","write_action":false,"price_micros":0,"input_schema":null},{"name":"hardware_list","description":"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;","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_edges","description":"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","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_faces","description":"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: whic","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_parts","description":"List the part scripts in the workspace, with the settings in effect.","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_versions","description":"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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"make_template","description":"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","write_action":false,"price_micros":0,"input_schema":null},{"name":"measure","description":"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 (t","write_action":false,"price_micros":0,"input_schema":null},{"name":"new_part","description":"Create parts/<name>/<name>.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. 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 st","write_action":true,"price_micros":0,"input_schema":null},{"name":"params","description":"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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"read_guide","description":"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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"read_part","description":"Return the current code of a part script.","write_action":false,"price_micros":0,"input_schema":null},{"name":"recipe","description":"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 ex","write_action":false,"price_micros":0,"input_schema":null},{"name":"render_preview","description":"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, chea","write_action":false,"price_micros":0,"input_schema":null},{"name":"restore_version","description":"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 comman","write_action":false,"price_micros":0,"input_schema":null},{"name":"save_setup","description":"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,","write_action":false,"price_micros":0,"input_schema":null},{"name":"save_version","description":"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? (<part>: <what changed>)\", never save on your own. message: what changed, in the user's words (\"arm 11","write_action":false,"price_micros":0,"input_schema":null},{"name":"section","description":"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 imag","write_action":false,"price_micros":0,"input_schema":null},{"name":"set_params","description":"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 overri","write_action":false,"price_micros":0,"input_schema":null},{"name":"suggest_orientation","description":"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, wh","write_action":false,"price_micros":0,"input_schema":null},{"name":"trace_outline","description":"Trace a flat object in a scan or photo (parts/<part>/ref/<file>, 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","write_action":false,"price_micros":0,"input_schema":null},{"name":"upload_reference","description":"Get an original model (STL, 3MF or STEP) onto the server, into parts/<part>/ref/<filename>, 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 ho","write_action":true,"price_micros":0,"input_schema":null},{"name":"use_printer","description":"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 ke","write_action":false,"price_micros":0,"input_schema":null},{"name":"write_part","description":"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.","write_action":true,"price_micros":0,"input_schema":null}],"scan":{"score":85,"grade":"A","scanned_at":"2026-10-25T04:59:01.401Z","report":{"scannerVersion":"0.1.10","scannedAt":"2026-10-25T04:59:01.240Z","components":{"code":{"score":20,"max":25,"notes":["59 source files scanned"]},"reliability":{"score":-1,"max":20,"notes":["no gateway calls yet and no remote to probe"]},"poisoning":{"score":-1,"max":15,"notes":["tools not inspected (local package is not executed); not counted"]},"auth":{"score":12,"max":15,"notes":["local package, no credentials required"]},"maintenance":{"score":15,"max":15,"notes":["last push 0 days ago"]},"identity":{"score":8,"max":10,"notes":["registry namespace matches repository owner","GitHub account older than a year"]}},"findings":[{"id":"exec.eval","severity":"medium","component":"code","title":"eval / new Function used","evidence":"b123d_print-0.3.13/src/b123d_print/edges.py: …mType.LINE)...\", ...} part = fillet(eval(sel[\"expr\"]), radius=1) # in the scrip…"}],"inputs":{"packages":[{"registryType":"pypi","identifier":"b123d-print","version":"0.3.13","found":true,"weeklyDownloads":1842,"license":"MIT","dependencyCount":7,"publishedAt":"2026-10-24T17:51:20.997256Z","repositoryUrl":"https://github.com/KD5RYN/b123d-print"}],"repo":{"found":true,"owner":"KD5RYN","repo":"b123d-print","archived":false,"pushedAt":"2026-10-25T01:05:30Z","stars":1,"forks":0,"openIssues":3,"ownerType":"User","ownerAvatarUrl":"https://avatars.githubusercontent.com/u/75957530?v=4","ownerCreatedAt":"2020-12-14T00:24:47Z","license":"MIT"},"icon":{"url":"https://avatars.githubusercontent.com/u/75957530?v=4&s=128","source":"github"},"presence":{"stars":1,"forks":0,"downloadsWeek":1842,"license":"MIT","lastPushAt":"2026-10-25T01:05:30.000Z","score":37}}}},"grade_history":[],"reviews":[]}