bambu-printer-mcp 1.0.5 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,6 +11,37 @@ A Bambu Lab-focused MCP server for controlling Bambu printers, manipulating STL
11
11
 
12
12
  This is a stripped-down, Bambu-only fork of [mcp-3D-printer-server](https://github.com/DMontgomery40/mcp-3D-printer-server). All OctoPrint, Klipper, Duet, Repetier, Prusa Connect, and Creality Cloud support has been removed. What remains is a focused, lean implementation for Bambu Lab hardware.
13
13
 
14
+ Local handoff note: see [REMOTE-DEPLOYMENT.md](./REMOTE-DEPLOYMENT.md) for the custom H2D/H2S patches, per-printer MCP split, and remote deployment plan used in this clone.
15
+
16
+ ---
17
+
18
+ ## What's new in bambu-printer-mcp
19
+
20
+ This fork adds a substantial set of printer control tools beyond the upstream `mcp-3D-printer-server`. Everything listed below is unique to this package.
21
+
22
+ ### v1.1.0 — AMS auto-match, camera snapshot, pause/resume, skip objects
23
+
24
+ - **AMS auto-match by RFID** (`auto_match_ams` on `print_3mf`) — resolves sliced 3MF filament requirements against live AMS inventory. Handles same-SKU different-color filaments. Dry-run with `resolve_3mf_ams_slots`.
25
+ - **Structured AMS inventory** (`get_printer_filaments`) — per-tray display names, profile resolution tier (`exact-model-nozzle`/`model`/`generic`/`unresolved`), match confidence, and a summary with recommended auto-slice filament.
26
+ - **AMS settle-time retry** — transparently retries when AMS data hasn't arrived on the first MQTT push from an idle printer.
27
+ - **Camera snapshot** (`camera_snapshot`) — JPEG from the chamber camera. TCP-on-6000 for A1/P1S/P1P, RTSP via ffmpeg for X1/P2S/H2 series.
28
+ - **Pause / resume** (`pause_print`, `resume_print`) — alongside the existing `cancel_print`.
29
+ - **Skip objects** (`skip_objects`) — skip specific object IDs during a running multi-object print. IDs from `list_3mf_plate_objects`.
30
+ - **HMS diagnostics** (`printer://{host}/hms` MCP resource) — read-only error summary with automatic settle retry.
31
+ - **Utility controls** — `set_print_speed` (silent/standard/sport/ludicrous), `clear_hms_errors`, `reread_ams_rfid`, `set_airduct_mode` (cooling/heating for H2/P2).
32
+ - **H2/H2D-safe print path** — correct `project_file` format with `ams_mapping2` parallel array, H2 firmware quirks handled.
33
+ - **BambuStudio CLI auto-flatten** (`BAMBU_CLI_FLATTEN=true`) — works around upstream profile inheritance bugs.
34
+ - **Print collar charm** (`print_collar_charm`) — specialized two-color wrapper with fixed tray policy.
35
+
36
+ ### v1.1.1 — AMS dryer control (current)
37
+
38
+ - **AMS dryer start/stop** (`set_ams_drying`) — sends `print.ams_control` MQTT command. Works on heated AMS units (AMS Pro / AMS-HT). Action: `start` or `stop`, target by AMS index 0–3.
39
+ - Same-SKU different-color fix for `auto_match_ams`.
40
+ - AMS and HMS settle-time retry for idle printers.
41
+ - Validation script (`scripts/validate-printer.mjs`) for live printer testing.
42
+
43
+ > Full changelog at [CHANGELOG.md](./CHANGELOG.md).
44
+
14
45
  <details>
15
46
  <summary><strong>Click to expand Table of Contents</strong></summary>
16
47
 
@@ -31,6 +62,7 @@ This is a stripped-down, Bambu-only fork of [mcp-3D-printer-server](https://gith
31
62
  - [AMS (Automatic Material System) Setup](#ams-automatic-material-system-setup)
32
63
  - [Bambu Communication Notes (MQTT and FTP)](#bambu-communication-notes-mqtt-and-ftp)
33
64
  - [What this fork fixes](#what-this-fork-fixes)
65
+ - [Verified print procedure (H2S, LAN-only, no client cert)](#verified-print-procedure-h2s-lan-only-no-client-cert)
34
66
  - [Available Tools](#available-tools)
35
67
  - [STL Manipulation Tools](#stl-manipulation-tools)
36
68
  - [Printer Control Tools](#printer-control-tools)
@@ -51,7 +83,7 @@ This is a stripped-down, Bambu-only fork of [mcp-3D-printer-server](https://gith
51
83
 
52
84
  ## Description
53
85
 
54
- `bambu-printer-mcp` is a Model Context Protocol server that gives Claude (or any MCP client) direct control over Bambu Lab 3D printers. It handles the full workflow: manipulate an STL, auto-slice it with BambuStudio if needed, upload the resulting 3MF over FTPS, and start the print via an MQTT `project_file` command -- all without leaving your conversation.
86
+ `bambu-printer-mcp` is a Model Context Protocol server that gives Claude (or any MCP client) direct control over Bambu Lab 3D printers. The verified end-to-end path is: **slice in Bambu Studio, export a `.gcode.3mf`, hand the path to `print_3mf`** — the server reads the slicer's metadata out of the 3MF, builds the correct AMS mapping, uploads over FTPS, and starts the print via an MQTT `project_file` command. See [docs/SLICING.md](./docs/SLICING.md) for the full recipe and why in-process slicing is not the recommended path.
55
87
 
56
88
  **What this is not.** This package intentionally supports only Bambu Lab printers. It does not include adapters for OctoPrint, Klipper (Moonraker), Duet, Repetier, Prusa Connect, or Creality Cloud. If you need multi-printer support, use the parent project [mcp-3D-printer-server](https://github.com/DMontgomery40/mcp-3D-printer-server) instead.
57
89
 
@@ -64,15 +96,30 @@ This is a stripped-down, Bambu-only fork of [mcp-3D-printer-server](https://gith
64
96
  ## Features
65
97
 
66
98
  - Get detailed printer status: temperatures (nozzle, bed, chamber), print progress, current layer, time remaining, and live AMS slot data
67
- - List, upload, and manage files on the printer's SD card via FTPS
68
- - Upload and print `.3mf` files with full plate selection and calibration flag control
69
- - Automatic slicing: pass an unsliced 3MF to `print_3mf` and the server will slice it with BambuStudio CLI (or another configured slicer) before uploading
70
- - Parse AMS mapping from the 3MF's embedded slicer config (`Metadata/project_settings.config`) and send it correctly formatted per the OpenBambuAPI spec
71
- - Cancel in-progress print jobs via MQTT
99
+ - Query live AMS inventory with resolved Bambu/Orca filament profile paths via `get_printer_filaments`. Includes per-tray display names, match confidence (`high`/`medium`/`low`/`none`), resolution tier (`exact-model-nozzle`/`model`/`generic`/`unresolved`), and a summary with recommended auto-slice filament. Retries automatically when AMS data hasn't arrived yet (common on first MQTT push from idle printers).
100
+ - List, upload, and delete files on the printer's SD card via FTPS
101
+ - Capture a JPEG snapshot from the chamber camera. Supports A1, A1 mini, P1S, P1P (TCP-on-6000), and X1, X1C, X1E, P2S, H2, H2S, H2D, H2C, H2D Pro (RTSP via ffmpeg). Requires ffmpeg in PATH for the RTSP path.
102
+ - Upload and print pre-sliced `.gcode.3mf` files with full plate selection and calibration flag control (recommended path — see [docs/SLICING.md](./docs/SLICING.md))
103
+ - Optional single-color auto-slice path via BambuStudio CLI. Set `BAMBU_CLI_FLATTEN=true` to enable a workaround that flattens BBL profile inheritance before invoking the CLI — works around upstream bugs in BambuStudio CLI mode ([#9636](https://github.com/bambulab/BambuStudio/issues/9636), [#9968](https://github.com/bambulab/BambuStudio/issues/9968)). Single-color smoke is verified on H2S/H2D/X1C/P1S. H2D two-color CLI slicing is blocked upstream ([#10408](https://github.com/bambulab/BambuStudio/issues/10408)); use a GUI-sliced `.gcode.3mf` for that workflow. Default off; Path A (GUI-slice) remains the recommended workflow for non-BBL profiles, multi-color H2D jobs, or first-time prints. See [docs/SLICING.md](./docs/SLICING.md).
104
+ - Parse AMS mapping from the 3MF's embedded slicer metadata (`Metadata/plate_<n>.json` + gcode filament header) and send it correctly formatted per the OpenBambuAPI spec, with correct H2S/H2D `ams_mapping2` parallel array format
105
+ - **Auto-match AMS slots by RFID** (`auto_match_ams` flag on `print_3mf`). Resolves required `tray_info_idx` from the sliced 3MF against live AMS inventory. Handles same-SKU different-color filaments by matching on `(tray_info_idx, tray_color)` and tracking already-claimed slots. Dry-run with `resolve_3mf_ams_slots` before printing.
106
+ - Cancel, pause, and resume in-progress print jobs via MQTT
107
+ - Skip specific objects during a running multi-object print via `skip_objects` (use `list_3mf_plate_objects` to find object IDs first)
108
+ - Set print speed mode (`silent`/`standard`/`sport`/`ludicrous`), clear HMS/print errors, trigger AMS RFID re-read, and control H2/P2 airduct mode (`cooling`/`heating`) via MQTT
109
+ - **Start/stop AMS filament drying** (`set_ams_drying`) on heated AMS units (AMS Pro / AMS-HT). Sends `print.ams_control` MQTT command.
72
110
  - Set nozzle and bed temperature via G-code dispatch over MQTT
111
+ - Set fan speed (part, auxiliary, chamber) and chamber light mode (on/off/flashing) via MQTT
112
+ - Read HMS (Health Management System) diagnostics as an MCP resource at `printer://{host}/hms` — read-only error summary from the printer, with automatic settle retry
73
113
  - Start G-code files already stored on the printer
114
+ - **Collar charm print wrapper** (`print_collar_charm`) — specialized two-color workflow with fixed tray policy for inner (black, AMS 1 slot 1) and outer (white, AMS 2 slot 1) charm parts
74
115
  - STL manipulation: scale, rotate, extend base, merge vertices, center at origin, lay flat, and inspect model info
75
116
  - Slice STL or 3MF files using BambuStudio, OrcaSlicer, PrusaSlicer, Cura, or Slic3r
117
+ - Inspect slicer settings from a saved 3MF template or extracted profile via `get_slice_settings`
118
+ - Enumerate saved slicing templates from the local registry via `list_templates`
119
+ - Save templates into the local registry via `save_template`
120
+ - Slice directly from a named template via `slice_with_template`
121
+ - For simple single-material slices, auto-select the printer's current or first loaded AMS filament when no explicit slicer profile or `load_filaments` override is provided
122
+ - Template-driven slicing can reuse a saved 3MF's process settings while still pulling the live printer filament choice over MQTT
76
123
  - Optional Blender MCP bridge for advanced mesh operations
77
124
  - Dual transport: stdio (default, for Claude Desktop / Claude Code) and Streamable HTTP
78
125
 
@@ -84,13 +131,14 @@ This is a stripped-down, Bambu-only fork of [mcp-3D-printer-server](https://gith
84
131
 
85
132
  - Node.js 18 or higher
86
133
  - npm
134
+ - **BambuStudio** *(optional -- only needed for slicing)* -- [download from bambulab.com](https://bambulab.com/en/download/studio). Required by `slice_stl` and `print_3mf` auto-slice (when a 3MF has no embedded gcode). Not needed if you only print pre-sliced 3MF files. Default path: `/Applications/BambuStudio.app/Contents/MacOS/BambuStudio` (macOS); set `SLICER_PATH` if installed elsewhere.
87
135
 
88
136
  ### Run without installing (npx)
89
137
 
90
138
  The fastest way to get started. No global install required:
91
139
 
92
140
  ```bash
93
- npx bambu-printer-mcp
141
+ npx @rowbotik/bambu-printer-mcp
94
142
  ```
95
143
 
96
144
  Set environment variables inline or via a `.env` file in your working directory (see [Configuration](#configuration)).
@@ -98,7 +146,7 @@ Set environment variables inline or via a `.env` file in your working directory
98
146
  ### Install globally from npm
99
147
 
100
148
  ```bash
101
- npm install -g bambu-printer-mcp
149
+ npm install -g @rowbotik/bambu-printer-mcp
102
150
  ```
103
151
 
104
152
  After installation, the `bambu-printer-mcp` command is available in your PATH.
@@ -106,7 +154,7 @@ After installation, the `bambu-printer-mcp` command is available in your PATH.
106
154
  ### Install from source
107
155
 
108
156
  ```bash
109
- git clone https://github.com/DMontgomery40/bambu-printer-mcp.git
157
+ git clone https://github.com/rowbotik/bambu-printer-mcp.git
110
158
  cd bambu-printer-mcp
111
159
  npm install
112
160
  npm run build
@@ -126,16 +174,20 @@ Create a `.env` file in the directory where you run the server, or pass environm
126
174
  PRINTER_HOST=192.168.1.100 # IP address of your Bambu printer on the local network
127
175
  BAMBU_SERIAL=01P00A123456789 # Printer serial number (see Finding Your Serial Number below)
128
176
  BAMBU_TOKEN=your_access_token # LAN access token from printer touchscreen
177
+ # Compatible aliases also accepted:
178
+ # BAMBU_PRINTER_HOST / BAMBU_PRINTER_SERIAL / BAMBU_PRINTER_ACCESS_TOKEN
129
179
 
130
180
  # --- Printer model (CRITICAL for safe operation) ---
131
- BAMBU_MODEL=p1s # Your printer model: p1s, p1p, x1c, x1e, a1, a1mini, h2d
132
- BED_TYPE=textured_plate # Bed plate type: textured_plate, cool_plate, engineering_plate, hot_plate
181
+ BAMBU_MODEL=p1s # Your printer model: p1s, p1p, x1c, x1e, a1, a1mini, h2d, h2s
182
+ # Alias also accepted: BAMBU_PRINTER_MODEL
183
+ BED_TYPE=textured_plate # Bed plate type: textured_plate, cool_plate, engineering_plate, hot_plate, supertack_plate
133
184
  NOZZLE_DIAMETER=0.4 # Nozzle diameter in mm (default: 0.4)
134
185
 
135
186
  # --- Slicer configuration (required for slice_stl and print_3mf auto-slice) ---
136
187
  SLICER_TYPE=bambustudio # Options: bambustudio, prusaslicer, orcaslicer, cura, slic3r
137
188
  SLICER_PATH=/Applications/BambuStudio.app/Contents/MacOS/BambuStudio
138
189
  # Default on macOS. Adjust for your OS and install path.
190
+ # Alias also accepted: BAMBU_STUDIO_PATH
139
191
  SLICER_PROFILE= # Optional: path to a slicer profile/config file
140
192
 
141
193
  # --- Temporary file directory ---
@@ -160,14 +212,14 @@ BLENDER_MCP_BRIDGE_COMMAND= # Shell command to invoke your Blender MCP bri
160
212
 
161
213
  | Variable | Default | Required | Description |
162
214
  |---|---|---|---|
163
- | `PRINTER_HOST` | `localhost` | Yes | IP address of the Bambu printer |
164
- | `BAMBU_SERIAL` | | Yes | Printer serial number |
165
- | `BAMBU_TOKEN` | | Yes | LAN access token |
166
- | `BAMBU_MODEL` | | **Yes** | Printer model: `p1s`, `p1p`, `x1c`, `x1e`, `a1`, `a1mini`, `h2d`. **Required for safe operation** -- determines the correct G-code generation. If omitted and the MCP client supports elicitation, the server will ask you interactively. |
167
- | `BED_TYPE` | `textured_plate` | No | Bed plate type: `textured_plate`, `cool_plate`, `engineering_plate`, `hot_plate` |
215
+ | `PRINTER_HOST` | `localhost` | Yes | IP address of the Bambu printer. Alias: `BAMBU_PRINTER_HOST` |
216
+ | `BAMBU_SERIAL` | | Yes | Printer serial number. Alias: `BAMBU_PRINTER_SERIAL` |
217
+ | `BAMBU_TOKEN` | | Yes | LAN access token. Alias: `BAMBU_PRINTER_ACCESS_TOKEN` |
218
+ | `BAMBU_MODEL` | | **Yes** | Printer model: `p1s`, `p1p`, `x1c`, `x1e`, `a1`, `a1mini`, `h2d`, `h2s`. **Required for safe operation** -- determines the correct G-code generation. Alias: `BAMBU_PRINTER_MODEL`. If omitted and the MCP client supports elicitation, the server will ask you interactively. |
219
+ | `BED_TYPE` | `textured_plate` | No | Bed plate type: `textured_plate`, `cool_plate`, `engineering_plate`, `hot_plate`, `supertack_plate` |
168
220
  | `NOZZLE_DIAMETER` | `0.4` | No | Nozzle diameter in mm. Used to select the correct BambuStudio machine preset. |
169
221
  | `SLICER_TYPE` | `bambustudio` | No | Slicer to use for slicing operations |
170
- | `SLICER_PATH` | BambuStudio macOS path | No | Full path to the slicer executable |
222
+ | `SLICER_PATH` | BambuStudio macOS path | No | Full path to the slicer executable. Alias: `BAMBU_STUDIO_PATH` |
171
223
  | `SLICER_PROFILE` | | No | Path to a slicer profile or config file |
172
224
  | `TEMP_DIR` | `./temp` | No | Directory for intermediate files |
173
225
  | `MCP_TRANSPORT` | `stdio` | No | Transport mode: `stdio` or `streamable-http` |
@@ -178,6 +230,10 @@ BLENDER_MCP_BRIDGE_COMMAND= # Shell command to invoke your Blender MCP bri
178
230
  | `MCP_HTTP_JSON_RESPONSE` | `true` | No | Return structured JSON alongside text responses |
179
231
  | `MCP_HTTP_ALLOWED_ORIGINS` | | No | Comma-separated list of allowed CORS origins |
180
232
  | `BLENDER_MCP_BRIDGE_COMMAND` | | No | Command to invoke Blender MCP bridge |
233
+ | `BAMBU_CLI_FLATTEN` | `false` | No | When `true`, the MCP flattens BBL profile inheritance before invoking the BambuStudio CLI. Workaround for upstream issues [#9636](https://github.com/bambulab/BambuStudio/issues/9636) / [#9968](https://github.com/bambulab/BambuStudio/issues/9968). BBL printers only. Single-color smoke verified on H2S/H2D/X1C/P1S; H2D two-color CLI slicing remains blocked by [#10408](https://github.com/bambulab/BambuStudio/issues/10408). See [docs/SLICING.md](./docs/SLICING.md). |
234
+ | `BAMBU_PROFILES_ROOT` | derived from `SLICER_PATH` | No | Override path to the BambuStudio `Resources/profiles` directory used by the CLI flattener. Useful for non-standard installs or dev environments. |
235
+
236
+ SuperTack can be passed for pre-sliced print jobs, but BambuStudio CLI slicing currently fails fast for `supertack_plate` because the accepted CLI bed identifier is not verified. Use a pre-sliced 3MF for SuperTack until this is confirmed.
181
237
 
182
238
  ---
183
239
 
@@ -190,7 +246,7 @@ Add this server to your MCP client's config (Claude Desktop, Claude Code, Cursor
190
246
  "mcpServers": {
191
247
  "bambu-printer": {
192
248
  "command": "npx",
193
- "args": ["-y", "bambu-printer-mcp"],
249
+ "args": ["-y", "@rowbotik/bambu-printer-mcp"],
194
250
  "env": {
195
251
  "PRINTER_HOST": "192.168.1.100",
196
252
  "BAMBU_SERIAL": "01P00A123456789",
@@ -234,6 +290,8 @@ This applies to all MCP servers, not just this one.
234
290
 
235
291
  This MCP server communicates directly with your printer over your local network using MQTT and FTPS. For this to work, **Developer Mode** must be enabled on the printer. Without it, the printer will reject third-party LAN connections even if you have the correct access code.
236
292
 
293
+ On H2D/H2-series firmware, the printer may stream `push_status` data without ever answering the legacy `get_version` handshake used by older libraries. This fork treats the live status stream as authoritative and does not require that extra ACK before considering the connection usable.
294
+
237
295
  Developer Mode is available on the following firmware versions and later:
238
296
 
239
297
  | Series | Minimum Firmware |
@@ -378,16 +436,36 @@ If you are using the direct-feed spool holder (no AMS attached) or want to bypas
378
436
  }
379
437
  ```
380
438
 
439
+ ### Auto-match AMS by RFID
440
+
441
+ For pre-sliced 3MFs that declare filament types, the `auto_match_ams` flag on `print_3mf` (or the standalone `resolve_3mf_ams_slots` dry-run tool) automatically resolves the required filaments against your live AMS inventory. The matcher works as follows:
442
+
443
+ 1. Reads the required `tray_info_idx` values from the 3MF's `Metadata/slice_info.config` and `Metadata/plate_<n>.json`
444
+ 2. Reads your live AMS trays from the printer's MQTT status push
445
+ 3. Matches on `(tray_info_idx, tray_color)` — so two filaments of the same SKU but different colors (e.g. two GFG02 PETG HF spools in black and white) resolve to different slots
446
+ 4. Tracks already-claimed slots so two requirements can't collapse onto the same physical position
447
+ 5. Falls back to SKU-only matching when the 3MF carries no color data or only one tray of that SKU is loaded
448
+
449
+ If resolution fails, returns a structured `missing` report with per-requirement reasons:
450
+ - `no_loaded_match` — no AMS tray of that SKU is loaded
451
+ - `color_mismatch` — the SKU matches but the loaded color differs
452
+ - `exhausted` — all matching trays are already claimed by other requirements
453
+ - `no_sku` — the 3MF doesn't declare a `tray_info_idx` for this filament
454
+
455
+ Dry-run with `resolve_3mf_ams_slots` before printing to preview the match without uploading or starting a job.
456
+
457
+ ### AMS settle-time handling
458
+
459
+ The first MQTT status push from an idle printer is often sparse (model/module info only) — AMS slot data arrives on a second push. The server's filament inventory and HMS handlers both retry after a 1.5-second settle window when the expected data isn't present in the first response. This is transparent to the caller.
460
+
381
461
  ### Checking AMS status
382
462
 
383
- Use `get_printer_status` to see which filaments are currently loaded in each AMS slot, including material type and color data reported by the printer:
463
+ Use `get_printer_filaments` for the parsed, enriched view (profile paths, display names, match confidence) or `get_printer_status` for the raw AMS data from the printer:
384
464
 
385
465
  ```
386
466
  "What filaments are loaded in my AMS right now?"
387
467
  ```
388
468
 
389
- The `ams` field in the status response contains the raw AMS data from the printer, including tray information for each slot.
390
-
391
469
  ---
392
470
 
393
471
  ## Bambu Communication Notes (MQTT and FTP)
@@ -427,24 +505,91 @@ private async ftpUpload(host, token, localPath, remotePath): Promise<void> {
427
505
 
428
506
  The `bambu-js` library's project file command hardcodes `use_ams: true` and does not support the `ams_mapping` field at all. Without the fix, the mapping is a simple array of slot indices (e.g., `[0, 2]`), which does not match the OpenBambuAPI specification.
429
507
 
430
- According to the OpenBambuAPI spec, `ams_mapping` must be a 5-element array where each position corresponds to a filament color slot in the print file. Unused positions must be padded with `-1`. For example, a print using only AMS slot 0 sends `[-1, -1, -1, -1, 0]`.
508
+ According to the OpenBambuAPI spec, P1/A1/X1-series printers use a 5-element `ams_mapping` array where position `i` is the project filament index and the value is the AMS slot feeding that filament. For example, a single-filament print from AMS slot 0 sends `[0, -1, -1, -1, -1]`.
431
509
 
432
- This fork sends the `project_file` command directly via `bambu-node` (bypassing `bambu-js` entirely for print initiation) and constructs the `ams_mapping` array correctly:
510
+ This fork sends the `project_file` command directly via `bambu-node` (bypassing `bambu-js` entirely for print initiation) and constructs the mapping in the format the target firmware expects:
433
511
 
434
512
  ```typescript
435
- // From src/printers/bambu.ts
436
- let amsMapping: number[];
437
- if (options.amsMapping && options.amsMapping.length > 0) {
438
- amsMapping = Array.from({ length: 5 }, (_, i) =>
439
- i < options.amsMapping!.length ? options.amsMapping![i] : -1
440
- );
441
- } else {
442
- amsMapping = [-1, -1, -1, -1, 0]; // default: slot 0 only
443
- }
513
+ // P1/A1/X1-series: 5-element project lookup table
514
+ ams_mapping = [0, -1, -1, -1, -1];
515
+
516
+ // H2S/H2D: project-length lookup table + parallel ams_mapping2
517
+ ams_mapping = [-1, 1, -1, -1];
518
+ ams_mapping2 = [
519
+ { ams_id: 255, slot_id: 255 },
520
+ { ams_id: 0, slot_id: 1 },
521
+ { ams_id: 255, slot_id: 255 },
522
+ { ams_id: 255, slot_id: 255 }
523
+ ];
444
524
  ```
445
525
 
446
526
  The command payload also includes all required fields per the OpenBambuAPI spec: `param` (the internal gcode path within the 3MF), `url` (the sdcard path), `md5` (computed from the plate's embedded gcode), and all calibration flags.
447
527
 
528
+ ### Verified print procedure (H2S, LAN-only, no client cert)
529
+
530
+ This is the sequence that successfully started a print on an H2S running current (post-Jan 2025) firmware in LAN-only mode. It's documented here because several common approaches fail on this firmware, and this fork's transport is what makes it reliable.
531
+
532
+ **Result:** print started in `RUNNING` state, printer accepted the MQTT `project_file` command, no client certificate was required. Authentication was plain `bblp` + LAN access code over TLS with `rejectUnauthorized: false`.
533
+
534
+ **What doesn't work on stock bambu-cli:**
535
+
536
+ - `bambu-cli print start <file>` and `bambu-cli files upload` both fail with `522 SSL connection failed: session reuse required`. Bambu's FTPS server requires TLS session reuse between the control and data channels, which the Go FTPS client in bambu-cli does not negotiate correctly.
537
+ - `bambu-cli print start --no-upload` still opens an FTPS session (to stat the remote file) and hits the same 522.
538
+
539
+ **What works — two-step upload + MQTT dispatch:**
540
+
541
+ 1. **Upload the `.gcode.3mf` via curl** (curl's OpenSSL backend negotiates FTPS session reuse correctly):
542
+
543
+ ```bash
544
+ curl -k --ftp-pasv --ssl-reqd \
545
+ -u "bblp:<ACCESS_CODE>" \
546
+ -T /path/to/file.gcode.3mf \
547
+ "ftps://<PRINTER_IP>:990/<remote-name>.gcode.3mf"
548
+ ```
549
+
550
+ Keep `<remote-name>` simple ASCII, ending in `.gcode.3mf`. The file lands at the FTP root, which corresponds to `/data/` on the printer's SD card.
551
+
552
+ 2. **Send the `project_file` command over MQTT** to `device/<SERIAL>/request`:
553
+
554
+ ```js
555
+ import mqtt from "mqtt";
556
+ const payload = {
557
+ print: {
558
+ sequence_id: "0",
559
+ command: "project_file",
560
+ param: "Metadata/plate_1.gcode", // path inside the 3MF
561
+ subtask_name: "<remote-name>.gcode.3mf",
562
+ file: "<remote-name>.gcode.3mf",
563
+ url: "ftp:///<remote-name>.gcode.3mf", // three slashes, FTP root
564
+ md5: "",
565
+ project_id: "0", profile_id: "0", task_id: "0", subtask_id: "0",
566
+ timelapse: false,
567
+ bed_type: "auto",
568
+ bed_leveling: true, bed_levelling: true,
569
+ flow_cali: true, vibration_cali: true, layer_inspect: true,
570
+ use_ams: true,
571
+ ams_mapping: [0, -1, -1, -1, -1]
572
+ }
573
+ };
574
+ const client = mqtt.connect(`mqtts://<PRINTER_IP>:8883`, {
575
+ username: "bblp",
576
+ password: "<ACCESS_CODE>",
577
+ rejectUnauthorized: false,
578
+ });
579
+ client.on("connect", () => {
580
+ client.publish(`device/<SERIAL>/request`, JSON.stringify(payload));
581
+ });
582
+ ```
583
+
584
+ **Notes:**
585
+
586
+ - `url` must be `ftp:///<filename>` (three slashes) — the empty host component is required; the printer rejects `ftp://<filename>` as "unsupported print file path or name".
587
+ - `param` uses the internal plate path inside the 3MF (`Metadata/plate_1.gcode` for plate 1), not a filesystem path.
588
+ - `md5: ""` is accepted; populating it is optional.
589
+ - On AMS-equipped H2 printers, `use_ams: false` does not suppress mapping lookup if the sliced file declares filaments. The working H2 path is to send `use_ams: true` plus a valid mapping. For H2, the mapping length must match the project-level filament declaration length, and the populated positions must match `plate_<n>.json.filament_ids`. Prefer `ams_slots` at the tool layer and let the server expand it. If no mapping is provided for an H2 pre-sliced job with declared filaments, the server fails before sending; pass explicit `ams_slots`, raw `ams_mapping`, or `auto_match_ams: true`.
590
+ - No client X.509 certificate was needed. The earlier assumption that post-Jan 2025 firmware mandates mTLS on all models does not hold for the H2S in LAN mode — user/password over TLS is sufficient.
591
+ - The MCP server's `ftpUpload` helper (basic-ftp with `secure: "implicit"` and a short idle timeout) performs the equivalent upload natively and is the preferred path when using the server itself; the curl form is the manual-debug equivalent.
592
+
448
593
  ---
449
594
 
450
595
  ## Available Tools
@@ -560,6 +705,8 @@ Note: this works best on models with a clearly dominant flat face. Results on or
560
705
 
561
706
  All printer tools accept optional `host`, `bambu_serial`, and `bambu_token` arguments. If omitted, values fall back to the environment variables `PRINTER_HOST`, `BAMBU_SERIAL`, and `BAMBU_TOKEN`. Passing them explicitly is useful when working with more than one printer.
562
707
 
708
+ The server also accepts the alias variables `BAMBU_PRINTER_HOST`, `BAMBU_PRINTER_SERIAL`, and `BAMBU_PRINTER_ACCESS_TOKEN`, plus `BAMBU_PRINTER_MODEL` and `BAMBU_STUDIO_PATH`.
709
+
563
710
  #### get_printer_status
564
711
 
565
712
  Retrieve current printer state including temperatures, print progress, layer count, time remaining, and AMS slot data. Internally sends a `push_all` MQTT command to force a fresh status report before reading cached state.
@@ -574,6 +721,35 @@ Retrieve current printer state including temperatures, print progress, layer cou
574
721
 
575
722
  Returns a structured object with fields including `status` (gcode_state string), `temperatures.nozzle`, `temperatures.bed`, `temperatures.chamber`, `print.progress`, `print.currentLayer`, `print.totalLayers`, `print.timeRemaining`, and `ams` (raw AMS data from the printer).
576
723
 
724
+ #### get_printer_filaments
725
+
726
+ Read the live AMS inventory and resolve each loaded tray to Bambu Studio
727
+ filament profile JSON paths when `bambu_model` is known. The result includes a
728
+ summary, per-slot display labels, profile match confidence, and a recommended
729
+ `load_filaments` value for simple single-material CLI slicing.
730
+
731
+ ```json
732
+ {
733
+ "bambu_model": "h2d",
734
+ "nozzle_diameter": "0.4",
735
+ "host": "192.168.1.100",
736
+ "bambu_serial": "094...",
737
+ "bambu_token": "your_access_token"
738
+ }
739
+ ```
740
+
741
+ High-signal fields:
742
+
743
+ - `summary.loaded_slots`, `summary.resolved_profile_slots`,
744
+ `summary.unresolved_loaded_slots`, `summary.empty_slots`
745
+ - `trays[].display_name`, `trays[].tray_color`, `trays[].remain_percent`
746
+ - `trays[].resolved_profile_path`
747
+ - `trays[].profile_resolution`: `exact-model-nozzle`, `model`, `generic`, or
748
+ `unresolved`
749
+ - `trays[].match_confidence`: `high`, `medium`, `low`, or `none`
750
+ - `recommended.load_filaments`: the profile path the MCP will use for
751
+ auto-slicing when no explicit filament override is provided
752
+
577
753
  #### list_printer_files
578
754
 
579
755
  List files stored on the printer's SD card. Scans the `cache/`, `timelapse/`, and `logs/` directories and returns both a flat list and a directory-grouped breakdown.
@@ -586,6 +762,51 @@ List files stored on the printer's SD card. Scans the `cache/`, `timelapse/`, an
586
762
  }
587
763
  ```
588
764
 
765
+ #### camera_snapshot
766
+
767
+ Capture a single JPEG frame from the printer's chamber camera. Read-only.
768
+
769
+ Two transports are wired in, picked by `bambu_model`:
770
+
771
+ - **TCP-on-6000** for **A1, A1 mini, P1S, P1P**. Native protocol per [OpenBambuAPI/video.md](https://github.com/Doridian/OpenBambuAPI/blob/main/video.md): TLS on port 6000, 80-byte auth packet (`bblp` + access token), repeating 16-byte frame header + JPEG payload.
772
+ - **RTSP** for **X1, X1 Carbon, X1E, P2S** and **H2, H2S, H2D, H2C, H2D Pro**. Shells out to ffmpeg with `rtsps://bblp:<token>@<host>:322/streaming/live/1 -frames:v 1`. The H2 series wasn't documented in OpenBambuAPI's `video.md` but its firmware uses the same RTSP endpoint as X1 (verified live against an H2S, 2026-04-27).
773
+
774
+ **Requires ffmpeg in PATH** for the RTSP path. Install with `brew install ffmpeg` on macOS. Override the binary location with the `ffmpeg_path` tool argument if it lives elsewhere. The TCP-on-6000 path uses native Node TLS and does not require ffmpeg.
775
+
776
+ ```json
777
+ {
778
+ "save_path": "/tmp/snap.jpg",
779
+ "timeout_ms": 8000,
780
+ "bambu_model": "h2s",
781
+ "host": "192.168.1.100",
782
+ "bambu_serial": "01P00A123456789",
783
+ "bambu_token": "your_access_token"
784
+ }
785
+ ```
786
+
787
+ Returns `{ status, format: "image/jpeg", sizeBytes, base64, savedTo?, transport }`. `transport` is `"tcp-6000"` or `"rtsps-322"` so callers can tell which path produced the frame. Pass `save_path` to also write the bytes to disk; otherwise only the base64 payload is returned.
788
+
789
+ #### delete_printer_file
790
+
791
+ Delete a single file from the printer's SD card via FTPS. **Destructive.** Requires `confirm: true` — without it the call returns `status: "skipped"` and does not contact the printer. Path traversal segments (`..`) are rejected. Only files under `cache/`, `timelapse/`, and `logs/` can be deleted.
792
+
793
+ ```json
794
+ {
795
+ "filename": "old_print.gcode.3mf",
796
+ "confirm": true,
797
+ "host": "192.168.1.100",
798
+ "bambu_serial": "01P00A123456789",
799
+ "bambu_token": "your_access_token"
800
+ }
801
+ ```
802
+
803
+ A bare filename defaults to `cache/<filename>`. To target other directories pass a relative path:
804
+
805
+ ```json
806
+ { "filename": "timelapse/2026-04-26_12-00.mp4", "confirm": true }
807
+ { "filename": "logs/printer.log", "confirm": true }
808
+ ```
809
+
589
810
  #### upload_gcode
590
811
 
591
812
  Write G-code content from a string directly to the printer's `cache/` directory. The content is written to a temporary file and uploaded via FTPS.
@@ -632,10 +853,86 @@ If `filename` does not include a directory prefix, the server prepends `cache/`
632
853
 
633
854
  #### cancel_print
634
855
 
635
- Cancel the currently running print job. Sends an `UpdateState` MQTT command with `state: "stop"`.
856
+ Cancel the currently running print job. Sends an `UpdateState` MQTT command with `state: "stop"`. Not resumable — use `pause_print` if you may want to continue.
857
+
858
+ ```json
859
+ {
860
+ "host": "192.168.1.100",
861
+ "bambu_serial": "01P00A123456789",
862
+ "bambu_token": "your_access_token"
863
+ }
864
+ ```
865
+
866
+ #### pause_print
867
+
868
+ Pause the currently running print job. Sends an `UpdateState` MQTT command with `state: "pause"`. Resumable via `resume_print`.
869
+
870
+ ```json
871
+ {
872
+ "host": "192.168.1.100",
873
+ "bambu_serial": "01P00A123456789",
874
+ "bambu_token": "your_access_token"
875
+ }
876
+ ```
877
+
878
+ #### resume_print
879
+
880
+ Resume a paused print job. Sends an `UpdateState` MQTT command with `state: "resume"`.
881
+
882
+ ```json
883
+ {
884
+ "host": "192.168.1.100",
885
+ "bambu_serial": "01P00A123456789",
886
+ "bambu_token": "your_access_token"
887
+ }
888
+ ```
889
+
890
+ #### clear_hms_errors
891
+
892
+ Clear HMS or print error state on the printer. Sends Bambu's `clean_print_error` MQTT command.
893
+
894
+ ```json
895
+ {
896
+ "host": "192.168.1.100",
897
+ "bambu_serial": "01P00A123456789",
898
+ "bambu_token": "your_access_token"
899
+ }
900
+ ```
901
+
902
+ #### set_print_speed
903
+
904
+ Set the active print speed mode. Accepted `mode` values are `silent`, `standard`, `sport`, `ludicrous`, or their numeric equivalents `1`, `2`, `3`, and `4`.
905
+
906
+ ```json
907
+ {
908
+ "mode": "sport",
909
+ "host": "192.168.1.100",
910
+ "bambu_serial": "01P00A123456789",
911
+ "bambu_token": "your_access_token"
912
+ }
913
+ ```
914
+
915
+ #### set_airduct_mode
916
+
917
+ Set H2/P2 airduct mode to `cooling` or `heating`. This is intended for supported printers only.
636
918
 
637
919
  ```json
638
920
  {
921
+ "mode": "cooling",
922
+ "host": "192.168.1.100",
923
+ "bambu_serial": "01P00A123456789",
924
+ "bambu_token": "your_access_token"
925
+ }
926
+ ```
927
+
928
+ #### reread_ams_rfid
929
+
930
+ Trigger a Bambu AMS RFID re-read for one AMS slot. This can move AMS filament; use it only when the printer is idle and unloaded.
931
+
932
+ ```json
933
+ {
934
+ "ams_id": 0,
935
+ "slot_id": 1,
639
936
  "host": "192.168.1.100",
640
937
  "bambu_serial": "01P00A123456789",
641
938
  "bambu_token": "your_access_token"
@@ -656,16 +953,80 @@ Set the target temperature for the bed or nozzle. Dispatches an M140 (bed) or M1
656
953
  }
657
954
  ```
658
955
 
956
+ #### set_fan_speed
957
+
958
+ Set a printer fan speed from 0 to 100 percent. Accepted `fan` values are `part`, `auxiliary`, `chamber`, `1`, `2`, and `3`.
959
+
960
+ ```json
961
+ {
962
+ "fan": "chamber",
963
+ "speed": 40,
964
+ "host": "192.168.1.100",
965
+ "bambu_serial": "01P00A123456789",
966
+ "bambu_token": "your_access_token"
967
+ }
968
+ ```
969
+
970
+ #### set_light
971
+
972
+ Set a printer light node mode. Common Bambu firmware reports the chamber light as `chamber_light`; valid modes are `on`, `off`, and `flashing`.
973
+
974
+ ```json
975
+ {
976
+ "light": "chamber_light",
977
+ "mode": "on",
978
+ "host": "192.168.1.100",
979
+ "bambu_serial": "01P00A123456789",
980
+ "bambu_token": "your_access_token"
981
+ }
982
+ ```
983
+
984
+ #### skip_objects
985
+
986
+ Skip specific object IDs during a running multi-object print. Use `list_3mf_plate_objects` on the sliced 3MF to find the IDs first.
987
+
988
+ ```json
989
+ {
990
+ "object_ids": [6495, 6496],
991
+ "host": "192.168.1.100",
992
+ "bambu_serial": "01P00A123456789",
993
+ "bambu_token": "your_access_token"
994
+ }
995
+ ```
996
+
997
+ #### set_ams_drying
998
+
999
+ Start or stop the AMS filament drying cycle on heated AMS units (AMS Pro / AMS-HT). The `action` parameter accepts `start` or `stop`. The `ams_id` must be an integer from 0 to 3.
1000
+
1001
+ ```json
1002
+ {
1003
+ "action": "start",
1004
+ "ams_id": 0,
1005
+ "host": "192.168.1.100",
1006
+ "bambu_serial": "01P00A123456789",
1007
+ "bambu_token": "your_access_token"
1008
+ }
1009
+ ```
1010
+
1011
+ To stop drying:
1012
+
1013
+ ```json
1014
+ {
1015
+ "action": "stop",
1016
+ "ams_id": 0
1017
+ }
1018
+ ```
1019
+
659
1020
  #### print_3mf
660
1021
 
661
- The primary tool for starting a Bambu print. This tool handles the complete workflow:
1022
+ The primary tool for starting a Bambu print. **Recommended input: a pre-sliced `.gcode.3mf` exported from Bambu Studio** — see [docs/SLICING.md](./docs/SLICING.md). This tool handles the complete workflow:
662
1023
 
663
1024
  1. Checks whether the 3MF contains embedded G-code (`Metadata/plate_<n>.gcode` entries).
664
- 2. If no G-code is found, automatically slices the file using the configured slicer before proceeding.
1025
+ 2. If no G-code is found, attempts to auto-slice via the configured slicer. This fallback is unreliable in practice (stale profiles, leftover multi-filament declarations) — prefer pre-slicing in Bambu Studio.
665
1026
  3. Parses the sliced 3MF to extract the correct plate file and compute its MD5 hash.
666
1027
  4. Also parses `Metadata/project_settings.config` to read AMS mapping embedded by Bambu Studio.
667
1028
  5. Uploads the 3MF to the printer's `cache/` directory via FTPS using `basic-ftp` directly (avoiding the bambu-js double-path bug).
668
- 6. Sends a `project_file` MQTT command with the plate path, MD5, AMS mapping (formatted as a 5-element array per the OpenBambuAPI spec), and calibration flags.
1029
+ 6. Sends the correct MQTT print command for the target printer family. For H2S/H2D that means `project_file` with project-length `ams_mapping`, parallel `ams_mapping2`, and H2-compatible calibration flags.
669
1030
 
670
1031
  ```json
671
1032
  {
@@ -686,10 +1047,77 @@ The primary tool for starting a Bambu print. This tool handles the complete work
686
1047
 
687
1048
  `bambu_model` is **required** -- it ensures the slicer generates G-code for the correct printer. Using the wrong model can cause the bed to crash into the nozzle. If `bambu_model` is not provided in the tool call and `BAMBU_MODEL` is not set in the environment, the server will ask you interactively via MCP elicitation (if your client supports it) or return a clear error.
688
1049
 
689
- `bed_type` defaults to `textured_plate` if omitted. AMS mapping from the 3MF's slicer config is used automatically when present; the `ams_mapping` argument overrides it. Setting `use_ams: false` disables AMS entirely regardless of other mapping values.
1050
+ `bed_type` defaults to `textured_plate` if omitted. `ams_slots` is the preferred override input; `ams_mapping` remains the raw escape hatch. On AMS-equipped H2 printers, `use_ams: false` does not suppress mapping lookup if the sliced file declares filaments. If no mapping is provided for an H2 pre-sliced job with declared filaments, the server fails before sending; pass explicit `ams_slots`, raw `ams_mapping`, or `auto_match_ams: true`.
1051
+
1052
+ Set `auto_match_ams: true` to match the sliced 3MF's `tray_info_idx` values against the live AMS inventory and use the matching `ams_slots`. The matcher joins on `(tray_info_idx, tray_color)` and tracks already-claimed slots, so prints with two filaments of the same SKU but different colors (e.g. two GFG02 PETG HF in black and white) resolve correctly. Falls back to SKU-only when the 3MF's filament has no color set or only one tray of that SKU is loaded. Returns a structured `missing` report (`reason: "no_loaded_match" | "color_mismatch" | "exhausted" | "no_sku"`) when a filament can't be resolved. Ignored when you provide `ams_slots` or `ams_mapping` explicitly.
690
1053
 
691
1054
  Layer height, nozzle temperature, and other slicer parameters cannot be overridden via this tool -- they are baked into the 3MF's G-code at slice time. Apply those settings in your slicer before generating the 3MF.
692
1055
 
1056
+ #### resolve_3mf_ams_slots
1057
+
1058
+ Dry-run the AMS match without uploading or starting a print. The tool reads `Metadata/plate_<n>.json` and `Metadata/slice_info.config`, then compares required `tray_info_idx` values against live AMS trays.
1059
+
1060
+ ```json
1061
+ {
1062
+ "three_mf_path": "/Users/yourname/Downloads/bracket.gcode.3mf",
1063
+ "bambu_model": "h2d",
1064
+ "host": "192.168.1.100",
1065
+ "bambu_serial": "094...",
1066
+ "bambu_token": "your_access_token"
1067
+ }
1068
+ ```
1069
+
1070
+ #### list_3mf_plate_objects
1071
+
1072
+ List object IDs from a sliced 3MF plate. Use this before `skip_objects` so you pass real Bambu object IDs instead of display-order guesses.
1073
+
1074
+ ```json
1075
+ {
1076
+ "three_mf_path": "/Users/yourname/Downloads/bracket.gcode.3mf",
1077
+ "plate_index": 0
1078
+ }
1079
+ ```
1080
+
1081
+ #### print_collar_charm
1082
+
1083
+ High-level wrapper for a prepared two-part dog-collar-charm workflow. This tool is intentionally specialized: it expects a prepared two-part charm project and applies a fixed tray policy.
1084
+
1085
+ - Smaller inner object -> black -> AMS 1 slot 1
1086
+ - Larger outer object -> white -> AMS 2 slot 1
1087
+
1088
+ The tool will:
1089
+
1090
+ 1. Resolve a local `.3mf` or `template_name`.
1091
+ 2. Auto-slice if the 3MF is still an unsliced project.
1092
+ 3. Inspect `Metadata/plate_1.json` to identify the smaller inner part and larger outer part.
1093
+ 4. Preflight the required AMS trays on the printer.
1094
+ 5. Dispatch the print through the existing H2-safe `print3mf` path using `ams_slots`.
1095
+
1096
+ ```json
1097
+ {
1098
+ "template_name": "collars/letter_charm_a",
1099
+ "bambu_model": "h2d",
1100
+ "host": "192.168.1.100",
1101
+ "bambu_serial": "03W09C123456789",
1102
+ "bambu_token": "your_access_token",
1103
+ "bed_leveling": true,
1104
+ "flow_calibration": true,
1105
+ "vibration_calibration": true,
1106
+ "timelapse": false
1107
+ }
1108
+ ```
1109
+
1110
+ You can also pass `source_path` directly instead of `template_name`.
1111
+
1112
+ This wrapper currently assumes:
1113
+
1114
+ - the input is a prepared two-part charm `.3mf`, not a bare STL that needs color-region generation
1115
+ - the selected plate has exactly 2 objects
1116
+ - the selected plate has exactly 2 used filament positions
1117
+ - the smaller object is the inner insert/letter and the larger object is the outer body
1118
+
1119
+ If the project does not match those assumptions, the tool fails fast with a structured error instead of guessing. The role-to-color and color-to-tray mapping is isolated in code so the next version can evolve toward customer-requested colors without replacing the whole wrapper.
1120
+
693
1121
  </details>
694
1122
 
695
1123
  <details>
@@ -697,6 +1125,57 @@ Layer height, nozzle temperature, and other slicer parameters cannot be overridd
697
1125
 
698
1126
  ### Slicing Tools
699
1127
 
1128
+ > **Note:** the verified workflow is to slice in Bambu Studio (GUI) and feed the resulting `.gcode.3mf` to `print_3mf`. The CLI-driven slicing tools below (`slice_stl`, `slice_with_template`) work but are sensitive to profile drift and are not the recommended path for production prints. See [docs/SLICING.md](./docs/SLICING.md).
1129
+
1130
+ #### list_templates
1131
+
1132
+ List saved templates from the local registry directory. You can override the registry root with `BAMBU_TEMPLATE_DIR`.
1133
+
1134
+ ```json
1135
+ {}
1136
+ ```
1137
+
1138
+ Each result includes the template `name`, absolute `path`, source type, and relative path inside the registry. You can then pass `template_name` to `get_slice_settings`, `slice_stl`, or `print_3mf` instead of a raw path.
1139
+
1140
+ #### save_template
1141
+
1142
+ Copy a local `3mf`, `json`, or `.config` file into the template registry and register it under a reusable template name.
1143
+
1144
+ ```json
1145
+ {
1146
+ "source_path": "/path/to/sliced_project.3mf",
1147
+ "template_name": "collars/p1p_petg_default"
1148
+ }
1149
+ ```
1150
+
1151
+ This creates the destination under the template registry directory and makes it available immediately to `list_templates`, `get_slice_settings`, `slice_with_template`, `slice_stl`, and `print_3mf`.
1152
+
1153
+ #### get_slice_settings
1154
+
1155
+ Inspect the slicer settings embedded in a saved 3MF template or in an extracted JSON/config profile without slicing anything.
1156
+
1157
+ ```json
1158
+ {
1159
+ "template_name": "h2s_template"
1160
+ }
1161
+ ```
1162
+
1163
+ This returns a compact summary of the high-signal settings such as printer preset, default print profile, filament profiles, layer height, infill density, shell counts, support mode, and bed type. It accepts either `source_path` or `template_name`. For 3MF inputs it also writes the extracted settings blob to a temp path so the result can be reused directly.
1164
+
1165
+ #### slice_with_template
1166
+
1167
+ Slice an STL or 3MF using a named template from the local registry. This is a higher-level wrapper over `slice_stl` for template-based workflows.
1168
+
1169
+ ```json
1170
+ {
1171
+ "stl_path": "/path/to/model.stl",
1172
+ "template_name": "collars/p1p_petg_default",
1173
+ "bambu_model": "p1p"
1174
+ }
1175
+ ```
1176
+
1177
+ This uses the named template as the slicing profile source and still supports live printer filament selection unless you explicitly override `load_filaments`. The template settings are applied at slice time, and the later `print_3mf` step computes H2-safe AMS mapping from the newly sliced output.
1178
+
700
1179
  #### slice_stl
701
1180
 
702
1181
  Slice an STL or 3MF file using an external slicer and return the path to the output file. The output is a sliced 3MF (for BambuStudio and OrcaSlicer) or a G-code file (for PrusaSlicer, Cura, Slic3r).
@@ -714,6 +1193,8 @@ Slice an STL or 3MF file using an external slicer and return the path to the out
714
1193
 
715
1194
  `slicer_path` and `slicer_profile` fall back to the `SLICER_PATH` and `SLICER_PROFILE` environment variables when omitted.
716
1195
 
1196
+ You can provide either `template_3mf_path` or `template_name` when you want to slice from a saved template. `template_name` resolves through the local template registry directory configured for the server.
1197
+
717
1198
  For printing on a Bambu printer, the recommended workflow is: slice with `bambustudio` to get a sliced 3MF, then pass that output path to `print_3mf`.
718
1199
 
719
1200
  #### BambuStudio Slicer Options
@@ -809,6 +1290,8 @@ Resources follow the MCP resource protocol and can be read by calling `ReadResou
809
1290
 
810
1291
  - `printer://{host}/files` -- File listing for the printer's SD card. Equivalent to calling `list_printer_files`. Returns files grouped by directory.
811
1292
 
1293
+ - `printer://{host}/hms` -- HMS and error diagnostics from the latest status payload. Returns connection state, printer status, explicit HMS payloads when present, and shallow raw fields whose names indicate errors, failures, warnings, or HMS data.
1294
+
812
1295
  **Example:** To read the status of the default printer, use URI `printer://192.168.1.100/status`. The host segment must match a configured printer IP; the server uses `PRINTER_HOST` if the default URI template is used.
813
1296
 
814
1297
  ---
@@ -825,6 +1308,18 @@ After connecting the MCP server in Claude Desktop or Claude Code, you can ask Cl
825
1308
  - "Cancel the current print job."
826
1309
  - "Set the nozzle temperature to 220 degrees."
827
1310
  - "Set the bed to 65 degrees."
1311
+ - "Turn the chamber light on."
1312
+ - "Set the chamber fan to 40 percent."
1313
+ - "List the object IDs in this sliced 3MF."
1314
+ - "Skip object 6495 on the current print."
1315
+ - "Start the AMS drying cycle on AMS 0."
1316
+ - "Stop drying on AMS 1."
1317
+ - "Match the AMS slots for this 3MF against my loaded filaments without printing."
1318
+ - "Auto-match AMS slots and print this 3MF."
1319
+ - "Take a camera snapshot of the print bed."
1320
+ - "Show me the HMS error codes on the printer."
1321
+ - "What speed mode is the printer in?"
1322
+ - "Set the airduct to cooling mode."
828
1323
 
829
1324
  ### Printing 3MF files
830
1325
 
@@ -857,7 +1352,7 @@ After connecting the MCP server in Claude Desktop or Claude Code, you can ask Cl
857
1352
 
858
1353
  Understanding these constraints will help you avoid frustrating errors and set appropriate expectations.
859
1354
 
860
- 1. **Printable 3MF required for print_3mf.** The `print_3mf` tool expects a sliced 3MF containing at least one `Metadata/plate_<n>.gcode` entry. If you pass an unsliced 3MF (one exported from a CAD tool without slicing), the server will attempt to auto-slice it using the configured slicer. If auto-slicing fails, the tool errors out rather than sending an incomplete command to the printer.
1355
+ 1. **Printable 3MF required for print_3mf.** The `print_3mf` tool expects a sliced 3MF containing at least one `Metadata/plate_<n>.gcode` entry. If you pass an unsliced 3MF (one exported from a CAD tool without slicing), the server will attempt to auto-slice it using the configured slicer — but this fallback is brittle and the recommended workflow is to pre-slice in Bambu Studio and pass the resulting `.gcode.3mf`. See [docs/SLICING.md](./docs/SLICING.md) for the full procedure.
861
1356
 
862
1357
  2. **Layer height, temperature, and slicer settings are baked in.** The `project_file` MQTT command tells the printer which plate to run. It does not support overriding layer height, temperature targets, infill percentage, or other slicing parameters at print time. These must be set in your slicer before generating the 3MF.
863
1358
 
@@ -904,3 +1399,7 @@ STL manipulation tools load the entire mesh into memory as Three.js geometry. Fo
904
1399
  GPL-2.0. See [LICENSE](./LICENSE) for the full text.
905
1400
 
906
1401
  This project is a fork of [mcp-3D-printer-server](https://github.com/DMontgomery40/mcp-3D-printer-server) by David Montgomery, also GPL-2.0.
1402
+
1403
+ ## Acknowledgements
1404
+
1405
+ Some printer command surfaces and workflow priorities were informed by [Bambuddy](https://github.com/maziggy/bambuddy), an AGPL-3.0 Bambu Lab printer management project. This project does not vendor Bambuddy code.