Skip to content

Releases: MaxEllis/orcaslicer-mcp

v0.1.17

Choose a tag to compare

@MaxEllis MaxEllis released this 12 Oct 02:22

Added

  • Plate tools for fork v2.4.2-mcp.13 and later. list_plates shows each plate's index, name, lock state, build volume and objects, and which one is current. add_plate adds one. select_plate picks the plate that slice_and_wait, get_gcode, render_plate and get_job_status act on. delete_plate removes a plate; its objects are parked beside the bed and the reply counts them. move_object_to_plate keeps an object's position relative to its old plate, and an object parked beside the bed lands at the plate's centre. list_objects shows each object's plate. On an older build these tools say they need fork v2.4.2-mcp.13 or later.
  • arrange_plate warns that with several plates it packs every unlocked plate together again.
  • transform_object says that on fork v2.4.2-mcp.13 an object moved by coordinates joins the plate it lands on.

The plate tools need OrcaSlicer MCP v2.4.2-mcp.13 or later.

v0.1.16

Choose a tag to compare

@MaxEllis MaxEllis released this 09 Oct 03:46

Fixed

  • The printer tools no longer fail with a raw error when a printer sends a reply that can't be decoded, redirects, or isn't the JSON object expected at the top level. They return protocol_error (or not_reachable when the connection drops) with a message.
  • An ORCA_PRINTER_API_KEY pasted with a trailing space or newline is trimmed before it is sent.
  • A user name and password in the printer address are dropped from the address a message can echo, as a second guard after the existing redaction.
  • Looking for the printer no longer leaves an HTTP client open when the call is cancelled or fails in an unexpected way.
  • A damaged or hand-edited printer.json can no longer break a status call: the remembered address, protocol and time are checked when read, and the file is written in one atomic step.
  • Errors from finding the printer (a bad ORCA_PRINTER_URL, a profile with no address, an unsupported connection type, OrcaSlicer not reachable) now carry a printer entry saying where the address came from.
  • A printer address with port 0 is refused as not valid.
  • While Klipper is starting up (right after a firmware restart, say), get_printer_status no longer shows 0 °C for the heaters and a warning count. It leaves the temperatures empty, because the sensors haven't been read yet, and the headline is "Klipper is starting up; check again in a minute."
  • Console errors in the status lose Klipper's repeated restart instructions, as other Klipper messages already did, and an error that repeats shows once (its newest occurrence) instead of filling the list of five recent errors. A job's error message is trimmed the same way.
  • Layer numbers in the job are always whole numbers or null. Text or a non-finite number from a printer no longer reaches the result.
  • With OctoPrint, a job request that fails (or answers with something that isn't JSON) no longer fails the whole status. The status comes back with a note that the current job couldn't be read.
  • wait_for_printer treats a job that completes successfully while it waits for printing or first_layer_done as met, instead of stopping with "The job ended before ...". A one-layer or very short print passes both points before the next poll. A cancelled or errored job still stops the wait early, and so does a job that was already complete when the wait began.
  • wait_for_printer no longer sends a progress notification carrying an old status after a poll fails. The next notification comes with the next good poll.
  • A hand-edited printer.json holding a remembered time no calendar can hold (-1e300, say) no longer puts a 310-character age in the "remembered printer" note. It reads "remembered earlier".
  • list_print_history shows the failure reason already stored for a job, so the reply matches the row it just synced. Before, a reason read from the printer's console this time could differ from the one in the store.
  • list_print_history reads a job's failure reason from the console the way the status does: Klipper's repeated restart instructions are cut, and a line with nothing else in it ("Printer is shutdown") is skipped. Before, that line could be stored as the reason, and a stored reason is not replaced later.
  • list_print_history says what to do when the printer answers 404 for its history list: Moonraker versions before 0.9 need a [history] section in moonraker.conf, so add one and restart Moonraker. Before, it reported only the HTTP status.
  • list_print_history copies jobs into the outcome store oldest first, as the always-on recorder does, so when one file was printed twice against a single saved slice, the earlier print claims it. The store writes also run off the event loop, so a busy store no longer stalls the server.
  • When OrcaSlicer can't be read because of a setting other than the token (an invalid ORCA_API_TIMEOUT, say), the printer tools no longer tell you to check ORCA_API_TOKEN. The hint points at the server's OrcaSlicer settings (ORCA_API_URL, ORCA_API_TIMEOUT) and detail names the problem.
  • check_printer_match no longer reports Klipper's [firmware_retraction] section as absent when retraction is off and Klipper's settings were never read. The printer side is empty then.
  • check_printer_match says when OrcaSlicer didn't report the bed type, and its bed check is unknown, not ok, when the printable height or Klipper's Z travel wasn't available. The message says the height wasn't checked.
  • save_gcode keeps the saved G-code file and returns outcome_error when recording the slice fails for any reason, not only a database or file error.
  • An ORCA_PRINTER_API_KEY holding a character that can't be sent in an HTTP header (a curly quote pasted from a word processor, say) is refused with a not_configured message instead of a raw encoding error. The message never repeats the key.
  • An OctoPrint reply that isn't a JSON object, and a Moonraker file-info reply that is the JSON value null, now return protocol_error. The first used to fail with a raw error (or, for null, read as offline or no job) and the second read as "no such file".
  • With OctoPrint, a refused API key on the job request is reported as auth_required or auth_rejected like any other request, instead of becoming a note.
  • The outcome store closes its database connection when it can't set up or upgrade the store (a locked or damaged file), instead of leaving it open for the caller.
  • A printer error's extra detail can no longer replace its error, message or hint.
  • A console error that is only Klipper's "Printer is shutdown" or "Printer is halted" line is no longer listed as a problem. The shutdown reason is reported on its own.

Changed

  • get_printer_status and wait_for_printer make one request fewer to a Klipper printer: the answer from the request that found the printer is reused once. Later polls of wait_for_printer still ask again.
  • A printer found through OrcaSlicer's profile is tried first with the protocol that answered last time at the same address, so a new session makes fewer attempts.
  • When a print that is already running is waiting for its heaters (OctoPrint reheating mid-print, or OctoPrint's first heat-up, which also shows file progress), the headline reads "Printing benchy: 28%, waiting for the heaters.", with the time left when it is known. A Klipper job's first heat-up still reads "Heating up to print benchy."
  • The headline says "almost done" when no time is left or progress is 100 %, instead of "about 1 min left".
  • connected in the status is false when the state is offline, OctoPrint keeps the job for a cancelled or errored print as Klipper does, and headline comes first in the result.
  • The list_print_history summary reads "Your last 3 successful prints with an estimate ran 9% longer than estimated (median)." (or shorter, or matched the estimate). It no longer names OrcaSlicer, because the estimate can come from another slicer's file.
  • ended_at in list_print_history carries the time zone offset, for example 2030-01-15T14:23+12:00.
  • ~/.orcaslicer-mcp/printer.json is now created readable only by its owner.

Documentation

  • The README and the wait_for_printer text say that with OctoPrint, waiting for printing means waiting until the job is running with the heaters at temperature, because OctoPrint reports no extrusion.
  • The README says the outcome store keeps a fingerprint of the objects' names and sizes, not their geometry, and save_gcode describes it the same way.
  • The README says a finished print's row deleted from the store by hand comes back, without its saved slice settings, while its job is still in Moonraker's history, and that deleting the job there too drops it for good.
  • The printer address setting in the Claude Desktop extension and the registry listing says a password in the address is stored as an ordinary setting, so the API key is the better choice.
  • list_print_history and recall_prints say "the slicer's estimate", because an estimate can come from another slicer's file.
  • The marketplace listing (lhm.plugin.json) now takes its tool descriptions from the live server with scripts/gen_lhm_tools.py, and a test keeps it from going stale. Before, many descriptions stopped mid-sentence or carried old [needs M4b] tags.

v0.1.15

Choose a tag to compare

@MaxEllis MaxEllis released this 09 Oct 01:22

Added

  • Printer feedback: get_printer_status, wait_for_printer, list_print_history and check_printer_match. The server finds the printer from OrcaSlicer's active printer profile, or ORCA_PRINTER_URL. Klipper (Moonraker) printers get all four tools; OctoPrint gets status and waiting, with ORCA_PRINTER_API_KEY when it needs a key. Read-only: no command, G-code or file is ever sent to the printer. The server only reads, with HTTP GET requests (carrying the API key, or the user name and password from ORCA_PRINTER_URL, when you set them). wait_for_printer also returns early when the job ends before the point it waits for, as when a print is cancelled while it heats. Requested in orcaslicer-mcp#12.
  • The Claude Desktop extension has settings for the printer address, its API key and the printer name used in the outcome store.

Changed

  • httpx is now capped below 1.0. Its 1.0 pre-releases have no AsyncClient, so an install that resolved one (for example with pre-releases allowed) failed on the first printer or slicer call; the cap keeps a future 1.0 release from doing the same to fresh installs.
  • The outcome store is now owned by this project (klipper-mcp carries a copy) and works without klipper-mcp. save_gcode always records the slice, with OrcaSlicer's time and filament estimates, and list_print_history adds finished prints with the printer's failure reason. New default location ~/.orcaslicer-mcp/outcomes/; an existing ~/projects/_shared/print-outcomes/ is still used. The store upgrades itself in place by adding columns, so older versions can still read it.
  • recall_prints rows include the failure reason and OrcaSlicer's estimates. duration_s is Moonraker's whole job time, including heating up and any pauses, so beside the estimates it overstates an overrun; list_print_history compares the print time, which leaves both out, with the estimate. filament_g is the G-code file's own estimate, because printers report filament in millimetres, not grams.
  • A new outcome store's printer_id column defaults to unknown, the same value the store module uses when a caller passes no printer. Existing stores keep the default they were created with; every write names its printer anyway.

Security

  • get_preset_config could show part of a printer password to the model. It removed user:password@ from print_host and print_host_webui only when the password had no / or space in it, so http://user:pa/ss@host came back unchanged. It now hides everything between the scheme and the last @, whatever the password contains. A URL with an @ in its path also loses the part before that @, because it looks the same as a password with a / in it.

Documentation

  • README: the introduction, security notes and privacy policy now name the printer as the one other place the server connects to, read-only, and the data-retention entry lists the outcome store and printer.json.
  • docs/order-of-operations.md explains why filament edits come before print edits on a multi-filament setup (per-filament keys are read merged but written to the one preset open in the Filament tab, and select_preset discards unsaved overrides in every group), with a recipe for setting up a multi-material plate. Linked from the README and from the set_config and select_preset docstrings.
  • set_config warns against echoing a get_config value back for a per-filament setting (hot_plate_temp, fan_min_speed, nozzle_temperature_initial_layer, ...). get_config reports those merged across every loaded filament, while the write lands in the one filament preset open in the Filament tab, so the merged string corrupted that preset's list. Reported by @RoyPorter (orcaslicer-mcp#9); OrcaSlicer MCP v2.4.2-mcp.12 rejects the merged shape instead of storing it.
  • select_preset says that it discards unsaved overrides in every preset group, not only the one being switched, and that newer slicer builds list the affected groups as discarded_changes. Reported by @RoyPorter (orcaslicer-mcp#10).

Known issues

  • compare_settings and compare_slices snapshot with get_config and restore with set_config, so for a per-filament key on a multi-filament setup the restore writes back the merged list. That never actually restored the original: it corrupted the filament preset the same way a manual write did. On OrcaSlicer MCP v2.4.2-mcp.12 and later the restore now fails loudly with per_filament_length_mismatch instead of corrupting silently; re-select the filament preset to recover. Making the snapshot/restore path per-filament aware is still to do.

v0.1.14

Choose a tag to compare

@MaxEllis MaxEllis released this 01 Oct 22:19

Security

  • Config writes that would change a key able to run code or drive the printer are refused with blocked_by_local_policy before they reach OrcaSlicer. They are post_process, every *_gcode template, printer_model, printer_technology, filename_format, and the printer connection settings (print_host, print_host_webui, printhost_*, host_type, bbl_use_printhost, printer_agent, flashforge_serial_number). This covers set_config, apply_and_slice, edit_preset, compare_settings, compare_slices and set_object_config. The fork's PUT /config accepts any preset key and post_process runs through the shell after export, so an assistant steered by injected text could otherwise save a command into a user preset. Thanks to @ferpa for the original change.
  • Writing back an unchanged value passes, compared the way the fork serializes it (true is 1). The host address and credentials are always refused, because OrcaSlicer never reports their current value.
  • edit_preset checks against the named preset before selecting it, so a refusal no longer discards unsaved overrides. The compare_* snapshot restores skip the check, since they write back values just read from OrcaSlicer, so a restore never waits on an extra read.
  • ORCA_MCP_ALLOW_KEYS opts specific keys back in. Wildcards such as *_gcode work, and the Claude Desktop extension exposes it as a setting. Names that match no protected key are logged at startup.
  • get_preset_config hides printhost_apikey, printhost_user and printhost_password, and removes any user:password@ from print_host and print_host_webui. The fork returns preset config unfiltered, unlike GET /config. Writes carrying the <redacted> placeholder are refused, so a round-tripped preset never overwrites a real credential.
  • OrcaSlicer MCP v2.4.2-mcp.10 and later enforce the same rule inside the slicer, through Preferences → Remote API → Allow script, G-code and connection edits (off by default). When the slicer refuses a key, the tool reply carries a hint that says where the switch is.

Documentation

  • README: Windows fallback for uvx failing on pywin32 with a sharing violation (pip venv, which retries). Findings in docs/windows-install-findings-2026-09-22.md, including the upstream 2.4.x "Profile syncing change" dialog and the fork's startup remove_all crash on a locked AppData datadir.

Pairs with the OrcaSlicer MCP fork v2.4.2-mcp.10, which applies the same rule inside the slicer.

Thanks to @ferpa for the original change (#7).

Install or upgrade with uvx orcaslicer-mcp; the Claude Desktop extension is the attached .mcpb.

v0.1.13

Choose a tag to compare

@MaxEllis MaxEllis released this 17 Sep 03:44

Fixed

  • edit_preset on a filament preset is no longer blocked by the print preset that happens to be selected. The physics gate now knows which preset layers feed each check: for filament edits, checks that mix filament inputs with print speeds (flow_ceiling, temp_vs_flow) are returned as cross_layer_warnings instead of physics_blocked, while filament-only checks (fan range, first-layer temperature) still block. Print-preset edits are unchanged and still block on the flow ceiling of the selected filament. Reported via a fork by shadow-fight.
  • save_preset docstring now says when detach=True is needed (creating a filament preset for a different material than the selected one).

Thanks to @shadow-fight for finding this in their fork.

Install or upgrade with uvx orcaslicer-mcp; the Claude Desktop extension is the attached .mcpb.

v0.1.12

Choose a tag to compare

@MaxEllis MaxEllis released this 10 Sep 02:34

Full Changelog: v0.1.11...v0.1.12

v0.1.11

Choose a tag to compare

@MaxEllis MaxEllis released this 09 Sep 04:27

Full Changelog: v0.1.10...v0.1.11

v0.1.10

Choose a tag to compare

@MaxEllis MaxEllis released this 06 Sep 21:19

Full Changelog: v0.1.9...v0.1.10

v0.1.9

Choose a tag to compare

@MaxEllis MaxEllis released this 07 Aug 03:04

Full Changelog: v0.1.8...v0.1.9

v0.1.8

Choose a tag to compare

@MaxEllis MaxEllis released this 30 Jul 21:53

Full Changelog: v0.1.7...v0.1.8