Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Protocol

Message format

Every message is one JSON object. A request names a command in t; include an id when you want a correlated reply (reads), omit it for fire-and-forget (HID writes).

// request  → fire-and-forget (no id)
{ "t": "hid.move", "dx": 30, "dy": -5 }

// request  → with id, expects a reply
{ "t": "screen.pixel", "id": 7, "x": 100, "y": 50 }
// response →
{ "id": 7, "r": 139, "g": 0, "b": 0 }

// subscribe → the server then pushes frames as state changes
{ "t": "subscribe", "events": ["mouse", "input"] }
{ "t": "mouse", "x": 812, "y": 344 }

On connect, the server sends a hello frame with the protocol version and whether auth is required, so a client can verify compatibility with no round-trip.

Command surface

CategoryCommands
HID writeshid.down, hid.up, hid.press, hid.type, hid.move, hid.move_to, hid.scroll
Screenscreen.pixel, screen.resolution, screen.capture, screen.displays
Systemsystem.mouse, system.window, system.time
Inputinput.keys, input.is_down, input.modifiers
Clipboardclipboard.get, clipboard.set
Windowwindow.list, window.find, window.activate, window.move
Eventssubscribe, unsubscribe (streams: mouse, window, input)
Metahello, ping, auth, lua.exec

system.window reads the active (foreground) window; the window.* commands list, find, activate, and move windows.

screen.capture (protocol 1.1.0+) returns a display as a base64 PNG at native resolution plus its geometry and the cursor position, and screen.displays enumerates monitors with signed virtual-desktop origins — together the basis for screenshot-driven, computer-use-style automation. The hello frame advertises the server’s protocol version so a client can check for these before using them.

Screen and Window commands depend on platform support — both are limited or absent on Linux; Clipboard is available on Windows and macOS. See Platforms & limits.

Authentication

Auth is off by default (fine on localhost). To require a token, set AUTH_TOKEN at the top of remote_access.lua before installing, then have the client send { "t": "auth", "token": "..." } first. The lua.exec escape hatch (arbitrary Lua) is disabled unless you set ALLOW_LUA_EXEC = true — leave it off unless you trust every client.

Performance

Measured on localhost (Windows host, release build):

MetricValue
RPC round-trip p50~1 ms
RPC round-trip p99~2 ms
Sustained RPC throughput (16 in-flight)~10,000 req/s
Server-side message drain~12,000 msg/s
Fire-and-forget wire throughput~100,000 msg/s

Round-trips are sub-millisecond over localhost and a wired LAN — the transport won’t be your bottleneck.