Commands
Run shell commands. Short ones answer inline, long ones return an id to poll.
Run a command
Needs the exec permission. Answers within 28 s.
Starts a command on the screen. If it ends within wait_s (default 25) the reply is 200 with exit code and output (max_bytes and tail shape it). Otherwise 202 with the exec id: poll getExec. timeout_s: 0 runs with no limit (dev servers, bots). The command keeps running if the connection drops; resend with the same Idempotency-Key and you get the same exec, never a second run.
path Parameters
screen_id^scr_[0-9a-z]{20}$ · requiredScreen id (scr_...).
Headers
Idempotency-Key^[ -~]+$Any unique string, ideally a UUIDv7; the SDK and MCP always send one. A retry with the same key and body gets the stored answer instead of running twice (kept 24 h for screens and power, 10 minutes for actions and commands). Stored once execution began: 2xx, 500 and 504. Never stored when outcome is not_applied (400, 401, 403, 404, 409, 415, 422, 429), so the same key can be retried after a conflict or a rate limit. Replays of runActions keep per-action results and shot metadata only, capture a fresh screenshot and carry Idempotent-Replayed: true. Same key, different body: 422 IDEMPOTENCY_KEY_REUSED. Same key still running: 409 IDEMPOTENCY_KEY_IN_USE.
Kubi-Run^[ -~]{1,100}$Optional label that groups calls into one run in the screen's history. It is only a label and never locks the screen. The SDK fills it from KUBI_RUN, else Claude Code's CLAUDE_CODE_SESSION_ID, else one id per client it creates.
Run a command › Request Body
commandShell command, run with bash -lc as the desktop user. Send this or argv.
argvProgram and arguments, no shell. Send this or command.
cwdstdinWritten to stdin, then closed.
timeout_s0: no limit (dev servers, bots). At the limit we send TERM, then KILL after 10 s; status timed_out. Runs on after the call returns.
wait_sAnswer inline if done within this; else 202 and an id to poll.
max_bytesBytes of output per stream in this reply.
tailtrue: the last max_bytes after the offset (errors and exit lines). false: the first.
Run a command › Responses
Finished within wait_s.
id^ex_[0-9a-z]{20}$ · requiredscreen_id^scr_[0-9a-z]{20}$ · requiredlost: the screen restarted mid-run; the exit status is unknown. Never rerun blindly.
started_atstdoutOutput from stdout_from, up to max_bytes (head or tail). UTF-8, invalid bytes replaced.
stderrstdout_bytesTotal bytes written so far. Use as the next stdout_from.
stderr_bytesincarnationoutput_droppedOlder output fell out of the 1 MiB per-stream buffer.
Get a command's status and output
Needs the exec permission. Answers within 28 s.
Status, exit code and output from byte offsets. With wait_s, until=exit (default) holds the reply until the command ends; until=output answers as soon as it prints (for live log views). Output keeps the last 1 MiB per stream for 24 h after exit.
path Parameters
screen_id^scr_[0-9a-z]{20}$ · requiredScreen id (scr_...).
exec_id^ex_[0-9a-z]{20}$ · requiredExec id (ex_...) from startExec.
query Parameters
wait_sLong poll: hold the reply up to this many seconds until something changes. 0 answers at once. Capped at 25 so every call ends within 30 s.
untilWhat ends a long poll: exit (default) or output.
stdout_fromByte offset in stdout to read from (the last reply's stdout_bytes).
stderr_fromByte offset in stderr to read from (the last reply's stderr_bytes).
max_bytesBytes of output per stream in this reply.
tailtrue: the last max_bytes after the offset. false: the first.
Headers
Kubi-Run^[ -~]{1,100}$Optional label that groups calls into one run in the screen's history. It is only a label and never locks the screen. The SDK fills it from KUBI_RUN, else Claude Code's CLAUDE_CODE_SESSION_ID, else one id per client it creates.
Get a command's status and output › Responses
Success.
id^ex_[0-9a-z]{20}$ · requiredscreen_id^scr_[0-9a-z]{20}$ · requiredlost: the screen restarted mid-run; the exit status is unknown. Never rerun blindly.
started_atstdoutOutput from stdout_from, up to max_bytes (head or tail). UTF-8, invalid bytes replaced.
stderrstdout_bytesTotal bytes written so far. Use as the next stdout_from.
stderr_bytesincarnationoutput_droppedOlder output fell out of the 1 MiB per-stream buffer.
Stop a command
Needs the exec permission. Answers within 12 s.
Sends a signal to the command's process group. TERM then KILL after 10 s.
path Parameters
screen_id^scr_[0-9a-z]{20}$ · requiredScreen id (scr_...).
exec_id^ex_[0-9a-z]{20}$ · requiredExec id (ex_...) from startExec.
Headers
Idempotency-Key^[ -~]+$Any unique string, ideally a UUIDv7; the SDK and MCP always send one. A retry with the same key and body gets the stored answer instead of running twice (kept 24 h for screens and power, 10 minutes for actions and commands). Stored once execution began: 2xx, 500 and 504. Never stored when outcome is not_applied (400, 401, 403, 404, 409, 415, 422, 429), so the same key can be retried after a conflict or a rate limit. Replays of runActions keep per-action results and shot metadata only, capture a fresh screenshot and carry Idempotent-Replayed: true. Same key, different body: 422 IDEMPOTENCY_KEY_REUSED. Same key still running: 409 IDEMPOTENCY_KEY_IN_USE.
Kubi-Run^[ -~]{1,100}$Optional label that groups calls into one run in the screen's history. It is only a label and never locks the screen. The SDK fills it from KUBI_RUN, else Claude Code's CLAUDE_CODE_SESSION_ID, else one id per client it creates.
Stop a command › Request Body optional
signalStop a command › Responses
Success.
id^ex_[0-9a-z]{20}$ · requiredscreen_id^scr_[0-9a-z]{20}$ · requiredlost: the screen restarted mid-run; the exit status is unknown. Never rerun blindly.
started_atstdoutOutput from stdout_from, up to max_bytes (head or tail). UTF-8, invalid bytes replaced.
stderrstdout_bytesTotal bytes written so far. Use as the next stdout_from.
stderr_bytesincarnationoutput_droppedOlder output fell out of the 1 MiB per-stream buffer.