Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This file is the repository's shared source of truth for local agents, scheduled
- Before opening or updating a PR, run Matt Pocock's `code-review` skill against the main merge base and resolve substantive findings locally. GitHub CI is the expensive gate, so it should only see reviewed work. Then use a PR to main and wait for CI on the current head; a passing local test does not authorize ignoring current CI failures. Codex review is not part of this process: don't put `@codex review` in commit messages or PR comments unless the maintainer asks for it.
- Prioritize substantive defects and regressions in supported workflows. Document and defer obscure edge cases, speculative hardening, and cosmetic objections instead of extending a sound release into an endless review loop.
- The main-branch Publish Package workflow (`.github/workflows/publish.yml`) runs the checks and `npm publish` with trusted publishing; do not publish from a local checkout. Verify that workflow and the exact npm version before claiming publication. Then create a `v<version>` tag and GitHub release with the accumulated changelog notes. Verify npm, the tag, the release, and a fresh `npx -y mcp-3d-printer-server` startup before declaring the release complete. Never move a published tag.
- Changes to src/, scripts/, or printer behavior need a present-tense CHANGELOG.md entry under `## Unreleased`, including evidence limits (mocked transports versus real hardware).
- Changes to src/, scripts/, or printer behavior need a present-tense CHANGELOG.md entry under `## Unreleased`, including evidence limits (mocked transports versus real hardware). Promote those notes to the release version and date before merging; released changes must never remain under Unreleased on main. Synchronize server.json's server and npm package versions with package.json. Verify the Pages deployment and live `/project/changelog` version/date after merging, not just the local site build.
- Never add AI or agent attribution anywhere in Git or GitHub: no `Co-Authored-By` trailers for Claude, Codex, or other assistants, no "Generated with" footers, and no agent session links in commits, PR titles or bodies, review replies, issue comments, or release notes.
- Preserve original authorship when integrating contributor PRs. Credit code, issue reports, hardware evidence, and useful superseded proposals in CONTRIBUTORS.md.

Expand All @@ -31,12 +31,15 @@ This file is the repository's shared source of truth for local agents, scheduled

- Multi-printer MCP server: OctoPrint, Klipper (Moonraker), Duet, Repetier, Bambu Lab, Prusa Connect/PrusaLink, and Creality Cloud. `PRINTER_TYPE` selects the adapter. Transports: stdio by default and streamable-http.
- Bambu uses MQTT on port 8883 for commands/status and FTPS on port 990 for files. Use `basic-ftp` directly for uploads and `bambu-node` for MQTT commands.
- File listings and metadata lookups are read-only FTPS operations with the shared TLS-session options. Runtime diagnostics go to stderr; stdout is reserved for MCP protocol messages.
- bambu-printer-mcp is a Bambu-only fork of this repository. Safety-critical changes must be ported to both repositories, each through its own review and release rules. Report a required port you could not complete.

## Printer and slicer safety

- Every print and positive-heating path must pass the shared gates in `src/safety/`: finite temperature validation before any connection; independent hardware ceilings per heater (Bambu per model, other printers from server configuration) that a request or file can never raise; declared-material ceilings; inspection of the exact file bytes to be dispatched, including all heater commands and their S/R targets; fresh printer state that is ready and free of actionable errors; and human confirmation through MCP elicitation unless the server explicitly opts out. Heater-off, pause, and cancel/stop are never gated.
- `BAMBU_MODEL` (or the explicit tool model) is required for every Bambu print operation. Elicit it when missing and never guess: G-code for the wrong model can damage hardware.
- Fresh returned serial prefix `039` identifies the full-size A1; `030` identifies A1 mini. Configured serial/model values never replace fresh observed identity or suppress conflicts.
- Accept the official A1/A1 mini `M109 H` wait parameter only for those models and from 0 to 300. Independently check S/R heater targets; missing targets, malformed waits, other heater commands, and other models still reject.
- Never swallow inspection or auto-slice failures and fall back to printing the original, unsliced file. Stop with the actionable error before upload or dispatch.
- Resolve Bambu-compatible slicer profiles recursively (inherits and includes) and require the exact model/nozzle machine preset from the selected installation before CLI slicing. Missing references, cycles, or malformed profiles stop preparation.
- Remote-file starts must not bypass inspection. Raw bridge methods (such as the FULU BambuNetwork RPC) must not bypass the shared gates.
Expand Down
44 changes: 43 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,48 @@
# Changelog

## 1.2.10
## 1.2.11 — 2026-10-06

This release also includes the safety, slicing, Blender, and documentation
changes prepared as 1.2.10 below. Version 1.2.10 was not published to npm.

### Fixed

- Send Moonraker's configured `API_KEY` as `X-Api-Key` on every request,
including multipart uploads and remote-file inspection downloads. Thanks to
Jack Manning (@EastArctica) for [#30](https://github.com/DMontgomery40/mcp-3D-printer-server/pull/30)
and Klipper 0.13.0 authentication evidence. Loopback tests cover authenticated
and trusted-client configurations; no maintainer physical print was run.
- Correct fresh Bambu A1/A1 mini serial identity (`039` / `030`) and accept the
official A1/A1 mini `M109 H` wait parameter without weakening independently
checked S/R temperature targets. Port the fork's fixes reported by @Steavie
([#39](https://github.com/DMontgomery40/bambu-printer-mcp/issues/39)) and implemented
by @nitpreet22 ([#41](https://github.com/DMontgomery40/bambu-printer-mcp/pull/41)).
Covered by mocked identity and file-inspection regressions.
- Keep model parsing, slicing, and STL diagnostics on stderr so they cannot
corrupt stdio MCP messages, following @travismcashan's report in the fork's
[#44](https://github.com/DMontgomery40/bambu-printer-mcp/issues/44). Subprocess
regressions check the compiled parser and slicer.
- Make Bambu file metadata lookup read-only through the shared FTPS client;
remove the obsolete `bambu-js` dependency that created directories during reads.

### Dependencies and interoperability

- Update the MCP SDK to 1.32.1, basic-ftp to 6.2.2, JSZip to 3.10.2, dotenv
within version 16, and proxy-addr to its patched release. The production npm
audit reports no vulnerabilities; unresolved nodemon watcher advisories are
development-only and remain deferred rather than forcing an unsafe downgrade.
- Verify discovery, invocation, and STL export with upstream mcp-for-blender
2.1.9 and the former blender-mcp 2.0.0 package in isolated Blender 5.0.1.
The exported fixture has 12 triangles and measures 40 × 20 × 10 mm. This
verifies application interoperability, not a user's live scene or a print.

### Discovery

- Add the official MCP Registry ownership field and server metadata for the
npm package. The listing documents printer backend configuration and marks
API keys and Bambu LAN access codes as secrets.

## 1.2.10 — repository changes, not published to npm

### Safety

Expand Down
4 changes: 4 additions & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Thank you to everyone who builds, tests, reports problems, and shares real print

| Contributor | Contribution |
| --- | --- |
| [Jack Manning (EastArctica)](https://github.com/EastArctica) | Sends `X-Api-Key` on every Klipper/Moonraker request, including uploads and remote-file downloads, in [#30](https://github.com/DMontgomery40/mcp-3D-printer-server/pull/30). Supplies Klipper 0.13.0 evidence of authenticated status succeeding after the previous 401 response. |
| [nitpreet22](https://github.com/nitpreet22) | Adds A1/A1 mini `M109 H` wait compatibility and safety regressions in the Bambu fork's [#41](https://github.com/DMontgomery40/bambu-printer-mcp/pull/41), ported here with original code authorship. Shares Windows A1 slicing and file-inspection evidence; this is not physical-print verification. |
| [Javier Cortejoso (jcortejoso)](https://github.com/jcortejoso) | Reads the FULU bridge command from server configuration by default, with an explicit opt-in for per-call bridge commands, in [#20](https://github.com/DMontgomery40/mcp-3D-printer-server/pull/20). [#21](https://github.com/DMontgomery40/mcp-3D-printer-server/pull/21) extends the same gate to every per-call executable selector. |
| [Ewan Monro (heyitsmeez)](https://github.com/heyitsmeez) | Reports in [#17](https://github.com/DMontgomery40/mcp-3D-printer-server/issues/17) that a top-level `anyOf` in the `upload_gcode` input schema made the Anthropic API reject every tool, and fixes it in [#18](https://github.com/DMontgomery40/mcp-3D-printer-server/pull/18). |
| [David Gageot (dgageot)](https://github.com/dgageot) | Fixes the Docker build and hardens the image (non-root user, pinned base image, production dependencies only, build caching) in [#3](https://github.com/DMontgomery40/mcp-3D-printer-server/pull/3). |
Expand All @@ -16,6 +18,8 @@ Thank you to everyone who builds, tests, reports problems, and shares real print

| Contributor | Contribution |
| --- | --- |
| [Steavie](https://github.com/Steavie) | Reports reversed A1/A1 mini serial identity in the Bambu fork's [#39](https://github.com/DMontgomery40/bambu-printer-mcp/issues/39). This repository now uses the corrected prefixes for fresh safety identity, with mocked MQTT regressions. |
| [Travis Cashman (travismcashan)](https://github.com/travismcashan) | Reports MCP stdout pollution from model parsing and slicing in the Bambu fork's [#44](https://github.com/DMontgomery40/bambu-printer-mcp/issues/44). The stderr correction and subprocess regressions are also applied here. |
| [Lickitysplitted](https://github.com/Lickitysplitted) | Diagnoses Bambu FTPS "Premature close" upload failures on an X1C as missing TLS session reuse in [#22](https://github.com/DMontgomery40/mcp-3D-printer-server/issues/22). Release 1.2.9 addresses it; confirmation on that X1C firmware is still outstanding. |
| [CrowSoda](https://github.com/CrowSoda) | Tries slicing and printing on a Creality K1 Max through Klipper and Moonraker, and reports invalid OrcaSlicer CLI flags, missing filament-profile support, and unregistered upload and start tools in [#16](https://github.com/DMontgomery40/mcp-3D-printer-server/issues/16). All three are fixed. |
| [dongio20](https://github.com/dongio20) | Reports the PrusaLink 0.8.1 status 404, with firmware details and the working endpoint, in [#11](https://github.com/DMontgomery40/mcp-3D-printer-server/issues/11). Fixed in [#15](https://github.com/DMontgomery40/mcp-3D-printer-server/pull/15). |
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ Preserve my existing servers and settings. Prefer the published npm package
Ask which printer system I use and set PRINTER_TYPE to match. Never guess it.
Then ask only for the values that backend needs:
- octoprint: PRINTER_HOST, PRINTER_PORT if not 80, API_KEY
- klipper (Moonraker): PRINTER_HOST, PRINTER_PORT (usually 7125)
- klipper (Moonraker): PRINTER_HOST, PRINTER_PORT (usually 7125),
API_KEY if Moonraker requires authentication
- duet: PRINTER_HOST, PRINTER_PORT if not 80
- repetier: PRINTER_HOST, PRINTER_PORT (usually 3344), API_KEY
- bambu: PRINTER_HOST, BAMBU_SERIAL, BAMBU_TOKEN (the LAN access code),
Expand Down Expand Up @@ -764,7 +765,7 @@ For example, `printer://192.168.1.100/status` reads the status of the printer at
1. **Status depth varies by backend.** Bambu status includes progress, layers, and time remaining. OctoPrint status comes from `/api/printer` (state and temperatures, not job progress). Klipper status comes from Moonraker's `/printer/info`, which reports the host state but not job progress or temperatures. Duet, Repetier, and Creality responses have not been verified on hardware.
2. **Cancel, but no pause.** There is no pause or resume tool. `cancel_print` stops the job.
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.
4. **Klipper and Duet send no credentials.** Moonraker must trust the MCP host, and a password-protected Duet cannot be reached yet.
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.
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.
6. **Bambu prints need a sliced project and the right model.** `print_3mf` needs a `.3mf` with `Metadata/plate_<n>.gcode`, uploads it to `cache/`, and starts plate 1. Print settings such as layer height and temperatures cannot be changed at print time. `start_print` handles plain `.gcode` files only.
7. **Bambu AMS mapping is simple.** `ams_mapping` values are sorted and padded to five entries; real behavior still depends on firmware, loaded filament, and the project's metadata. For AMS inventory and color matching, see [bambu-printer-mcp](https://github.com/DMontgomery40/bambu-printer-mcp).
Expand Down
10 changes: 5 additions & 5 deletions docs/SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ npm link
|---|---|---|---|---|
| `bambu` | Bambu Lab | MQTT over TLS on port 8883, FTPS on port 990 | `BAMBU_SERIAL`, `BAMBU_TOKEN` (LAN access code), `BAMBU_MODEL` | **Most tested.** Maintainer hardware testing, shared with the Bambu-only fork. The FTPS fix for [#22](https://github.com/DMontgomery40/mcp-3D-printer-server/issues/22) is tested against a local FTPS server; confirmation on the reporter's X1C is outstanding. |
| `octoprint` | OctoPrint | HTTP REST API, port 80 on OctoPi | `API_KEY`, sent as `X-Api-Key` | **Community-reported.** Used against a real OctoPrint instance in [#4](https://github.com/DMontgomery40/mcp-3D-printer-server/issues/4). |
| `klipper` | Klipper (Moonraker) | HTTP API, usually port 7125 | None sent; Moonraker must trust the MCP host | **Community-reported.** Used with a Creality K1 Max through Moonraker in [#16](https://github.com/DMontgomery40/mcp-3D-printer-server/issues/16). |
| `klipper` | Klipper (Moonraker) | HTTP API, usually port 7125 | Optional `API_KEY`, sent as `X-Api-Key`; otherwise Moonraker must trust the MCP host | **Community-reported.** Used with a Creality K1 Max through Moonraker in [#16](https://github.com/DMontgomery40/mcp-3D-printer-server/issues/16). |
| `prusa` | PrusaLink / Prusa Connect | HTTP for local PrusaLink, HTTPS for `connect.prusa3d.com` or port 443 | `API_KEY`, sent as `X-Api-Key` and as a bearer token | **Community-reported.** PrusaLink 0.8.1 status fixed after [#11](https://github.com/DMontgomery40/mcp-3D-printer-server/issues/11); Prusa Connect setup discussed in [#9](https://github.com/DMontgomery40/mcp-3D-printer-server/issues/9). |
| `duet` | Duet | HTTP, port 80 | None sent | **Unverified.** No hardware reports yet. |
| `repetier` | Repetier-Server | HTTP, usually port 3344 | `API_KEY`, sent as the `apikey` query parameter | **Unverified.** No hardware reports yet. |
Expand All @@ -74,7 +74,7 @@ Create a `.env` file in the directory where you run the server, or pass environm
PRINTER_TYPE=octoprint # octoprint, klipper, duet, repetier, bambu, prusa, creality
PRINTER_HOST=192.168.1.100 # Printer or host-software address
PRINTER_PORT=80 # 7125 for Moonraker, 3344 for Repetier-Server
API_KEY=your_api_key # OctoPrint, Repetier, Prusa, Creality
API_KEY=your_api_key # OctoPrint, authenticated Moonraker, Repetier, Prusa, Creality

# --- Bambu Lab only ---
# BAMBU_SERIAL=01P00A123456789 # Printer serial number
Expand Down Expand Up @@ -118,7 +118,7 @@ API_KEY=your_api_key # OctoPrint, Repetier, Prusa, Creality
| `PRINTER_TYPE` | `octoprint` | Yes | Printer adapter: `octoprint`, `klipper`, `duet`, `repetier`, `bambu`, `prusa`, or `creality` |
| `PRINTER_HOST` | `localhost` | Yes | Printer or host-software address. Prusa also accepts `connect.prusa3d.com` or a full `https://` URL |
| `PRINTER_PORT` | `80` | Depends on backend | HTTP port for non-Bambu backends. Set `7125` for Moonraker and `3344` for Repetier-Server |
| `API_KEY` | | OctoPrint, Repetier, Prusa, Creality | Backend API key or token. Klipper and Duet adapters do not send one |
| `API_KEY` | | OctoPrint, authenticated Moonraker, Repetier, Prusa, Creality | Backend API key or token. Duet does not send one |
| `BAMBU_SERIAL` | | Bambu | Printer serial number |
| `BAMBU_TOKEN` | | Bambu | LAN access code shown on the printer |
| `BAMBU_MODEL` | | **Bambu printing and Bambu slicing** | Printer model: `p1s`, `p1p`, `x1c`, `x1e`, `a1`, `a1mini`, `h2d`. **Required** for `print_3mf`, `start_print`, upload with `print: true`, positive Bambu heating, and Bambu-compatible slicing. Slicing also accepts `p2s`, `h2s`, and `h2c` when the installed slicer has that preset. If omitted and the MCP client supports elicitation, the server asks. It selects the slicer machine preset and is checked against the live printer before printing. |
Expand Down Expand Up @@ -208,7 +208,7 @@ Replace the `env` block with the values for your backend:
| Backend | `env` values |
|---|---|
| OctoPrint | `PRINTER_TYPE=octoprint`, `PRINTER_HOST`, `PRINTER_PORT` (80 on OctoPi, 5000 for `octoprint serve`), `API_KEY` |
| Klipper (Moonraker) | `PRINTER_TYPE=klipper`, `PRINTER_HOST`, `PRINTER_PORT=7125` |
| Klipper (Moonraker) | `PRINTER_TYPE=klipper`, `PRINTER_HOST`, `PRINTER_PORT=7125`, `API_KEY` if required |
| Duet | `PRINTER_TYPE=duet`, `PRINTER_HOST`, `PRINTER_PORT` if not 80 |
| Repetier-Server | `PRINTER_TYPE=repetier`, `PRINTER_HOST`, `PRINTER_PORT=3344`, `API_KEY` |
| Bambu Lab | `PRINTER_TYPE=bambu`, `PRINTER_HOST`, `BAMBU_SERIAL`, `BAMBU_TOKEN`, `BAMBU_MODEL` |
Expand Down Expand Up @@ -289,7 +289,7 @@ The adapter connects over plain HTTP and sends the key as `X-Api-Key`. It calls
### Klipper (Moonraker)

1. Make sure Moonraker is reachable from the machine running the MCP server, usually on port 7125.
2. The adapter does not send an API key. Allow the MCP host in Moonraker's `[authorization]` `trusted_clients`, or use an installation without Moonraker authorization.
2. If Moonraker requires authentication, set `API_KEY` to its API key. The adapter sends `X-Api-Key` on status, file, upload, start, cancel, and heater requests. Leave it empty only when Moonraker trusts the MCP host. See [Moonraker authentication](https://moonraker.readthedocs.io/en/latest/external_api/authorization/).
3. Set `PRINTER_TYPE=klipper`, `PRINTER_HOST`, and `PRINTER_PORT=7125`.

Status comes from `/printer/info`, which reports the Klipper host state (for example `ready`) but not job progress or temperatures; [#12](https://github.com/DMontgomery40/mcp-3D-printer-server/issues/12) requests richer job status. The safety gate reads `/printer/objects/query?webhooks&print_stats` to refuse a printer that is printing, paused, or in error. Other calls: `/server/files/list`, `/server/files/upload`, `/server/files/gcodes/<file>` (download for inspection before `start_print`), `/printer/print/start`, `/printer/print/cancel`, and `SET_HEATER_TEMPERATURE` through `/printer/gcode/script` for `bed` and `extruder`.
Expand Down
Loading
Loading