Skip to content

moonraker

tested on simulator

Tier Tier 1
Protocol Moonraker JSON-RPC over HTTP, Moonraker JSON-RPC over WebSocket
Covers Klipper 3D printers (Voron, RatRig, Creality K1 and Sonic Pad, Sovol SV08, Elegoo Neptune 4, Qidi)
Hazard default medium
Conformance control
Tested with Moonraker simulator over an HTTP mock transport and a real local WebSocket server

Estimated reach. Every Klipper install with Moonraker, hundreds of printer models. Moonraker is the API server that Mainsail and Fluidd need, so practically every Klipper printer runs it. Klipper's config folder ships several hundred printer and board configurations, and several vendors now ship Klipper with Moonraker from the factory.

The moonraker driver talks to Klipper printers through Moonraker, the API server behind Mainsail and Fluidd. The driver reads printer objects (heaters, sensors, fans, print state, toolhead), sets heater targets and fan speeds with Klipper G-code, and runs homing and print control.

Driver namemoonraker
Librarieshttpx 0.28.1 (BSD-3-Clause), websockets 17.3 (BSD-3-Clause)
Extrauv tool install --compile-bytecode "openhal-hub[moonraker] @ git+https://github.com/sohan-bhat/OpenHAL"
Hazard defaultmedium
Safe statenative. TURN_OFF_HEATERS. printer.emergency_stop only when emergency_stop_on_stop is true
Self-describeyes, from printer.objects.list and the configfile object

What it supports

Channel nameKindPrinter object and field
stateread, enumprint_stats.state (standby, printing, paused, complete, cancelled, error)
klippy_state, filenameread, stringwebhooks.state, print_stats.filename
extruder_temp, bed_temp, chamber_tempread, temperatureextruder, heater_bed, temperature_sensor chamber
progressread, percentvirtual_sdcard.progress times 100
position_x, position_y, position_z, homed_axesreadtoolhead.position, toolhead.homed_axes
extruder_target, bed_targetwrite, temperatureSET_HEATER_TEMPERATURE HEATER=... TARGET=..., read back from target
fan_speedwrite, percentM106 S0..255, read back from fan.speed
home (arg axes x, y, z, xy or all)actionG28
pause, resume, cancelactionprinter.print.pause, resume, cancel

Other names need a map.

MapMeaning
{ object: "temperature_sensor chamber", field: temperature }Any object and field. index picks a list element, scale multiplies
{ heater: enclosure }A heater_generic (or extruder1, heater_bed) target
{ fan: exhaust }A fan_generic speed, set with SET_FAN_SPEED
{ command: home }Run home, pause, resume or cancel under another action name

Temperatures are degC on the wire and converted to the channel unit both ways. Fan percent maps to M106 S as round(percent * 255 / 100) and to SET_FAN_SPEED SPEED as percent / 100.

The driver deliberately has no raw G-code action.

How the protocol is handled

  • transport: http polls one object per read, while transport: websocket subscribes to every object the file uses with printer.objects.subscribe, keeps a cache that notify_status_update refreshes, and reads from the cache without a round trip.
  • An API key, when Moonraker requires one, is read from the environment variable named in token_env and sent as X-Api-Key.
  • G-code requests return when Klipper has finished the command. Because the hub's driver timeout is 10 s, home waits up to action_wait, then returns started and finishes in the background with a deadline of 300 s.
  • Klipper refuses heater targets above max_temp in printer.cfg, and that error, like every other Klipper or Moonraker error, fails the command with the original message.
  • health() reads printer.info (or the subscribed webhooks object). Anything but ready reports the printer as disconnected with Klipper's own message, for example an MCU shutdown.
  • match.moonraker is checked against printer.info on connect, with glob patterns, so a file can't drive the wrong printer.

Setup

  1. Install the extra with uv tool install --compile-bytecode "openhal-hub[moonraker] @ git+https://github.com/sohan-bhat/OpenHAL".
  2. If Moonraker has [authorization] with API keys, put the key in an environment variable such as MOONRAKER_API_KEY and set token_env. Otherwise add the hub's address to trusted_clients.
  3. Start from openhal/drivers/moonraker/examples/voron-2-4.hal.yaml, or from the driver's describe() output.
  4. Validate with openhal file validate, then confirm the limits by hand.

Parameters

KeyDefaultMeaning
hostrequiredMoonraker host name or address
port7125Moonraker port
schemehttphttp or https (and ws or wss for the WebSocket)
transporthttphttp to poll, websocket to subscribe
token_envnoneEnvironment variable that holds the API key
timeout5 sDeadline for each request
action_wait8 sHow long home waits before returning started. At most 9 s
emergency_stop_on_stopfalseAlso call printer.emergency_stop during the safe state

Example device file

device: { name: Voron 2.4, manufacturer: Voron Design }
id: voron
match: { moonraker: { hostname: "voron*" } }
connect: { moonraker: voron.local, port: 7125, transport: websocket }
read:
  state: { type: enum, values: [standby, printing, paused, complete, cancelled, error], every: 1 s }
  extruder_temp: { unit: degC, every: 1 s, range: [0, 320] }
  bed_temp: { unit: degC, every: 1 s, range: [0, 130] }
write:
  extruder_target: { unit: degC, min: 0, max: 260, max_change_per_s: 50, confirm: confirm }
  bed_target: { unit: degC, min: 0, max: 110, max_change_per_s: 20 }
actions:
  home: { args: { axes: { type: enum, values: [x, y, z, xy, all] } }, require: ["state != printing"] }
safe_state:
  - { extruder_target: 0, bed_target: 0 }
hazard: medium

Known limitations

  • File uploads and starting prints are not exposed.
  • exclude_object, macros and other Klipper commands need their own driver support, because the driver deliberately has no raw G-code action.
  • With transport: http each read is one request, so poll intervals under about 200 ms per channel will load the printer's host.
  • Because the safe state needs Moonraker to be reachable, Klipper's own max_temp, verify_heater and MCU watchdogs remain the protection when the network is down. Set watchdog.on_loss: hold when you'd rather let a print continue through a network drop.

Hazard defaults

The default hazard is medium, because heaters and moving axes can burn or pinch, so keep confirm: confirm on the hotend target and on home.

Sources