Repository navigation
Releases: MaxEllis/orcaslicer-mcp
Releases · MaxEllis/orcaslicer-mcp
Release list
v0.1.17
Added
- Plate tools for fork v2.4.2-mcp.13 and later.
list_platesshows each plate's index, name, lock state, build volume and objects, and which one is current.add_plateadds one.select_platepicks the plate thatslice_and_wait,get_gcode,render_plateandget_job_statusact on.delete_plateremoves a plate; its objects are parked beside the bed and the reply counts them.move_object_to_platekeeps an object's position relative to its old plate, and an object parked beside the bed lands at the plate's centre.list_objectsshows each object's plate. On an older build these tools say they need fork v2.4.2-mcp.13 or later. arrange_platewarns that with several plates it packs every unlocked plate together again.transform_objectsays 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
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(ornot_reachablewhen the connection drops) with a message. - An
ORCA_PRINTER_API_KEYpasted 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.jsoncan 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 aprinterentry 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_statusno 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_printertreats a job that completes successfully while it waits forprintingorfirst_layer_doneas 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_printerno 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.jsonholding 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_historyshows 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_historyreads 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_historysays what to do when the printer answers 404 for its history list: Moonraker versions before 0.9 need a[history]section inmoonraker.conf, so add one and restart Moonraker. Before, it reported only the HTTP status.list_print_historycopies 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 checkORCA_API_TOKEN. The hint points at the server's OrcaSlicer settings (ORCA_API_URL,ORCA_API_TIMEOUT) anddetailnames the problem. check_printer_matchno longer reports Klipper's[firmware_retraction]section asabsentwhen retraction is off and Klipper's settings were never read. The printer side is empty then.check_printer_matchsays when OrcaSlicer didn't report the bed type, and its bed check isunknown, notok, when the printable height or Klipper's Z travel wasn't available. The message says the height wasn't checked.save_gcodekeeps the saved G-code file and returnsoutcome_errorwhen recording the slice fails for any reason, not only a database or file error.- An
ORCA_PRINTER_API_KEYholding a character that can't be sent in an HTTP header (a curly quote pasted from a word processor, say) is refused with anot_configuredmessage 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 returnprotocol_error. The first used to fail with a raw error (or, fornull, 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_requiredorauth_rejectedlike 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,messageorhint. - 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_statusandwait_for_printermake one request fewer to a Klipper printer: the answer from the request that found the printer is reused once. Later polls ofwait_for_printerstill 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".
connectedin the status is false when the state isoffline, OctoPrint keeps the job for a cancelled or errored print as Klipper does, andheadlinecomes first in the result.- The
list_print_historysummary reads "Your last 3 successful prints with an estimate ran 9% longer than estimated (median)." (orshorter, ormatched the estimate). It no longer names OrcaSlicer, because the estimate can come from another slicer's file. ended_atinlist_print_historycarries the time zone offset, for example2030-01-15T14:23+12:00.~/.orcaslicer-mcp/printer.jsonis now created readable only by its owner.
Documentation
- The README and the
wait_for_printertext say that with OctoPrint, waiting forprintingmeans 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_gcodedescribes 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_historyandrecall_printssay "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 withscripts/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
Added
- Printer feedback:
get_printer_status,wait_for_printer,list_print_historyandcheck_printer_match. The server finds the printer from OrcaSlicer's active printer profile, orORCA_PRINTER_URL. Klipper (Moonraker) printers get all four tools; OctoPrint gets status and waiting, withORCA_PRINTER_API_KEYwhen 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 fromORCA_PRINTER_URL, when you set them).wait_for_printeralso 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
httpxis now capped below 1.0. Its 1.0 pre-releases have noAsyncClient, 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_gcodealways records the slice, with OrcaSlicer's time and filament estimates, andlist_print_historyadds 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_printsrows include the failure reason and OrcaSlicer's estimates.duration_sis Moonraker's whole job time, including heating up and any pauses, so beside the estimates it overstates an overrun;list_print_historycompares the print time, which leaves both out, with the estimate.filament_gis the G-code file's own estimate, because printers report filament in millimetres, not grams.- A new outcome store's
printer_idcolumn defaults tounknown, 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_configcould show part of a printer password to the model. It removeduser:password@fromprint_hostandprint_host_webuionly when the password had no/or space in it, sohttp://user:pa/ss@hostcame 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.mdexplains 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, andselect_presetdiscards unsaved overrides in every group), with a recipe for setting up a multi-material plate. Linked from the README and from theset_configandselect_presetdocstrings.set_configwarns against echoing aget_configvalue back for a per-filament setting (hot_plate_temp,fan_min_speed,nozzle_temperature_initial_layer, ...).get_configreports 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_presetsays that it discards unsaved overrides in every preset group, not only the one being switched, and that newer slicer builds list the affected groups asdiscarded_changes. Reported by @RoyPorter (orcaslicer-mcp#10).
Known issues
compare_settingsandcompare_slicessnapshot withget_configand restore withset_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 withper_filament_length_mismatchinstead 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
Security
- Config writes that would change a key able to run code or drive the printer are refused with
blocked_by_local_policybefore they reach OrcaSlicer. They arepost_process, every*_gcodetemplate,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 coversset_config,apply_and_slice,edit_preset,compare_settings,compare_slicesandset_object_config. The fork'sPUT /configaccepts any preset key andpost_processruns 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 (
trueis1). The host address and credentials are always refused, because OrcaSlicer never reports their current value. edit_presetchecks against the named preset before selecting it, so a refusal no longer discards unsaved overrides. Thecompare_*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_KEYSopts specific keys back in. Wildcards such as*_gcodework, and the Claude Desktop extension exposes it as a setting. Names that match no protected key are logged at startup.get_preset_confighidesprinthost_apikey,printhost_userandprinthost_password, and removes anyuser:password@fromprint_hostandprint_host_webui. The fork returns preset config unfiltered, unlikeGET /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
hintthat says where the switch is.
Documentation
- README: Windows fallback for
uvxfailing onpywin32with a sharing violation (pip venv, which retries). Findings indocs/windows-install-findings-2026-09-22.md, including the upstream 2.4.x "Profile syncing change" dialog and the fork's startupremove_allcrash 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
Fixed
edit_preseton 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 ascross_layer_warningsinstead ofphysics_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_presetdocstring now says whendetach=Trueis 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.