mcp-3d-printer-server 1.2.20 → 1.2.21
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/CHANGELOG.md +21 -0
- package/README.md +112 -9
- package/dist/blender-mcp-bridge.d.ts +21 -0
- package/dist/blender-mcp-bridge.js +3 -3
- package/dist/counterpart/contract.d.ts +395 -0
- package/dist/counterpart/contract.js +220 -0
- package/dist/counterpart/progress.d.ts +32 -0
- package/dist/counterpart/progress.js +443 -0
- package/dist/counterpart/service.d.ts +56 -0
- package/dist/counterpart/service.js +224 -0
- package/dist/fusion-mcp-bridge.d.ts +166 -0
- package/dist/fusion-mcp-bridge.js +529 -0
- package/dist/index.js +272 -8
- package/dist/printers/creality.d.ts +26 -1
- package/dist/printers/creality.js +75 -2
- package/dist/printers/duet.d.ts +16 -0
- package/dist/printers/duet.js +64 -0
- package/dist/printers/generic-base.d.ts +52 -6
- package/dist/printers/generic-base.js +134 -7
- package/dist/printers/klipper.d.ts +33 -2
- package/dist/printers/klipper.js +106 -0
- package/dist/printers/octoprint.d.ts +23 -1
- package/dist/printers/octoprint.js +81 -0
- package/dist/printers/prusa.d.ts +13 -0
- package/dist/printers/prusa.js +59 -0
- package/dist/printers/repetier.d.ts +17 -1
- package/dist/printers/repetier.js +55 -0
- package/dist/slicer/bambu-cli.d.ts +2 -0
- package/dist/slicer/bambu-cli.js +11 -0
- package/dist/slicer/filament-profiles.d.ts +25 -0
- package/dist/slicer/filament-profiles.js +249 -0
- package/dist/stl/stl-manipulator.d.ts +21 -1
- package/dist/stl/stl-manipulator.js +86 -6
- package/package.json +7 -2
- package/server.json +2 -2
- package/src/blender-mcp-bridge.ts +3 -3
- package/src/counterpart/contract.ts +326 -0
- package/src/counterpart/progress.ts +470 -0
- package/src/counterpart/service.ts +247 -0
- package/src/fusion-mcp-bridge.ts +512 -0
- package/src/index.ts +314 -10
- package/src/printers/creality.ts +84 -1
- package/src/printers/duet.ts +67 -0
- package/src/printers/generic-base.ts +172 -1
- package/src/printers/klipper.ts +118 -2
- package/src/printers/octoprint.ts +86 -1
- package/src/printers/prusa.ts +60 -0
- package/src/printers/repetier.ts +63 -1
- package/src/slicer/bambu-cli.ts +13 -0
- package/src/slicer/filament-profiles.ts +249 -0
- package/src/stl/stl-manipulator.ts +100 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.2.21] – 2026-11-02
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Add the `counterpart/1` tools that bambu-printer-mcp also implements, so one client can watch and control either server: `counterpart_printer_info` (server, printer identity and detected capabilities), `counterpart_print_progress` (one state, job, progress, time, layer, temperature and problem shape per firmware), `camera_snapshot` (bambu-printer-mcp's arguments and result plus `capturedAt`), `get_printer_filaments` (one external slot, with Spoolman through Moonraker), `pause_print` and `resume_print`. Each declares an `outputSchema` and returns `structuredContent` plus the same JSON as text; their errors carry text only, because MCP clients validate structured content against the schema even on errors.
|
|
8
|
+
- Pause is never gated. Resume reheats and moves the printer, so it is gated like a print start. It resumes only the job this server instance inspected and started, after a fresh report that the same job is paused, and after a person confirms through MCP elicitation (unless the server sets `PRINT_REQUIRE_CONFIRMATION=0`). OctoPrint, Klipper and Duet re-download the file and compare its SHA-256 with the inspected bytes before asking; PrusaLink, Repetier and Creality have no download route here, so the job is matched by name only. The printer is read again after the confirmation. Cancelling the job, or a report that it ended, retires it, so a later job that reuses the name is never resumed. A stop or heater-off request cancels a pending resume. A job started elsewhere, or before a restart, is refused. OctoPrint drops a resume sent while it is still pausing, so transitional states are reported as `job.stage` and resume waits for a settled pause.
|
|
9
|
+
- `upload_gcode` and `start_print` results name the remote job in `jobName` (for `start_print`, the checked copy that actually starts), matching `job.name` in `counterpart_print_progress`.
|
|
10
|
+
- `slice_stl` and `slice_with_template` accept `layer_height`, `wall_loops` and `sparse_infill_density`, written over the selected profile: Orca and Bambu Studio process keys on the Bambu-compatible and generic OrcaSlicer paths, and `--layer-height`, `--perimeters` and `--fill-density` for PrusaSlicer and Slic3r. Cura refuses them. Profile files are never modified.
|
|
11
|
+
- `get_printer_filaments` slots carry `profile`, the installed slicer filament profile for the slot's material, as an absolute path `slice_stl` takes as `load_filaments`: from Spoolman's material when Spoolman reports one, otherwise the configured `FILAMENT_PROFILE`; omitted when nothing resolves. OrcaSlicer bundled, system and user presets, and PrusaSlicer/Slic3r `filament/*.ini` presets, are matched exactly on `filament_type`, preferring a profile whose `compatible_printers` lists the printer in `SLICER_PROFILE`. bambu-printer-mcp's resolver did not fit: it looks up Bambu profiles by AMS `tray_info_idx`, which other printers do not report.
|
|
12
|
+
- **Behaviour change:** PrusaSlicer and Slic3r now load a filament preset. `filament_profile`, `load_filaments` or `FILAMENT_PROFILE` must be one `.ini` preset and is passed as a second `--load` after `slicer_profile`; before, it was silently ignored. A `.json` or a list is refused with instructions. Generic slicers (PrusaSlicer, Slic3r, generic OrcaSlicer) now honour `load_filaments` as well as its alias `filament_profile`; before, only the Bambu CLI path read `load_filaments`. For generic OrcaSlicer, a filament chosen for the call replaces the `|filament.json` default in `SLICER_PROFILE` instead of becoming a second slot, and a filament preset that `inherits` installed presets is passed to `--load-filaments` with its chain merged in (the CLI does not resolve `inherits`, so a bundled preset would slice without its own temperatures). A preset whose parent is not installed is passed unchanged.
|
|
13
|
+
- `PRINTER_CAMERA_SNAPSHOT_URL` overrides the camera source for any printer, and `REPETIER_SLUG` selects the Repetier-Server printer for the new tools.
|
|
14
|
+
|
|
15
|
+
- Add an optional Autodesk Fusion bridge (`src/fusion-mcp-bridge.ts`) to faust-machines/fusion360-mcp-server pinned at `19b9f1e95192`, configured with `FUSION_MCP_COMMAND`, `FUSION_MCP_ARGS` (defaulting to the pinned server in socket mode), `FUSION_MCP_TIMEOUT_MS` and `FUSION_MCP_HOST`. `fusion_mcp_status` reports configuration, the Fusion process, whether the add-in answers its ping within a 2 s hard deadline (Blender's addon is not mistaken for it), and the server's tools; `launch: true` opens Fusion on macOS with `--env FUSION_MCP_PORT=<port>` and waits up to 90 s. The add-in port defaults to 9877 (PRD §8.9) because Blender's MCP addon holds the faust default, 9876; the bridge passes it to the Fusion server too. `fusion_mcp_call` forwards any discovered tool with its full content and errors and never retries. `fusion_mcp_new_design` opens a parametric design through `execute_code`. `fusion_mcp_export` writes `<name>.stl`, `<name>.f3d` and `<name>.parameters.json`, verifies the STL and its units against the Fusion body, and never overwrites. Unlike the Blender bridge, the client stays connected for the life of the server. Only `FUSION_*` settings reach the Fusion process. Closing stdin now shuts the server down, so a host that disconnects without a signal does not leave it, or the Fusion child, running.
|
|
16
|
+
|
|
17
|
+
### Evidence
|
|
18
|
+
|
|
19
|
+
- The pinned Fusion server started through the bridge with `uvx` and listed its 93 tools; Fusion itself was not installed, so no design was built or exported live. The bridge's tests use a stdio peer that reproduces that commit's recorded `--mode mock` output. At that commit no tool works while Fusion shows its home screen without an open document (faust-machines issue #12), so `fusion_mcp_new_design` explains how to open one.
|
|
20
|
+
- OctoPrint 1.11.2 and 1.8.7 (virtual printer) and Klipper with Moonraker 1.5.0 on simulavr, with Spoolman 0.27.1: info, progress, camera snapshot, filaments, a checked upload-and-print through MCP with the confirmation answered, pause, resume (re-read bytes and its own confirmation), cancel, and a refused resume after the cancel. `jobName` equalled the reported `job.name` on all three. These are simulators, not printers.
|
|
21
|
+
- PrusaLink, Duet (standalone `rr_*` and DSF), Repetier-Server and Creality follow their API documentation and are covered by recorded-shape mapping tests and loopback HTTP mocks only. Repetier's `done`, `printTime`, `printedTimeComp` and `@pause` are not in its API manual. Creality's Moonraker ports (7125, then 4408) come from community K1 setups. Duet uses `rr_model` flags `d99v` instead of `d99f`, because `f` omits `job.file`.
|
|
22
|
+
- The Bambu mapping is tested offline and matches bambu-printer-mcp's encodings. This server has no Bambu camera, pause or resume path.
|
|
23
|
+
|
|
3
24
|
## 1.2.20 — 2026-10-30
|
|
4
25
|
|
|
5
26
|
### Fixed
|
package/README.md
CHANGED
|
@@ -208,15 +208,17 @@ The optional FULU **BambuNetwork bridge** is a separate runtime. `fulu_bambu_net
|
|
|
208
208
|
|
|
209
209
|
- Seven printer backends, selected with `PRINTER_TYPE`: OctoPrint, Klipper (Moonraker), Duet, Repetier-Server, Bambu Lab, PrusaLink or Prusa Connect, and Creality
|
|
210
210
|
- Per-call `type`, `host`, `port`, and `api_key` arguments for working with more than one printer
|
|
211
|
-
- Printer status, file listing, G-code upload from inline content or a local path, starting a stored file, cancelling a job, and setting bed or nozzle temperatures
|
|
211
|
+
- Printer status, file listing, G-code upload from inline content or a local path, starting a stored file, pausing, resuming, cancelling a job, and setting bed or nozzle temperatures
|
|
212
|
+
- The `counterpart/1` tools shared with [bambu-printer-mcp](https://github.com/DMontgomery40/bambu-printer-mcp): one progress shape for every firmware (state, job, progress, time left, layers, temperatures, problems), detected printer capabilities, camera snapshots, and the loaded filament (Spoolman on Moonraker)
|
|
212
213
|
- STL tools: inspect dimensions, scale, rotate, translate, extend the base, merge vertices, center, lay flat, transform one section of a model, and render multi-angle SVG previews
|
|
213
|
-
- A print and heating safety gate on every backend: the exact G-code is inspected, every heater target is checked against hardware and material ceilings, the printer's state is checked, and a human confirms through MCP elicitation. Heater-off and cancel are never gated
|
|
214
|
+
- A print and heating safety gate on every backend: the exact G-code is inspected, every heater target is checked against hardware and material ceilings, the printer's state is checked, and a human confirms through MCP elicitation. Heater-off, pause, and cancel are never gated; resume only continues a paused job this server inspected and started, after a person confirms
|
|
214
215
|
- Slicing through PrusaSlicer, Slic3r, OrcaSlicer, CuraEngine, FULU OrcaSlicer-bambulab, or Bambu Studio command lines, with G-code peak-temperature checks and a one-call process-and-print pipeline
|
|
215
216
|
- Bambu-compatible CLI slicing with the exact model and nozzle machine preset resolved from your slicer installation, filament slots and colours, placement options, and a local template registry
|
|
216
217
|
- Bambu Lab project printing: upload a sliced `.3mf` over FTPS and start it over MQTT with the plate's G-code path, MD5, AMS mapping, and calibration flags, after checking the plate against a fresh printer report; auto-slice unsliced projects with FULU OrcaSlicer-bambulab or Bambu Studio
|
|
217
218
|
- Required Bambu printer model for print operations, asked for through MCP elicitation when missing
|
|
218
219
|
- FULU OrcaSlicer-bambulab setup inspection and diagnostic BambuNetwork bridge RPC, with raw print methods refused
|
|
219
220
|
- Optional Blender MCP bridge: discover a standard Blender MCP server's tools, forward calls, export named scene objects to a verified STL, and run verified STL edits
|
|
221
|
+
- Optional Autodesk Fusion bridge through the pinned faust-machines Fusion MCP server: check Fusion and its add-in, forward any of its CAD tools, start a parametric design, and export STL, F3D and parameters with verified output
|
|
220
222
|
- Slicer, bridge, and Blender executables come from server configuration unless you explicitly opt in to per-call selectors
|
|
221
223
|
- MCP resources for printer status, files, and file details
|
|
222
224
|
- Transports: stdio (default) and streamable HTTP, plus a Docker image
|
|
@@ -392,7 +394,7 @@ Every printer tool accepts `host`, `port`, `type`, and `api_key`, and Bambu prin
|
|
|
392
394
|
|
|
393
395
|
What each call does depends on the backend; see [printer backend setup](https://github.com/DMontgomery40/mcp-3D-printer-server/blob/main/docs/SETUP.md#printer-backend-setup) for the exact API routes.
|
|
394
396
|
|
|
395
|
-
Every print start and positive heating command, on every backend, goes through a [safety gate](https://github.com/DMontgomery40/mcp-3D-printer-server/blob/main/docs/SETUP.md#print-and-heating-safety): the server inspects the exact G-code it will start, checks each heater target against hardware and material ceilings, checks that the printer is ready, and asks a human to confirm through MCP elicitation. Turning a heater off (`temperature: 0`) and `cancel_print` are never gated.
|
|
397
|
+
Every print start and positive heating command, on every backend, goes through a [safety gate](https://github.com/DMontgomery40/mcp-3D-printer-server/blob/main/docs/SETUP.md#print-and-heating-safety): the server inspects the exact G-code it will start, checks each heater target against hardware and material ceilings, checks that the printer is ready, and asks a human to confirm through MCP elicitation. Turning a heater off (`temperature: 0`), `pause_print`, and `cancel_print` are never gated. `resume_print` reheats and moves the printer, so it only resumes a job this server inspected and started, and asks a person first.
|
|
396
398
|
|
|
397
399
|
#### get_printer_status
|
|
398
400
|
|
|
@@ -436,6 +438,7 @@ Upload G-code to the printer, and optionally start it. Pass `gcode_path` for a l
|
|
|
436
438
|
- With `print: true`, the exact uploaded bytes are inspected first (every `S` and `R` heater target, tool changes, and hardware and material ceilings), the printer's state is checked, and a human confirms before the job starts.
|
|
437
439
|
- Printing needs a declared material: slicer metadata in the file (`; filament_type = PLA`) or the `material` argument, which must not contradict the file.
|
|
438
440
|
- On Bambu printers, files go to `cache/` over FTPS, and printing also needs the model (`bambu_model` or `BAMBU_MODEL`). Automatic printing after upload supports `.gcode` only; print `.3mf` projects with `print_3mf`.
|
|
441
|
+
- The result's `jobName` is the remote file name. `counterpart_print_progress` reports the same name as `job.name` while that job runs.
|
|
439
442
|
|
|
440
443
|
#### start_print
|
|
441
444
|
|
|
@@ -450,11 +453,11 @@ Start a G-code file that is already stored on the printer. The server downloads
|
|
|
450
453
|
}
|
|
451
454
|
```
|
|
452
455
|
|
|
453
|
-
Pass `material` when the file has no `filament_type` metadata. On Bambu printers it also needs the model and supports `.gcode` files only; bare filenames are looked up in `cache/`.
|
|
456
|
+
Pass `material` when the file has no `filament_type` metadata. On Bambu printers it also needs the model and supports `.gcode` files only; bare filenames are looked up in `cache/`. The result's `jobName` is the checked copy's name (`checked-<id>-<file>`), which is the name the printer reports for the job.
|
|
454
457
|
|
|
455
458
|
#### cancel_print
|
|
456
459
|
|
|
457
|
-
Cancel the current print job. Cancelling is never gated and also cancels checked prints still waiting to start
|
|
460
|
+
Cancel the current print job. Cancelling is never gated and also cancels checked prints still waiting to start, including a pending `resume_print`. A cancelled job cannot be resumed; use `pause_print` to stop temporarily.
|
|
458
461
|
|
|
459
462
|
```json
|
|
460
463
|
{
|
|
@@ -463,6 +466,72 @@ Cancel the current print job. Cancelling is never gated and also cancels checked
|
|
|
463
466
|
}
|
|
464
467
|
```
|
|
465
468
|
|
|
469
|
+
#### pause_print
|
|
470
|
+
|
|
471
|
+
Pause the current print. Pausing is never gated. Routes: OctoPrint `POST /api/job` (`{"command":"pause","action":"pause"}`), Moonraker `POST /printer/print/pause`, PrusaLink `PUT /api/v1/job/<id>/pause`, Duet `M25`, Repetier `@pause`, and Creality printers that run Moonraker. Bambu pause is in [bambu-printer-mcp](https://github.com/DMontgomery40/bambu-printer-mcp).
|
|
472
|
+
|
|
473
|
+
```json
|
|
474
|
+
{
|
|
475
|
+
"type": "klipper",
|
|
476
|
+
"host": "192.168.1.50",
|
|
477
|
+
"port": "7125"
|
|
478
|
+
}
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
#### resume_print
|
|
482
|
+
|
|
483
|
+
Resume a paused print. Resume reheats and moves the printer, so it is gated like a print start. It resumes only the job this server instance inspected and started, after a fresh report that the same job is paused, and after a person confirms through MCP elicitation (unless the server sets `PRINT_REQUIRE_CONFIRMATION=0`). OctoPrint, Klipper and Duet re-download the file and compare its SHA-256 with the inspected bytes before asking; PrusaLink, Repetier and Creality have no download route here, so the job is matched by name only. The printer is read again after the confirmation. Cancelling the job, or a report that it ended, retires it, so a later job that reuses the name is never resumed. A job started at the printer, from another app, or before the server restarted is refused; resume it at the printer. Duet's download route needs the Duet Software Framework, so a standalone board's resume is refused. The result's `bytesVerified` says whether the bytes were re-read. OctoPrint drops a resume sent while it is still pausing, so the server waits for a settled pause (`job.stage` "Pausing" means not yet). Routes: OctoPrint `{"command":"pause","action":"resume"}`, Moonraker `POST /printer/print/resume`, PrusaLink `PUT /api/v1/job/<id>/resume`, Duet `M24`, and Repetier `continueJob`.
|
|
484
|
+
|
|
485
|
+
#### counterpart_printer_info
|
|
486
|
+
|
|
487
|
+
Describe the printer in the shared `counterpart/1` shape: the server's name and version, the printer's kind, host and any model, serial or name it reports, and which features work. Capabilities are detected from the firmware, never assumed. For example, `camera` is `http-snapshot` only when the firmware names a snapshot URL or the conventional one answers with a JPEG.
|
|
488
|
+
|
|
489
|
+
```json
|
|
490
|
+
{
|
|
491
|
+
"contract": "counterpart/1",
|
|
492
|
+
"server": { "name": "mcp-3d-printer-server", "version": "1.2.21" },
|
|
493
|
+
"printer": { "kind": "klipper", "host": "192.168.1.50", "name": "voron" },
|
|
494
|
+
"capabilities": { "progress": true, "layers": true, "camera": "http-snapshot", "filaments": "single",
|
|
495
|
+
"pause": true, "resume": true, "cancel": true, "print3mf": false, "gcode": true }
|
|
496
|
+
}
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
#### counterpart_print_progress
|
|
500
|
+
|
|
501
|
+
Read the printer's state and current job in one shape for every firmware. `state` is one of `idle`, `preparing`, `printing`, `paused`, `finished`, `failed`, `cancelled`, `offline`, or `busy`. `job` carries the file name (the same as the upload's `jobName`), `progress` (0 to 100), `elapsedSec`, `remainingSec`, `layer` and `totalLayers` where the firmware reports them, and `stage` for transitional states. `problems` lists firmware errors and messages. Optional fields are omitted, never null. A printer that does not answer at all is `offline`. See [progress, camera, pause and resume](https://github.com/DMontgomery40/mcp-3D-printer-server/blob/main/docs/SETUP.md#progress-camera-pause-and-resume) for each firmware's requests and mapping.
|
|
502
|
+
|
|
503
|
+
```json
|
|
504
|
+
{
|
|
505
|
+
"contract": "counterpart/1",
|
|
506
|
+
"observedAt": "2026-11-01T12:00:00.000Z",
|
|
507
|
+
"state": "printing",
|
|
508
|
+
"job": { "name": "checked-4f2a-bracket.gcode", "progress": 25, "elapsedSec": 1200, "remainingSec": 3600, "layer": 12, "totalLayers": 80 },
|
|
509
|
+
"temps": { "nozzle": { "actual": 215, "target": 215 }, "bed": { "actual": 60, "target": 60 } },
|
|
510
|
+
"problems": []
|
|
511
|
+
}
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
#### camera_snapshot
|
|
515
|
+
|
|
516
|
+
Capture one JPEG frame and return it as base64, with the same arguments and result as bambu-printer-mcp's `camera_snapshot` plus `capturedAt`. Pass `save_path` to also write the file, and `timeout_ms` (default 8000).
|
|
517
|
+
- OctoPrint: the Classic Webcam snapshot URL on 1.9 and later (`plugins.classicwebcam.snapshot`), `webcam.snapshotUrl` on 1.8, then `http://<host>/webcam/?action=snapshot`.
|
|
518
|
+
- Moonraker: the first enabled webcam's `snapshot_url` from `/server/webcams/list`.
|
|
519
|
+
- Repetier: the printer's webcam `staticUrl`.
|
|
520
|
+
- PrusaLink and Duet have no local snapshot API.
|
|
521
|
+
- `PRINTER_CAMERA_SNAPSHOT_URL` overrides the source for any printer.
|
|
522
|
+
|
|
523
|
+
Relative URLs and loopback hosts in the firmware's settings are read as the printer itself. The API key is sent only to the printer's own API address, and only a JPEG is accepted.
|
|
524
|
+
|
|
525
|
+
```json
|
|
526
|
+
{ "status": "success", "format": "image/jpeg", "sizeBytes": 78719, "base64": "/9j/4AAQ…", "capturedAt": "2026-11-01T12:00:00.000Z", "source": "moonraker-webcam" }
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
#### get_printer_filaments
|
|
530
|
+
|
|
531
|
+
Report the loaded filament as one external slot, `{"slots": [{"id": "ext", "material", "color", "name", "source", "profile"}]}`. Moonraker printers with Spoolman report the active spool's material, `#RRGGBB` colour and name (`source: "spoolman"`); every other printer reports `source: "unknown"`. Bambu AMS inventory is in [bambu-printer-mcp](https://github.com/DMontgomery40/bambu-printer-mcp).
|
|
532
|
+
|
|
533
|
+
Each slot also carries `profile`: the absolute path of the installed slicer filament profile for its material, which `slice_stl` takes as `load_filaments`. It is resolved in the slicer `slice_stl` uses by default (`SLICER_TYPE`, `SLICER_PATH`), for the printer in `SLICER_PROFILE`. OrcaSlicer searches its bundled `profiles/<vendor>/filament`, the `OrcaSlicer/system` copies and the user's `OrcaSlicer/user/<id>/filament` presets, reading `filament_type` and `compatible_printers` through `inherits`. PrusaSlicer and Slic3r search the data folder's `filament/*.ini` presets. The material must equal the profile's `filament_type` exactly (case aside): a `PLA` spool never gets a `PLA-CF` profile. Profiles that list other printers are skipped; one that lists this printer comes first, then profiles for every printer, user presets before bundled ones. With no reported material, `profile` is the filament `slice_stl` loads by default (`FILAMENT_PROFILE`), when that file exists. When nothing resolves, `profile` is omitted.
|
|
534
|
+
|
|
466
535
|
#### set_printer_temperature
|
|
467
536
|
|
|
468
537
|
Set a target temperature for a printer component. Use `bed` or `extruder`; Bambu also accepts `nozzle`, `tool`, and `tool0`. OctoPrint nozzle targets are sent to `tool0`.
|
|
@@ -587,7 +656,7 @@ Options for the Bambu-compatible path:
|
|
|
587
656
|
|---|---|
|
|
588
657
|
| `bed_type` | Build plate: `textured_plate`, `cool_plate`, `engineering_plate`, or `hot_plate` (default `BED_TYPE` or `textured_plate`) |
|
|
589
658
|
| `nozzle_type` | Installed nozzle: `stainless_steel`, `hardened_steel`, `tungsten_carbide`, or `brass` (default `BAMBU_NOZZLE_TYPE`, else the preset's stock nozzle). Printing requires it to match the printer's reported nozzle |
|
|
590
|
-
| `load_filaments` | Filament profile JSON paths in slot order, `;`-separated. One profile applies to every slot; otherwise give one per slot. `filament_profile` is an alias |
|
|
659
|
+
| `load_filaments` | Filament profile JSON paths in slot order, `;`-separated. One profile applies to every slot; otherwise give one per slot. PrusaSlicer and Slic3r take one `.ini` filament preset. `filament_profile` is an alias; `get_printer_filaments` reports a matching path as `slots[].profile` |
|
|
591
660
|
| `load_filament_ids` | Comma-separated filament IDs mapping filaments to objects, such as `1,2,3,1` |
|
|
592
661
|
| `filament_colours` | One `#RRGGBB` per filament slot, `;`-separated. Defaults to the input 3MF's colours, then each profile's colour |
|
|
593
662
|
| `template_3mf_path`, `template_name`, `template_dir` | Reuse a 3MF's or profile's slicer settings as the process profile (defaults: `BAMBU_TEMPLATE_3MF_PATH`, `BAMBU_TEMPLATE_DIR`). An explicit `slicer_profile` takes precedence |
|
|
@@ -596,7 +665,9 @@ Options for the Bambu-compatible path:
|
|
|
596
665
|
| `scale`, `rotate`, `rotate_x`, `rotate_y` | Transform before slicing (uniform scale; rotations in degrees). For OrcaSlicer STL input the server applies them to a mesh copy in Orca's order to avoid a CLI crash; see [OrcaSlicer CLI limits](https://github.com/DMontgomery40/mcp-3D-printer-server/blob/main/docs/SLICING.md#bambu-compatible-slicing) |
|
|
597
666
|
| `enable_timelapse`, `allow_mix_temp` | Insert timelapse parking moves; allow filaments with different temperature needs on one plate |
|
|
598
667
|
|
|
599
|
-
|
|
668
|
+
`layer_height` (mm), `wall_loops` (a whole number), and `sparse_infill_density` (such as `"15%"`) are written over the selected profile on every slicer: as the process keys `layer_height`, `wall_loops`, and `sparse_infill_density` for Bambu Studio and OrcaSlicer, and as `--layer-height`, `--perimeters`, and `--fill-density` for PrusaSlicer and Slic3r. They win over a template. Cura refuses them; set them in its definition file. Your profile files are never modified.
|
|
669
|
+
|
|
670
|
+
Generic slicers keep their own profile formats: PrusaSlicer and Slic3r load one exported config, plus an optional filament preset `.ini` from `load_filaments`, and generic OrcaSlicer takes `machine.json;process.json`, optionally followed by `|filament.json`. `slicer_type`, `slicer_profile`, and `filament_profile` fall back to `SLICER_TYPE`, `SLICER_PROFILE`, and `FILAMENT_PROFILE`. The slicer executable comes from `SLICER_PATH`; a per-call `slicer_path` requires `MCP_ALLOW_EXECUTABLE_ARG=1`. See the [slicing guide](https://github.com/DMontgomery40/mcp-3D-printer-server/blob/main/docs/SLICING.md#bambu-compatible-slicing).
|
|
600
671
|
|
|
601
672
|
#### slice_with_template
|
|
602
673
|
|
|
@@ -740,6 +811,38 @@ Import an STL into Blender, apply ordered edits, and export a new STL. Supported
|
|
|
740
811
|
|
|
741
812
|
Legacy `BLENDER_MCP_BRIDGE_COMMAND` shell commands remain supported when no standard command is configured. They receive JSON on stdin (`modelPath`, `operations`, `source`, and `stlPath`) and the same JSON in `MCP_BLENDER_PAYLOAD`, and their results report `output_verified: false`. A per-call `bridge_command` requires `MCP_ALLOW_EXECUTABLE_ARG=1`.
|
|
742
813
|
|
|
814
|
+
#### Fusion MCP
|
|
815
|
+
|
|
816
|
+
Design parts from scratch in Autodesk Fusion through [faust-machines/fusion360-mcp-server](https://github.com/faust-machines/fusion360-mcp-server), pinned to commit `19b9f1e95192`. Set `FUSION_MCP_COMMAND` to the full path of `uvx`; `FUSION_MCP_ARGS` defaults to the pinned server in socket mode. Install that commit's Fusion360MCP add-in in Fusion and set it to Run on Startup. The client stays connected for the life of this server, only `FUSION_*` settings reach the Fusion server, and requests are never replayed. See the [Fusion guide](https://github.com/DMontgomery40/mcp-3D-printer-server/blob/main/docs/FUSION.md) for setup, units, and the open-document requirement.
|
|
817
|
+
|
|
818
|
+
#### fusion_mcp_status
|
|
819
|
+
|
|
820
|
+
Report `configured`, `connected`, `addinReachable`, `fusionRunning`, the Fusion server's `tools` with their schemas, `launched`, `pin` (the faust-machines commit), and `error` when the server could not start. `addinReachable` means the add-in answered its own `ping` within 2 s on `FUSION_MCP_PORT` (default 9877, because Blender's MCP addon holds 9876). `connected` is true only when the add-in also answered through the Fusion server. With `launch: true` and Fusion not running on this Mac, it runs `open -a "Autodesk Fusion" --env FUSION_MCP_PORT=<port>` and waits up to 90 s for the add-in.
|
|
821
|
+
|
|
822
|
+
```json
|
|
823
|
+
{ "launch": true }
|
|
824
|
+
```
|
|
825
|
+
|
|
826
|
+
#### fusion_mcp_call
|
|
827
|
+
|
|
828
|
+
Call any tool the Fusion server advertises, such as `create_sketch`, `extrude`, `fillet`, `set_parameter`, or `execute_code`, with arguments matching its discovered schema. The full MCP result and errors are returned, as for `blender_mcp_call`. Calls change the active design and are never retried. Fusion lengths are in centimetres unless a tool says otherwise.
|
|
829
|
+
|
|
830
|
+
```json
|
|
831
|
+
{ "tool_name": "create_sketch", "arguments": { "plane": "xy" } }
|
|
832
|
+
```
|
|
833
|
+
|
|
834
|
+
#### fusion_mcp_new_design
|
|
835
|
+
|
|
836
|
+
Open a new parametric design document, so the Fusion tools have an active design. At the pinned commit, Fusion must already have some document open: no tool works from Fusion's home screen ([issue #12](https://github.com/faust-machines/fusion360-mcp-server/issues/12)).
|
|
837
|
+
|
|
838
|
+
#### fusion_mcp_export
|
|
839
|
+
|
|
840
|
+
Write `<name>.stl` (from `export_stl`), `<name>.f3d` (from `export_f3d`), and `<name>.parameters.json` (the design's user parameters) into `output_dir`, and return their absolute paths as `stl`, `f3d`, and `parameters`. The STL is one body: the only visible solid body, or `body_name`, whose name must be unique across all bodies, hidden ones and component copies included. It is checked as a finite triangle mesh, and `stlUnits` reports whether its numbers are millimetres. Existing files are never overwritten, and a failed export publishes nothing.
|
|
841
|
+
|
|
842
|
+
```json
|
|
843
|
+
{ "output_dir": "/path/to/project", "name": "bracket" }
|
|
844
|
+
```
|
|
845
|
+
|
|
743
846
|
</details>
|
|
744
847
|
|
|
745
848
|
</details>
|
|
@@ -764,8 +867,8 @@ For example, `printer://192.168.1.100/status` reads the status of the printer at
|
|
|
764
867
|
|
|
765
868
|
## Printer Limitations
|
|
766
869
|
|
|
767
|
-
1. **Status depth varies by backend.**
|
|
768
|
-
2. **
|
|
870
|
+
1. **Status depth varies by backend.** `get_printer_status` returns each backend's own status data: Bambu includes progress, layers, and time remaining; OctoPrint's `/api/printer` and Moonraker's `/printer/info` have no job progress. Use `counterpart_print_progress` for job progress on every backend. Its OctoPrint and Klipper mappings were checked against OctoPrint 1.8 and 1.11 virtual printers and a simulated Klipper printer; PrusaLink, Duet, Repetier, and Creality follow their API documentation and have not been checked on hardware.
|
|
871
|
+
2. **Resume only what this server started.** `resume_print` refuses a job it did not inspect and start, including one it started before a restart. Repetier's pause command and its time fields are not in Repetier's API manual.
|
|
769
872
|
3. **Plain HTTP for most backends.** OctoPrint, Klipper, Duet, Repetier, and Creality adapters connect over `http://`. The Prusa adapter uses HTTPS for Prusa Connect, an `https://` host, or port 443.
|
|
770
873
|
4. **Moonraker authentication is optional; Duet has no password support.** Set `API_KEY` for Moonraker hosts that require authentication. Leave it empty only when Moonraker trusts the MCP host. A password-protected Duet cannot be reached yet.
|
|
771
874
|
5. **Command sent is not print finished.** A success response means the printer or its host accepted the request. Check status, and the printer itself, before you walk away.
|
|
@@ -1,5 +1,26 @@
|
|
|
1
|
+
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
1
2
|
import { type CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
3
|
type Arguments = Record<string, unknown>;
|
|
4
|
+
type EditDeadline = {
|
|
5
|
+
check: () => void;
|
|
6
|
+
remaining: () => number;
|
|
7
|
+
};
|
|
8
|
+
type BoundingBox = {
|
|
9
|
+
min: [number, number, number];
|
|
10
|
+
max: [number, number, number];
|
|
11
|
+
dimensions: [number, number, number];
|
|
12
|
+
};
|
|
13
|
+
type StlMetadata = {
|
|
14
|
+
bytes: number;
|
|
15
|
+
triangles: number;
|
|
16
|
+
bounding_box: BoundingBox;
|
|
17
|
+
};
|
|
18
|
+
export declare function editDeadline(timeout: number, signal?: AbortSignal): EditDeadline;
|
|
19
|
+
export declare class ClosingStdioTransport extends StdioClientTransport {
|
|
20
|
+
private closing?;
|
|
21
|
+
close(): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
export declare function regularStl(filePath: string, deadline: EditDeadline): Promise<StlMetadata>;
|
|
3
24
|
export declare class BlenderMcpBridge {
|
|
4
25
|
private session;
|
|
5
26
|
private invoke;
|
|
@@ -16,7 +16,7 @@ const RECEIPT_PREFIX = "BAMBU_STL_RESULT:";
|
|
|
16
16
|
const EXPORT_RECEIPT_PREFIX = "MCP3D_STL_EXPORT:";
|
|
17
17
|
class BlenderError extends Error {
|
|
18
18
|
}
|
|
19
|
-
function editDeadline(timeout, signal) {
|
|
19
|
+
export function editDeadline(timeout, signal) {
|
|
20
20
|
const deadline = performance.now() + timeout;
|
|
21
21
|
const check = () => {
|
|
22
22
|
if (signal?.aborted)
|
|
@@ -26,7 +26,7 @@ function editDeadline(timeout, signal) {
|
|
|
26
26
|
};
|
|
27
27
|
return { check, remaining: () => { check(); return Math.max(1, Math.ceil(deadline - performance.now())); } };
|
|
28
28
|
}
|
|
29
|
-
class ClosingStdioTransport extends StdioClientTransport {
|
|
29
|
+
export class ClosingStdioTransport extends StdioClientTransport {
|
|
30
30
|
close() {
|
|
31
31
|
// Client.connect starts a non-awaited close on handshake failure. The SDK
|
|
32
32
|
// clears its process reference immediately, so later close calls otherwise
|
|
@@ -118,7 +118,7 @@ function boundingBox(min, max) {
|
|
|
118
118
|
dimensions: [round(max[0] - min[0]), round(max[1] - min[1]), round(max[2] - min[2])],
|
|
119
119
|
};
|
|
120
120
|
}
|
|
121
|
-
async function regularStl(filePath, deadline) {
|
|
121
|
+
export async function regularStl(filePath, deadline) {
|
|
122
122
|
deadline.check();
|
|
123
123
|
const stat = await fs.lstat(filePath).catch(() => { throw new BlenderError("STL file does not exist or is not readable."); });
|
|
124
124
|
deadline.check();
|