Klipper has no command that stops a macro to wait for a reply. Mainsail and Fluidd fill the gap with prompt dialogs that a macro opens and the buttons answer.
To get user input in a Klipper macro, open a prompt dialog: send RESPOND TYPE=command MSG="action:prompt_begin <title>", add text and buttons, then action:prompt_show. Mainsail (v2.9.0 or newer) and Fluidd (v1.27.0 or newer) draw the dialog, and each button runs the G-code you assign to it.
Yes, through the web interface. Klipper has no blocking input command, and its G-code reference lists no M0 or M1. A macro can print action:prompt_* messages with RESPOND TYPE=command, which Mainsail and Fluidd turn into a dialog with buttons. Each button runs G-code, usually another macro, which carries out the choice.
The macro that opens the dialog keeps going. Klipper evaluates a macro “in entirety and only then” runs its commands, so lines after action:prompt_show run without waiting. Put whatever depends on the answer in the button’s macro.
How to show a prompt dialog from a Klipper macro
- Enable RESPOND. Add an empty
[respond] section to printer.cfg. Klipper only registers RESPOND when that section exists.
- Write the prompt macro. Start it with
action:prompt_begin, add action:prompt_text lines and buttons, and end with action:prompt_show.
- Write one macro per button. Each one closes the dialog with
action:prompt_end, then does its job. Clicking a button does not close the dialog in either interface.
- Restart and test. Run
RESTART to reload the config, then type the prompt macro’s name in the console.
This prompt asks which material is loaded and heats the nozzle to match:
[respond]
[gcode_macro PICK_MATERIAL]
description: Ask which material is loaded, then heat for it
gcode:
RESPOND TYPE=command MSG="action:prompt_begin Load filament"
RESPOND TYPE=command MSG="action:prompt_text Which material is in the extruder?"
RESPOND TYPE=command MSG="action:prompt_button_group_start"
RESPOND TYPE=command MSG="action:prompt_button PLA|_HEAT_FOR TEMP=210|primary"
RESPOND TYPE=command MSG="action:prompt_button PETG|_HEAT_FOR TEMP=240|primary"
RESPOND TYPE=command MSG="action:prompt_button ABS|_HEAT_FOR TEMP=250|primary"
RESPOND TYPE=command MSG="action:prompt_button_group_end"
RESPOND TYPE=command MSG="action:prompt_footer_button Close|_PROMPT_CLOSE"
RESPOND TYPE=command MSG="action:prompt_show"
[gcode_macro _HEAT_FOR]
gcode:
{% set temp = params.TEMP|default(210)|int %}
RESPOND TYPE=command MSG="action:prompt_end"
M109 S{temp}
RESPOND MSG="Nozzle at {temp} C. Feed the filament."
[gcode_macro _PROMPT_CLOSE]
gcode:
RESPOND TYPE=command MSG="action:prompt_end"
The temperatures are examples, so set your filament’s values. TEMP=210 after the pipe passes a value to the button’s macro (macro parameters covers reading it). Names starting with _ keep the helpers off the macro panel in both interfaces.
Klipper macro prompt commands
Send each command as RESPOND TYPE=command MSG="action:...". TYPE=command adds the // prefix both interfaces watch for.
| Command |
What it does |
Fluidd |
prompt_begin <title> |
Starts a new prompt with this headline |
Yes |
prompt_text <text> |
Adds a line of text |
Yes |
prompt_button <label>|<gcode>|<color> |
Adds a button; G-code and color are optional |
Yes |
prompt_button_group_start / _end |
Puts the buttons between them on one row |
Ignored |
prompt_footer_button <label>|<gcode>|<color> |
Adds a button to the dialog footer |
Yes |
prompt_show |
Opens the dialog |
Yes |
prompt_end |
Closes it |
Yes |
Mainsail’s colors are primary, secondary, info, warning and error. A button with no G-code runs its label as the command. Fluidd’s prompt code skips the group lines and stacks every button on its own row.
During a print, pause it and let the buttons resume or cancel. PAUSE stops Klipper reading the print file, but the macro that called it carries on: lines after PAUSE in the same macro still run. After PAUSE, put only the prompt.
[gcode_macro CHECK_PLATE]
description: Hold the print until the plate is confirmed
gcode:
PAUSE
RESPOND TYPE=command MSG="action:prompt_begin Check the build plate"
RESPOND TYPE=command MSG="action:prompt_text Is the plate clean and seated?"
RESPOND TYPE=command MSG="action:prompt_footer_button Cancel|_PLATE_CANCEL|error"
RESPOND TYPE=command MSG="action:prompt_footer_button Start|_PLATE_OK|primary"
RESPOND TYPE=command MSG="action:prompt_show"
[gcode_macro _PLATE_OK]
gcode:
RESPOND TYPE=command MSG="action:prompt_end"
RESUME
[gcode_macro _PLATE_CANCEL]
gcode:
RESPOND TYPE=command MSG="action:prompt_end"
CANCEL_PRINT
Call CHECK_PLATE on its own line in your slicer’s start G-code, or as the last line of PRINT_START. Any command after it inside PRINT_START runs before anyone clicks. RESUME returns the toolhead to the position captured at the pause. If your PAUSE macro parks the head (pause and resume macros), the head moves before the dialog opens.
Outside a print, PAUSE holds nothing, because there is no print file to stop. A standalone macro has to hand its remaining steps to the buttons. To wait on heaters, moves or a timer instead of a person, see waiting in a Klipper macro.
If you know the value before the macro runs, skip the dialog and pass a parameter: _HEAT_FOR TEMP=240 from the console or the slicer, read inside the macro as params.TEMP. Parameters need no interface support.
Why the prompt does not appear
Unknown command:"RESPOND": the [respond] section is missing, or Klipper has not restarted since you added it.
- No dialog, but the console shows
// action:prompt_... lines: the interface is older than Mainsail v2.9.0 or Fluidd v1.27.0, or prompt_show was never sent.
- Text or a button is cut short: Klipper reads
# in printer.cfg and ; on any G-code line as the start of a comment, even inside quotes. Keep both characters out of prompt text.
- A button command breaks: a second pair of double quotes inside
MSG="..." breaks the quoting. Point the button at a helper macro instead of nesting quoted commands.
- The dialog stays open: the button’s macro never sent
action:prompt_end.