Skip to main content
Glama
TechHandPro

techhand-print-fab

by TechHandPro

techhand-print-fab

Shareable MCP server for original parts: idea → parametric model → STL/3MF → slice → optional print push to a Bambu X1 Carbon.

OpenSCAD is the primary model. A CadQuery script is written beside it and is not executed here. Design export stays on disk. When OrcaSlicer or Bambu Studio's CLI is installed, fab_slice (and fab_bambu_push_3mf) turn that mesh into a .gcode.3mf without opening the slicer GUI. A sliced file can be sent to the printer when you confirm it. TNT is not required.

Standing defaults, unless the part or the call says otherwise: PLA, bed textured_plate, Bambu Lab X1 Carbon, 0.4 mm nozzle.

Install

Python 3.10+. From a checkout:

python3 -m pip install -e .

That installs the techhand-print-fab command and pins mcp to the 2.x line (requirements.txt). Use python3 -m pip install -e ".[dev]" when you also want pytest (requirements-dev.txt).

OpenSCAD is optional for the built-in kinds (box, plate, mount plate, cylinder, tube, L-bracket). When openscad is on PATH, or OPENSCAD_BIN points at it, STL/3MF export shells out to it and boolean holes are in the mesh. Without it, those kinds still export from a built-in mesh. The bundled trainer grip files are custom_scad and need OpenSCAD to mesh. See the dogfood section.

CadQuery is not a dependency. model.py is a script for a machine that has CadQuery.

Related MCP server: 3D MCP Server

Run

stdio (Cursor and most local MCP clients):

techhand-print-fab

Streamable HTTP, for a connector that wants a URL. Default bind is loopback only:

techhand-print-fab --http --host 127.0.0.1 --port 8765

The MCP path is /mcp.

Projects live in FAB_DATA_DIR, or ~/.local/share/techhand-print-fab when that is unset. --data-dir overrides both.

Install as an MCP connector

Cursor, after techhand-print-fab is on PATH. This is the shape in examples/cursor-mcp.json:

{
  "mcpServers": {
    "techhand-print-fab": {
      "command": "techhand-print-fab"
    }
  }
}

Pin a data directory and an import root (for an existing .scad tree such as a grip CAD checkout):

{
  "mcpServers": {
    "techhand-print-fab": {
      "command": "techhand-print-fab",
      "env": {
        "FAB_DATA_DIR": "/home/me/.local/share/techhand-print-fab",
        "FAB_IMPORT_ROOTS": "/path/to/cad-v0"
      }
    }
  }
}

From a checkout before the script is on PATH, point Python at src:

{
  "mcpServers": {
    "techhand-print-fab": {
      "command": "python3",
      "args": ["-m", "techhand_print_fab"],
      "env": {
        "PYTHONPATH": "/path/to/techhand-print-fab/src"
      }
    }
  }
}

Grok Bot or any client that speaks Streamable HTTP: run techhand-print-fab --http --host 127.0.0.1 --port 8765 and point the connector at http://127.0.0.1:8765/mcp. Do not bind a public interface unless you have your own auth in front. This server has none.

Nothing in that setup calls TNT.

Tools

Tool

What it does

fab_create_project

Local project. Units are millimeters.

fab_list_parts

Parts already generated.

fab_param_model

OpenSCAD (model.scad) and, by default, a CadQuery script (model.py) from params JSON.

fab_export_stl

Binary STL on disk.

fab_export_3mf

Geometry-only 3MF. Not a Bambu/Orca project and not a toolpath.

fab_dfm_check

Wall, hole, overhang, clearance, and 256 mm bed heuristics.

fab_x1c_profile_notes

Starting notes for PLA, PETG, ABS, ASA, TPU, PA, and PA-CF.

fab_bom_sketch

Filament mass and a fastener guess from hole diameters.

fab_bambu_discover

List printers: host, model, state, and AMS when the printer exposes it. Does not print.

fab_bambu_status

Nozzle temperature, bed temperature, and job progress. Does not queue a job.

fab_slice

STL or geometry 3MF → .gcode.3mf with OrcaSlicer or Bambu Studio's CLI. Studio handoff when that CLI or FAB_SLICER_PRESETS is missing. Does not print.

fab_bambu_push_3mf

Slice an unsliced mesh on that same path, then upload a .gcode.3mf, or write a Studio handoff. dry_run defaults to true.

backend on fab_param_model is openscad, cadquery, or both (default). OpenSCAD stays the primary file whenever it is written.

Params

kind is box, cylinder, tube, plate, l_bracket, mount_plate, or custom_scad.

Prismatic parts use a corner at the origin: +X length, +Y width, +Z height. Round parts are centered on Z. An L bracket is a base plate plus an upright on the back edge (+Y).

face on a hole is base (drill along Z) or upright (L bracket only; x_mm is along the length and y_mm is the Z height). Cylinder hole x_mm / y_mm are offsets from the axis.

Example (examples/l-bracket.params.json):

{
  "kind": "l_bracket",
  "length_mm": 40,
  "width_mm": 30,
  "height_mm": 25,
  "thickness_mm": 3,
  "material": "PLA",
  "clearance_mm": 0.3,
  "holes": [
    {"diameter_mm": 3.4, "x_mm": 12, "y_mm": 10, "face": "base"}
  ]
}

custom_scad takes scad_body or source_path. source_path may be cad-v0 (the bundled trainer grip) or a .scad file or directory under the project folder or FAB_IMPORT_ROOTS (os.pathsep-separated). A directory becomes one part per file, named {part_name}-{relative-stem}, up to 50 files. A relative include <file.scad> inside that directory is inlined. Absolute includes, ../, use, and import() are rejected.

The bracket above names PLA. Omitting material means the same thing at slice time: PLA. Pass PETG (or another allow-listed material) only when that spool is loaded. examples/plate-pla.params.json is the small standing-default plate.

Call shape:

  1. fab_create_project with a name.

  2. fab_param_model with project_id, part_name, and params.

  3. fab_slice (exports model.stl when the part has no mesh yet), or fab_export_stl / fab_export_3mf if you want the mesh first.

  4. fab_dfm_check, fab_x1c_profile_notes, fab_bom_sketch as needed.

  5. fab_bambu_push_3mf when the .gcode.3mf should go to the printer. Push slices first if the mesh is newer than model.gcode.3mf.

output_path on export must stay inside the part directory or FAB_EXPORT_ROOTS.

PRINT dogfood: trainer grip CAD v0

Bundled at src/techhand_print_fab/cad_v0/ and installed with the package. Training grip block only. source_path cad-v0 needs no FAB_IMPORT_ROOTS entry.

File

Slug when part_name is trainer

grip_shell.scad

trainer-grip-shell

grip_shell_left.scad

trainer-grip-shell-left

grip_shell_right.scad

trainer-grip-shell-right

backstrap_insert.scad

trainer-backstrap-insert

laser_clamp.scad

trainer-laser-clamp

spring_seat.scad

trainer-spring-seat

trigger_lever.scad

trainer-trigger-lever

assembly_preview.scad

trainer-assembly-preview

Left and right shells include <grip_shell.scad>. The import step inlines that file. assembly_preview.scad is a pose stub (import_grip is not a module in this set) and is not the STL target.

  1. fab_create_project with name Trainer grip v0 and a short description of the original trainer block.

  2. fab_param_model with that project_id, part_name trainer, source_path cad-v0, and params {"material": "PETG"}.

  3. fab_list_parts returns the eight slugs above.

  4. fab_dfm_check on trainer-grip-shell. Header numbers are read from the file: wall about 2.4 mm, clearance 0.25 mm, box 110 × 32 × 120 mm. fab_dfm_check on trainer-laser-clamp warns on the 0.15 mm diametral clearance.

  5. fab_export_stl on trainer-grip-shell.

Step 5 needs OpenSCAD. These parts are not a built-in primitive. The server still writes model.scad. If openscad is missing, the tool returns an error that names OpenSCAD and does not report a mesh or a printer job. Install OpenSCAD, or set OPENSCAD_BIN, and call fab_export_stl again. fab_export_3mf is the same gate. Box, plate, and the other primitive kinds export without OpenSCAD.

Prefer Push stays held. Ticket attach stays the optional extras/tnt package.

Headless slice

Normal parts do not need the Bambu Studio window. fab_slice, and fab_bambu_push_3mf on an unsliced mesh, run a local slicer CLI and write model.gcode.3mf.

A checkout without orca-slicer or bambu-studio on PATH gets the Studio handoff. Tests cover that fallback and a mocked CLI. A machine with the CLI and full presets slices for real.

  1. Install OrcaSlicer or Bambu Studio so orca-slicer or bambu-studio is on PATH. ORCA_SLICER_BIN or BAMBU_STUDIO_BIN overrides that search. An explicit path that is not executable is an error. It is not replaced by another binary on PATH.

  2. Call fab_slice. When machine.json, process.json, or filament/PLA.json is missing or still has inherits, the server flattens the installed slicer's resources/profiles tree (next to the binary, or FAB_SLICER_PROFILE_ROOT). It looks up Bambu Lab X1 Carbon 0.4 nozzle, 0.20mm Standard @BBL X1C, and Bambu PLA Basic @BBL X1C, drops inherits, and writes full files. Vendor profiles are not in git. An AppImage does not expose that tree; set FAB_SLICER_PROFILE_ROOT to the extracted resources/profiles directory.

  3. Those files land in FAB_SLICER_PRESETS when that variable is set, otherwise in FAB_DATA_DIR/slicer-presets/x1c-0.4-pla-textured (~/.local/share/techhand-print-fab/slicer-presets/x1c-0.4-pla-textured when FAB_DATA_DIR is unset). The same step is:

techhand-print-fab --expand-presets \
  --profile-root /path/to/resources/profiles \
  --out "$FAB_SLICER_PRESETS" \
  --material PLA \
  --bed textured_plate

Jeremiah's X1 Carbon plate is Textured PEI, the same plate as the earlier smoke. Stock profiles often tag the sliced file Cool Plate or cool_plate. fab_slice writes Orca curr_bed_type Textured PEI Plate into process.json, then rewrites the selected plate in the 3MF. The standing bed also locks plate_id textured_pei in the tool result, the gcode header, and the plate metadata. bed_type stays textured_plate. A sliced file whose selected plate is still cool_plate or Cool Plate is a slice error and is not kept. Pass bed_type: cool_plate only when the physical plate is the cool plate. auto leaves the plate already stored in the preset.

  1. The server runs:

orca-slicer model.stl \
  --load-settings "$FAB_SLICER_PRESETS/process.json;$FAB_SLICER_PRESETS/machine.json" \
  --load-filaments "$FAB_SLICER_PRESETS/filament/PLA.json" \
  --load-defaultfila \
  --arrange 1 \
  --slice 0 \
  --export-3mf model.gcode.3mf \
  --nozzle-diameter 0.4 \
  --curr-bed-type "Textured PEI Plate"

--curr-bed-type follows the bed you passed: textured_plate → Textured PEI Plate, hot_plate → High Temp Plate, cool_plate → Cool Plate, engineering_plate → Engineering Plate. auto leaves the plate already stored in the preset. Empty bed_type is textured_plate. Empty material uses the part material, then PLA.

profile_applied is true only after that CLI writes Metadata/plate_N.gcode and the plate metadata matches the bed you asked for. This package does not ship a Bambu profile and does not call the Bambu cloud. A .gcode.3mf you sliced yourself keeps profile_applied false.

If the CLI is missing, or the profile tree cannot be flattened, the tool writes studio-handoff/ and preset_files. Each row is machine.json, process.json, or filament/<MATERIAL>.json with status ok, missing, inherits, or invalid. A file that still has inherits is not sliced, even when it also has machine_start_gcode. If the CLI runs and fails, mode is slice_error, printer_dispatched stays false, and the handoff is still written. Printer secrets are stripped from the slicer process environment.

A newer model.stl or model.3mf replaces a stale model.gcode.3mf on the next slice or push. A newer model.gcode.3mf is sent as-is.

Bambu X1 Carbon print push

PLA, PETG, ABS, ASA, TPU, PA, and PA-CF are allowed. PLA is the default. Notes are starting temperatures, not a slicer profile.

The printer runs a sliced .gcode.3mf. fab_export_stl and fab_export_3mf write geometry only. Raw .gcode is not queued.

The tool contract is also in openapi/print-fab.openapi.json. That file describes MCP tools. It is not a second HTTP API. Streamable HTTP is still the MCP endpoint at /mcp.

Why LAN Developer Mode

Bambu documents Developer Mode as the third-party control channel: MQTT on port 8883 and FTP on port 990, after LAN Only mode is on. That is the path this server uses for one X1 Carbon.

Farm Manager is optional. Its local REST API listens on port 8888. Use it when BAMBU_TRANSPORT=farm, or when BAMBU_FARM_URL is set and no LAN host is configured. A printer bound to Farm Manager closes its own MQTT port, so LAN and farm are two attachments. The cloud API is unused.

fab_bambu_discover reports path: lan_developer_mode and a why string with this choice. With BAMBU_LAN_HOST set it sends the printer's TCP 3000 detect frame. That probe does not use BAMBU_ACCESS_CODE, BAMBU_SERIAL, a farm token, or BAMBU_PRINT_ENABLED. No other BAMBU_* variable is required for the detect path. SSDP (UDP 2021 and 1990) runs only when you pass ssdp: true or set BAMBU_DISCOVER_SSDP=1, and that scan also needs no secrets. When BAMBU_ACCESS_CODE matches that serial, a read-only MQTT pushall fills state and ams.

Printer setup

  1. On the X1 Carbon, turn on LAN Only mode.

  2. Turn on Developer Mode and accept the notice on the printer.

  3. Record the LAN IP, the access code, and the serial number into the secret store. Do not paste them into chat.

Auth (orange-secret / vault inject)

Secrets are process environment variables. This package does not read a vault file and does not write secrets into the project directory. Inject them when the MCP process starts (orange-secret, an org vault agent, a systemd EnvironmentFile, or the env block of the MCP client). Never paste an access code or token into chat, a ticket, a PR, or git.

Variable

Secret

Purpose

BAMBU_ACCESS_CODE

yes

LAN access code. MQTT and FTPS password. The username is always bblp and is not a secret.

BAMBU_FARM_TOKEN

yes

Farm Manager bearer token. Prefer this over the password.

BAMBU_FARM_PASSWORD

yes

Farm Manager password, used only when BAMBU_FARM_TOKEN is unset.

BAMBU_FARM_USERNAME

no

Farm Manager user paired with the password.

BAMBU_LAN_HOST

no

Private IP or .local name.

BAMBU_SERIAL

no

Printer serial. MQTT topics are device/{serial}/request and device/{serial}/report.

BAMBU_PRINT_ENABLED

no

1 allows a live push. Unset or 0 cannot queue a job.

BAMBU_DISCOVER_SSDP

no

1 also runs SSDP discovery.

BAMBU_ALLOW_NONPRIVATE_HOST

no

1 allows a public address. Leave unset.

BAMBU_TRANSPORT

no

lan when a LAN host is set, otherwise farm if a farm URL is set.

BAMBU_FARM_URL

no

https://192.168.x.x:8888

BAMBU_FARM_SERVER_ID

no

Value for x-bbl-sec-sid when you already know it.

BAMBU_FARM_CA_FILE

no

CA bundle for the farm server certificate.

BAMBU_FARM_CERT_FILE

no

Optional client certificate for mTLS.

BAMBU_FARM_KEY_FILE

yes

Optional client key for mTLS.

BAMBU_FARM_TLS_INSECURE

no

1 skips farm TLS verification. The host still has to be private. Leave unset.

FAB_EXPORT_ROOTS

no

Directory that holds a sliced .gcode.3mf from Studio.

ORCA_SLICER_BIN

no

OrcaSlicer CLI. Overrides orca-slicer on PATH.

BAMBU_STUDIO_BIN

no

Bambu Studio CLI. Used when ORCA_SLICER_BIN is unset.

FAB_SLICER_PRESETS

no

Directory of full machine.json, process.json, and filament/<MATERIAL>.json. Unset uses the local cache.

FAB_SLICER_PROFILE_ROOT

no

Installed resources/profiles tree used to flatten inherits. A bad path is not replaced by a search.

examples/cursor-mcp.bambu.json ships those names with empty values. Fill them in the client config on the machine that runs the server.

A live push also needs dry_run: false and confirm: true. The default dry_run: true uploads nothing and queues nothing.

LAN upload uses implicit FTPS on port 990 and stores the file in /model when that directory exists. The start command is MQTT print.project_file with url ftp:///model/<file>.gcode.3mf and param Metadata/plate_1.gcode. The md5 field is sent empty. printer_dispatched becomes true only after that command's ack is success, or after Farm Manager returns a task id. An upload that the printer does not accept stays printer_dispatched: false. Profile notes ride along in the tool result. profile_applied is true only when this process sliced with the local CLI. It stays false for a file you sliced elsewhere. sliced_plate is Textured PEI Plate and plate_id is textured_pei for the standing textured bed. This package does not ship a Bambu profile and does not call the Bambu cloud.

PRINT dogfood: test plate

PRINT runs this list and reports PASS or FAIL for each step to PRODUCT and CREW. Include mode, printer_dispatched, and message. Omit every secret. Jeremiah owns the physical confirm on the first live push. PRINT does not mark that physical check PASS.

Safe steps (no live push):

  1. Set BAMBU_LAN_HOST to the printer's private IP. Leave BAMBU_ACCESS_CODE, BAMBU_SERIAL, farm secrets, and BAMBU_PRINT_ENABLED unset for the discover probe. PASS: the process starts and no secret is in the chat transcript. FAIL: a secret was pasted into chat or committed.

  2. fab_bambu_discover with BAMBU_LAN_HOST set and no access code, serial, farm token, or vault. The TCP 3000 probe does not need those. PASS: the call returns, printer_dispatched is false, and the row has host. reachable: false is a pass when this process cannot open port 3000 (the printer is not on this network). model may be empty in that case. state stays empty and ams null until a later secret inject. FAIL: the call raises, or printer_dispatched is true.

  3. fab_bambu_status against an unreachable host, still with no vault. PASS for this fix: mode is print_error, printer_dispatched is false, and the tool returns instead of raising. A live reading (mode status, with nozzle_c, bed_c, state, and progress_percent) waits on BAMBU_ACCESS_CODE and BAMBU_SERIAL. Injecting those from orange-secret or the vault is out of scope for this fix. Do not paste them. FAIL: the call raises, or printer_dispatched is true.

  4. fab_create_project with name Test plate.

  5. fab_param_model with part_name plate and params {"kind":"plate","length_mm":20,"width_mm":20,"thickness_mm":3,"material":"PLA"}. Omitting material is the same standing default.

  6. fab_slice on plate (or skip this and let step 7 slice). With orca-slicer or bambu-studio installed and its resources/profiles tree visible (or FAB_SLICER_PROFILE_ROOT set), you do not hand-copy JSON. PASS: mode is sliced, sliced is true, material is PLA, bed_type is textured_plate, plate_id is textured_pei, sliced_plate is Textured PEI Plate, nozzle_mm is 0.4, profile_applied is true, and printer_dispatched is false. The sliced 3MF selected plate is textured_pei or Textured PEI Plate. PASS without the CLI or without a profile tree: mode is studio_handoff, printer_dispatched is false, and preset_files names machine.json, process.json, and filament/PLA.json with status missing or inherits. FAIL: printer_dispatched is true, plate_id is cool_plate, the selected plate is Cool Plate, or the tool claims a slice it did not write.

  7. fab_bambu_push_3mf with that project_id and part_name (default dry_run true). PASS with the CLI: mode is dry_run, sliced is true, request.print.bed_type is textured_plate, request.print.command is project_file, and printer_dispatched is false. PASS without the CLI: mode is studio_handoff and printer_dispatched is false. FAIL: printer_dispatched is true.

  8. Only when step 6 was a Studio handoff: open the STL in Bambu Studio or OrcaSlicer. Pick X1 Carbon, a 0.4 mm nozzle, textured PEI, and PLA. Check the notes against the spool datasheet. Slice. Export plate.gcode.3mf into the part directory or a folder listed in FAB_EXPORT_ROOTS.

  9. fab_bambu_push_3mf with file_path of that sliced file, material PLA, and dry_run true. PASS: mode is dry_run, printer_dispatched is false, request.print.command is project_file, request.print.bed_type is textured_plate, and request.print.md5 is empty. The access code is not in the result. FAIL: a file was uploaded or printer_dispatched is true.

Live push (Jeremiah at the printer):

  1. Set BAMBU_PRINT_ENABLED=1. Jeremiah calls fab_bambu_push_3mf with that sliced file, material PLA, bed_type left empty (textured plate), dry_run false, and confirm true. Tool PASS: printer_dispatched is true, dry_fire is false, and ack_result is success (LAN) or task_id is set (Farm Manager). Tool FAIL: printer_dispatched is false, including a timeout after upload. The file may already be on the printer; the tool does not claim the job was queued. Physical confirm: Jeremiah checks the printer panel. PRINT reports his confirm to PRODUCT and CREW and does not invent it. Prefer Push does not apply.

Farm Manager

Set BAMBU_TRANSPORT=farm, BAMBU_FARM_URL, and BAMBU_FARM_TOKEN (or BAMBU_FARM_USERNAME and BAMBU_FARM_PASSWORD). fab_bambu_discover calls GET /devices and returns host, model, state, and AMS when the device report includes them. fab_bambu_status reads that same report. fab_bambu_push_3mf uploads with POST /file/upload3mf and creates the job with POST /task. queue_only: true sends task_print_model 0. Direct print sends task_print_model 1. printer_dispatched is true only when that call returns a task id. Pass device_id when more than one printer is listed. The same dry-run and confirm gates apply.

Guardrails

The server refuses a 1:1 copy of a proprietary commercial product.

  • reproduction is original (default), interoperable_fixture, or proprietary_clone.

  • proprietary_clone is always refused, before any file is written.

  • Phrases such as "exact copy", "1:1 clone", "counterfeit", "knock-off", and "copy the commercial product" are refused on names, intent, notes, and imported OpenSCAD.

  • An original bracket, a fixture you designed, or geometry from your own measurements is in scope. Saying "1:1 in millimeters" about your own sketch is not a clone request.

Design tools (fab_create_project through fab_bom_sketch) set dry_fire: true and printer_dispatched: false. Export copy says the mesh was written and no printer job was submitted. Profile notes are starting temperatures and habits for a person to type into OrcaSlicer or Bambu Studio. They are not an official Bambu profile and they are not applied to a slicer. Confirm them against the filament datasheet.

fab_bambu_discover and fab_bambu_status do not print. fab_slice does not print. fab_bambu_push_3mf sets printer_dispatched: true and dry_fire: false only after the printer or Farm Manager accepts a sliced job. A geometry STL or 3MF is sliced when the CLI and presets are ready, and otherwise writes a Studio handoff. dry_run: true (the default), a missing confirm: true, or BAMBU_PRINT_ENABLED unset returns a plan and leaves printer_dispatched false. Empty material is PLA. Empty bed type is textured_plate.

Print tools refuse firearm and other weapon-part requests from the job name, intent, and file name. Training-tool and general fab jobs stay in scope. A disclaimer in the text is not permission to queue a weapon part.

DFM numbers assume a 0.4 mm nozzle and a 256 mm X1 Carbon build axis. They do not inspect a sliced gcode file.

Optional TNT bridge

Default pip install of this package does not include ticket attach and does not import a TNT client.

The extra lives in extras/tnt and registers fab_attach_to_ticket only when both of these are true:

  1. techhand-print-fab-tnt is installed (entry point group techhand_print_fab.bridges).

  2. TECHHAND_FAB_ENABLE_TNT=1 is set when the server starts. If the flag is set and the extra is missing, the process exits instead of silently dropping the tool.

python -m pip install -e .
python -m pip install -e extras/tnt --no-deps

--no-deps avoids looking up techhand-print-fab on PyPI when you installed the core from this checkout. Once both packages are published, a normal install of techhand-print-fab-tnt is enough.

The tool runs user-tnt attach-fab (override the binary with USER_TNT_COMMAND, split like a command line, not a shell) and writes a JSON payload to stdin:

{
  "action": "attach_fab_artifact",
  "ticket_id": 403,
  "project_id": "...",
  "part_name": "clip",
  "note": "",
  "files": [{"name": "model.stl", "path": "/absolute/model.stl", "bytes": 123}],
  "printer_dispatched": false
}

user-tnt has to be installed and logged in on that machine. This repo does not ship it. Exit 0 is the only confirmation the bridge reports. It still does not start a printer.

Cursor snippet with the bridge turned on:

{
  "mcpServers": {
    "techhand-print-fab": {
      "command": "techhand-print-fab",
      "env": {
        "TECHHAND_FAB_ENABLE_TNT": "1"
      }
    }
  }
}

Leave that variable unset for a TNT-free connector. fab_attach_to_ticket will not be in the tool list.

Development

python -m pip install -e ".[dev]"
python -m pytest

CI runs that on Python 3.12 and does not install OpenSCAD. Tests cover tool schemas, the clone refusal, STL/3MF export through the built-in mesh, a mocked OpenSCAD success path, and mocked LAN MQTT / FTPS and Farm Manager HTTP clients. They do not contact a printer.

Out of scope

The Bambu cloud API, embedding a slicer in this process, a hard dependency on TNT, and Prefer Push. Headless slice shells out to OrcaSlicer or Bambu Studio and stops at a Studio handoff when that CLI is absent. DFM follow-ups that stay out of the print-push work: hole parsing, clamp bounding box, louder overhang warnings, BOM mass after an STL exists, and slotted-clamp clearance.

Available Tools

8 tools
fab_bom_sketchA
Read-only

Rough filament mass and fastener guesses from part metadata. Not a quote.

ParametersJSON Schema
NameRequiredDescriptionDefault
part_nameYesPart name or slug.
project_idYesProject id.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, covering the safety profile. The description adds behavioral context by labeling the output as 'rough guesses' and 'Not a quote,' which sets expectations about accuracy and scope. This is useful beyond the annotations, though it does not disclose potential failure modes or limits of the estimation logic.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence followed by a short exclusion statement. It is front-loaded with the core purpose and contains no filler. Every word earns its place, making it highly efficient for an agent to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simplicity of the tool (read-only estimation, two fully described parameters, and an output schema), the description is largely complete. It clearly states the tool's purpose and limitations. Minor omissions like prerequisites (e.g., part must exist) or error behavior are not critical for a basic read operation, and the output schema covers return details.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% for both parameters, so the schema already explains part_name and project_id. The description does not add any parameter-specific detail beyond the general 'from part metadata,' which is redundant with the schema. Baseline 3 is appropriate since the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: it produces rough estimates of filament mass and fasteners from part metadata. The explicit 'Not a quote.' exclusion clarifies scope and differentiates from any quoting tool, making its purpose unambiguous even without referencing siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit guidance is given on when to use this tool versus alternatives. The description only states what it does and that it is not a quote; it does not mention any sibling tools or conditions that would select this tool over others. The usage context is implied ('rough estimates') but not articulated as a decision rule.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fab_create_projectA

Create a local project directory. Does not talk to a printer or to TNT.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesName for an original design project.
unitsNoLength unit. v1 accepts mm only.mm
descriptionNoWhat the original part or fixture is for. Not a commercial clone brief.
reproductionNooriginal, interoperable_fixture, or proprietary_clone. proprietary_clone is refused.original

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses that the tool creates a local directory and explicitly states it does not communicate with a printer or TNT, which adds useful context beyond the annotation hints. It does not cover duplicate-name behavior or filesystem permissions, but the annotations and output schema reduce the burden.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences front-load the core purpose and add one useful exclusion. There is no filler, repetition, or tangential detail, making it highly scannable for an agent.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 100% schema coverage, an output schema, and annotation hints, the definition is largely sufficient for correct invocation. The description lacks broader workflow context, such as when to create a project relative to other fab tools, which prevents a perfect score.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds no parameter-level detail, but schema description coverage is 100%, with each parameter already documented. The phrase 'local project directory' mildly clarifies that name becomes a directory, but not enough to raise the score above the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action and resource: creating a local project directory. This clearly distinguishes it from sibling tools that list parts, export STL/3MF, or run DFM checks. The printer/TNT negation further reinforces its role as a project-creation, not fabrication-output, tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not explicitly say when to use this tool versus alternatives, nor does it name a sibling to prefer in other cases. The purpose implies it is an initial setup step, and the printer/TNT negation provides a partial when-not, but direct workflow guidance is missing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fab_dfm_checkA
Read-only

Heuristics for wall thickness, holes, overhang, clearance, and X1C bed size.

Notes are for a human reviewing an FDM print. Nothing is sliced or printed.

ParametersJSON Schema
NameRequiredDescriptionDefault
part_nameYesPart name or slug.
project_idYesProject id.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, and the description adds valuable context: it produces notes for a human, performs heuristics rather than exact simulation, and has no physical side effects. "Nothing is sliced or printed" goes beyond the read-only annotation by clarifying that no manufacturing artifacts are created. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tightly written sentences, with the heuristic categories front-loaded and the critical "nothing is sliced or printed" caveat included. Every sentence earns its place and there is no redundant filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only heuristic tool with two simple parameters, an output schema, and annotations, the description gives sufficient context about what the tool analyzes and the nature of its output. It could more explicitly orient the agent within the workflow relative to sibling tools, but nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the parameters are already minimally documented. The description adds no parameter-level meaning, such as how project_id and part_name relate or whether the part must already exist in the project. A 3 is the appropriate baseline since the schema carries the parameter documentation burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear domain: DFM heuristics for wall thickness, holes, overhang, clearance, and X1C bed size. It does not use a strong verb like "checks" or "validates," but combined with the tool name it is understandable and distinct from slicing/printing operations. It lacks explicit differentiation from the sibling fab_x1c_profile_notes, which could overlap on X1C-related notes.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context: "Notes are for a human reviewing an FDM print" suggests a pre-print design review stage. It also clarifies that nothing is sliced or printed, ruling out fabrication use. However, it does not explicitly state when to use this tool versus alternatives like fab_export_stl or fab_x1c_profile_notes.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fab_export_3mfA
Idempotent

Write a geometry-only 3MF mesh. Not a Bambu project and not a sliced job.

ParametersJSON Schema
NameRequiredDescriptionDefault
part_nameYesPart name or slug.
project_idYesProject id.
output_pathNoOptional extra copy path under the part dir or FAB_EXPORT_ROOTS.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate the operation is not read-only, is idempotent, and is not destructive, so the safety profile is covered. The description adds the 'geometry-only' qualifier and excludes Bambu/sliced-job variants, but does not disclose details like where files are written or whether existing files are replaced. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences carry real signal: the main action and the key exclusions. There is no filler, and the most important scoping information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 3-parameter export tool with complete schema descriptions, an output schema, and annotations covering idempotency and side effects, the description is largely sufficient. The only notable gap is not referencing sibling export tools such as fab_export_stl to help with format selection.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the parameters are already documented with clear titles and descriptions. The tool description itself adds no parameter-level information, so the baseline score of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('Write') and a precise resource ('geometry-only 3MF mesh'). The negative scoping ('Not a Bambu project and not a sliced job') clearly distinguishes this export from other output types and makes the tool's purpose immediately identifiable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides implied usage context: use this for a geometry-only 3MF mesh, not for a Bambu project or sliced job. However, it does not explicitly mention the sibling fab_export_stl tool or give conditions for choosing between 3MF and STL export.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fab_export_stlA
Idempotent

Write a binary STL. Dry-fire: the file is not sent to a printer.

ParametersJSON Schema
NameRequiredDescriptionDefault
part_nameYesPart name or slug.
project_idYesProject id.
output_pathNoOptional extra copy path under the part dir or FAB_EXPORT_ROOTS.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false and destructiveHint=false, but the description adds a meaningful behavioral trait: dry-fire (file is written but not sent to a printer). This goes beyond the annotations and helps the agent understand side effects. No contradiction with annotations is present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences with no waste. The primary action is front-loaded, and the dry-fire clarification is concise and directly relevant. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple, an output schema exists, and annotations cover safety and idempotency. The description covers the core behavior and dry-fire note. It lacks explicit mention of where the file is written, but the output_path parameter handles that. Minor gap on prerequisites, but overall adequate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all three parameters (part_name, project_id, output_path) are already fully documented. The description adds no extra parameter semantics, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Write' and the resource 'binary STL', which is specific and distinguishes it from other export formats like fab_export_3mf. The dry-fire clarification further disambiguates the action from sending to a printer, making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no explicit guidance on when to use this tool versus alternatives such as fab_export_3mf. The dry-fire note is a behavioral detail, not usage context. An agent must infer from the format name that this is for STL export, which is not explicitly stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fab_list_partsA
Read-only

List parts already generated in a project.

ParametersJSON Schema
NameRequiredDescriptionDefault
project_idYesId returned by fab_create_project.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The readOnlyHint annotation already declares the tool is read-only, and the description is consistent with that. The description adds the context that it lists already-generated parts, but it does not disclose anything else beyond what annotations provide, such as ordering or scope of results.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no filler. It clearly states what the tool does in minimal words, earning its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple, read-only listing operation with one required parameter and an output schema available, the description is sufficient. The annotations cover safety, and the schema covers parameter semantics, so nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema covers 100% of the single parameter, including a helpful description linking project_id to fab_create_project. The tool description itself does not add any additional meaning to the parameter, so a baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'List' and a clear resource 'parts already generated in a project,' making the tool's purpose immediately obvious. It is distinct from sibling tools like fab_create_project and fab_export_stl, which cover creation and export rather than listing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'already generated in a project' implies the tool is meant to be used after parts have been generated, and the parameter description references fab_create_project as the source of the ID. However, no explicit when-to-use or when-not-to-use guidance is given, nor are alternatives mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fab_param_modelA
Idempotent

Generate OpenSCAD and, by default, a CadQuery script from params JSON.

OpenSCAD is the primary backend. The CadQuery file is source to run later with CadQuery installed; this server does not execute it. No mesh is sent to a printer.

ParametersJSON Schema
NameRequiredDescriptionDefault
intentNoWhy this original part exists. Clone requests are refused.
paramsYesParametric model JSON. kind is box, cylinder, tube, plate, l_bracket, mount_plate, or custom_scad. Dimensions are millimeters.
backendNoopenscad (primary), cadquery (script only), or both. Default both.both
part_nameYesPart name. Stored as a filesystem slug.
project_idYesId returned by fab_create_project.
source_pathNoOptional .scad file or directory to ingest. Use cad-v0 for the bundled trainer grip set. Other paths must sit under the project directory or FAB_IMPORT_ROOTS. Relative include <> inside that root is inlined. Absolute includes, ../, use, and import() are rejected.
reproductionNooriginal, interoperable_fixture, or proprietary_clone.original

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond annotations, the description discloses important non-obvious behaviors: the CadQuery file is not executed, it is meant to be run later with CadQuery installed, and no mesh is sent to a printer. These add real context to idempotentHint=true and readOnlyHint=false. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, with the core generation action front-loaded. Every sentence earns its place: first says what it generates, second clarifies the primary backend, third clarifies execution and printer boundaries. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter tool with an output schema, the description is quite complete: it covers generation, backend default, non-execution, and a clear boundary against printing. Minor gaps include not explicitly stating that a project must already exist or that clone requests are refused, though the schema covers those details.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all 7 parameters are already documented in the input schema. The description's phrase 'params JSON' slightly reinforces that the params argument should be a JSON object, but it adds little semantic value beyond the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'Generate OpenSCAD and, by default, a CadQuery script from params JSON.' It clearly distinguishes this generation tool from export siblings by adding 'OpenSCAD is the primary backend' and 'No mesh is sent to a printer.' The purpose is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear context for how to use the tool: OpenSCAD is primary, CadQuery is a script-only output, and the server never executes it. The 'No mesh is sent to a printer' sentence implicitly tells an agent not to use this for direct fabrication. It does not explicitly name alternative sibling tools, so it misses a full 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fab_x1c_profile_notesA
Read-only

Starting nozzle, bed, fan, and drying notes for a Bambu X1 Carbon class setup.

These are notes to type into Orca or Bambu Studio. This tool does not apply a profile and does not start a print.

ParametersJSON Schema
NameRequiredDescriptionDefault
intentNoOptional context. Clone requests are refused.
materialYesPETG, ASA, TPU, or PA. PA-CF is accepted as its own note.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With readOnlyHint=true, the safety profile is already covered by annotations. The description adds valuable behavioral context: this tool returns notes for manual entry, does not apply a profile, and does not start a print. This goes beyond the annotation by clarifying the tool's offline, advisory nature.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short, front-loaded sentences. The first sentence states the resource and scope, and the second clarifies limitations. Every sentence earns its place with no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple, read-only notes tool, the description combined with the annotations, full schema coverage, and output schema provides everything an agent needs to select and invoke it correctly. It explains what the tool is for, what it is not for, and the parameter details are fully covered in the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with both 'material' and 'intent' clearly described, including material options and the clone-request refusal. The description itself adds little parameter-level meaning beyond the schema, so the baseline of 3 is appropriate given the schema already carries the burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the tool's deliverable: starting nozzle, bed, fan, and drying notes for a Bambu X1 Carbon class setup. It also distinguishes itself from other tools by explicitly stating it does not apply a profile or start a print, which sets it apart from the print/export-focused sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context on when to use the tool: when the user needs notes to type into Orca or Bambu Studio. It also provides an explicit exclusion: it does not apply a profile or start a print. It stops short of naming specific alternative tools, but the sibling list and this negative guidance make the intended use clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 8 tool updatesv0.1.0
    • First observedfab_bom_sketch
    • First observedfab_create_project
    • First observedfab_dfm_check
    • First observedfab_export_3mf
    • First observedfab_export_stl
    • First observedfab_list_parts
    • First observedfab_param_model
    • First observedfab_x1c_profile_notes

TDQS

A4/5.0

Scored across 8 tools

Disambiguation5/5

Each tool targets a distinct step in the fabrication workflow: project setup, model generation, mesh export, DFM analysis, printer notes, and BOM estimation. Even the two export tools are clearly differentiated by format and description.

Naming Consistency3/5

The fab_ prefix is consistent, and most names are readable, but conventions are mixed: list_parts, create_project, export_stl, and export_3mf follow verb_noun, while param_model, dfm_check, x1c_profile_notes, and bom_sketch are noun-oriented names. This is a noticeable pattern break, though not chaotic.

Tool Count5/5

Eight tools is well-scoped for a pre-print fabrication helper covering project setup, parametric model generation, exports, DFM checks, printer notes, and BOM sketching. Each tool has a clear role without redundancy.

Completeness4/5

The surface covers the main generation-to-export-to-check workflow well, including STL/3MF output and practical fabrication guidance. Minor gaps exist, such as no delete/update operations for projects or parts, but these are not critical for the stated dry-fire design purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Create and edit parametric 3D models with OpenSCAD. Render STL meshes and PNG previews, export SCAD, STL, CSG, and 3MF, and persist model revisions through MCP over stdio or local HTTP. Includes headless Docker support; no GPU or API keys required.
    8
    198
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI-driven 3D model generation and manipulation using OpenSCAD through natural language commands. Users can create primitives, apply transformations, perform boolean operations, and export models to various formats like STL and OBJ.
    7 npm
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Turns natural-language requests into printable Gridfinity STL/STEP files for bins, baseplates, and drawer spacers using CadQuery.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables a reviewable FreeCAD-to-Bambu Studio workflow with resumable jobs, bounded 3MF preflight, explicit review checkpoints, and LAN upload/control, including experimental guarded printing.
    MIT