Spacesd client and processes
SpacesdClient: the cua-spacesd client, running processes in a sandbox, and sandboxes without cua-spacesd.
sandbox.spacesd(), space.spacesd() (or cua.spacesd(url, token) for any spacesd) returns a SpacesdClient. It picks native gRPC or gRPC-Web, sends the token and chunks transfers. Processes are below; files and the computer and media have their own pages.
Python programs usually use the high-level API instead: cua_sandbox interfaces.
cua-spacesd is optional: images without it still boot and serve their declared services, and sandbox.spacesd() raises SpacesdNotAvailable. capabilities() reports what this spacesd supports (has_feature(name) checks one feature). call_json(method, json) reaches every cua.env.v1 RPC of the protocol, including those without a typed method.
From a Space#
Methods of Space.
Space.spacesd#
The cua-spacesd client over the connection this Space authenticated.
def spacesd(self) -> SpacesdClientReturns SpacesdClient · Raises CuaError
SpacesdClient#
Client for one cua-spacesd.
Returned by Cua.spacesd, Relay.connect, Sandbox.spacesd, Space.spacesd.
| Method | Description |
|---|---|
call_json | Calls any unary cua.env.v1 RPC with a proto3-JSON request and returns the proto3-JSON response. |
call_json_stream | Calls a server-streaming cua.env.v1 RPC and collects at most max_messages responses (or until the stream ends or timeout_ms elapses). |
capabilities | GetCapabilities (cached). |
diagnose | Runs the image self-test (SystemService.Diagnose, the checks of cua-spacesd doctor) and returns the report as JSON (schema version 1, libs/cua/proto/diagnose-report.schema.json). |
forward_tcp | Forwards a TCP port on this machine to guest port through cua-spacesd's tunnel: works for any Space this client reaches (on this machine, one of your machines or the cloud). |
has_feature | Whether the guest supports feature. |
health | Health as proto3 JSON. |
http | Sends one plain-HTTP request to the spacesd port with this client's endpoint and credentials (through a gateway when the endpoint is behind one). |
open_download | Streams path in chunks: one read that resumes where a dropped stream stopped and checks each segment's SHA-256, delivered through a small buffer (memory stays bounded whatever the file size). |
route | Which way calls go now, in one line: local <host:port> (a Space on this machine), direct <address>, relay <relay URL> (the relay's HTTPS path), mesh direct <ip:port> rtt <ms> ms (end to end over the mesh, straight to the machine: a LAN neighbour), mesh relayed or cloud. |
agents | Coding agents in this guest. |
attach | Attaches to a running process by pid or tag. |
click | Left click. |
cursor_position | Pointer position. |
displays | Displays as proto3 JSON ([Display]). |
double_click | Double click. |
download | Downloads path into memory. |
download_file | Downloads path to a local file. |
drag | Drags with the left button. |
get_clipboard | Clipboard text. |
hotkey | Presses a chord (["ctrl", "c"]). |
keyboard_json | Full ComputerService.Keyboard from proto3 JSON. |
list_dir | ListDir (depth 1 = direct children), as user. |
list_processes | Guest processes as proto3 JSON ([ProcessInfo]). |
make_dir | MakeDir (with parents), as user: the new directories are owned by that user. |
move_path | Move: renames source to destination, as user. |
move_to | Moves the pointer. |
open_media | Opens a media session and starts delivering encoded video frames and control events to frames. |
open_media_with_audio | SpacesdClient.open_media that also delivers audio packets to audio (set options.audio to negotiate audio tracks). |
pointer_json | Full ComputerService.Pointer from proto3 JSON. |
press | Presses one key (enter, KEY_ESCAPE, a, ...). |
remove | Remove, as user. |
right_click | Right click. |
run | Runs a command to completion. |
screenshot | Captures a display. |
scroll | Scrolls by line deltas. |
set_clipboard | Sets clipboard text; returns the clipboard generation. |
sh | Runs line with /bin/sh -c to completion. |
spawn | Starts a command and returns its handle. |
stat | Stat. |
type_text | Types text. |
upload | Uploads bytes to path (chunked, resumable, SHA-256 verified). |
upload_file | Uploads a local file to path. |
| Accessor | Returns | Description |
|---|---|---|
endpoint() | String | Endpoint URL. |
json_methods() | Vec<String> | Methods reachable through call_json / call_json_stream. |
transport() | String | grpc or grpc-web. |
SpacesdClient.call_json#
Calls any unary cua.env.v1 RPC with a proto3-JSON request and
returns the proto3-JSON response. method is the full path
(/cua.env.v1.WindowsService/ListWindows) or Service/Method.
Covers windows, accessibility, driver tools, teleport, tunnels and
every other RPC without a typed method.
user makes a file request (FilesystemService Stat, ListDir,
MakeDir, Move, Remove, CreateWatcher, CreateSignedUrl,
BeginUpload) act as that guest user: it sets the request's
run_as (in header for BeginUpload) and checks that the guest
agent supports acting as another user. Any other method refuses it,
and so does a request that already names a different run_as.
async def call_json(self, method: str, request_json: str, user: Optional[str] = None) -> str| Parameter | Type | Default |
|---|---|---|
method | String | required |
request_json | String | required |
user | Option<String> | None |
Returns String · Async · Raises CuaError
SpacesdClient.call_json_stream#
Calls a server-streaming cua.env.v1 RPC and collects at most
max_messages responses (or until the stream ends or timeout_ms
elapses).
user acts as that guest user for WatchDir and ReadFile, as for
call_json.
async def call_json_stream(self, method: str, request_json: str, max_messages: int, timeout_ms: int, user: Optional[str] = None) -> List[str]| Parameter | Type | Default |
|---|---|---|
method | String | required |
request_json | String | required |
max_messages | u32 | required |
timeout_ms | u32 | required |
user | Option<String> | None |
Returns Vec<String> · Async · Raises CuaError
SpacesdClient.capabilities#
GetCapabilities (cached).
async def capabilities(self) -> SpacesdCapabilitiesReturns SpacesdCapabilities · Async · Raises CuaError
SpacesdClient.diagnose#
Runs the image self-test (SystemService.Diagnose, the checks of
cua-spacesd doctor) and returns the report as JSON (schema version
1, libs/cua/proto/diagnose-report.schema.json). options_json is a
proto3-JSON DiagnoseOptions ("{}" for the defaults: every check,
read-only). Falls back to DiagnoseOnce when the stream is cut.
async def diagnose(self, options_json: str) -> str| Parameter | Type | Default |
|---|---|---|
options_json | String | required |
Returns String · Async · Raises CuaError
SpacesdClient.forward_tcp#
Forwards a TCP port on this machine to guest port through
cua-spacesd's tunnel: works for any Space this client reaches (on
this machine, one of your machines or the cloud). bind is the
local address to listen on (default 127.0.0.1:0, a free loopback
port; 0.0.0.0:0 serves the LAN).
async def forward_tcp(self, port: int, bind: Optional[str]) -> SpacesdForward| Parameter | Type | Default |
|---|---|---|
port | u16 | required |
bind | Option<String> | required |
Returns SpacesdForward · Async · Raises CuaError
SpacesdClient.has_feature#
Whether the guest supports feature.
async def has_feature(self, feature: str) -> bool| Parameter | Type | Default |
|---|---|---|
feature | String | required |
Returns bool · Async · Raises CuaError
SpacesdClient.health#
Health as proto3 JSON.
async def health(self) -> strReturns String · Async · Raises CuaError
SpacesdClient.http#
Sends one plain-HTTP request to the spacesd port with this
client's endpoint and credentials (through a gateway when the
endpoint is behind one). Used for streamable-HTTP MCP at /mcp,
for example by typed cua-driver clients. Not retried.
async def http(self, request: SpacesdHttpRequest) -> SpacesdHttpResponse| Parameter | Type | Default |
|---|---|---|
request | SpacesdHttpRequest | required |
Returns SpacesdHttpResponse · Async · Raises CuaError
SpacesdClient.open_download#
Streams path in chunks: one read that resumes where a dropped
stream stopped and checks each segment's SHA-256, delivered through
a small buffer (memory stays bounded whatever the file size). Read it
with SpacesdDownload.next_chunk; dropping it, or cancel, stops
the transfer.
async def open_download(self, path: str, chunk_size: Optional[int] = None, user: Optional[str] = None) -> SpacesdDownload| Parameter | Type | Default |
|---|---|---|
path | String | required |
chunk_size | Option<u32> | None |
user | Option<String> | None |
Returns SpacesdDownload · Async · Raises CuaError
SpacesdClient.route#
Which way calls go now, in one line: local <host:port> (a Space on
this machine), direct <address>, relay <relay URL> (the relay's
HTTPS path), mesh direct <ip:port> rtt <ms> ms (end to end over the
mesh, straight to the machine: a LAN neighbour), mesh relayed or
cloud. A Space one of your own machines provides prefers the
direct path and falls back to the relay by itself (CUA_MESH=off
turns that off). A client made otherwise reports where its spacesd
runs (local, cloud, direct) and the endpoint it dials.
async def route(self) -> strReturns String · Async · Raises CuaError
SpacesdCapabilities record#
SystemService.GetCapabilities, summarized. json has everything.
Returned by SpacesdClient.capabilities.
| Field | Type | Default | Description |
|---|---|---|---|
version | String | spacesd version. | |
protocol_version / protocolVersion | u32 | cua.env.v1 protocol version. | |
protocol_revision / protocolRevision | u32 | Additive contract revision. | |
os_family / osFamily | String | OS family (linux, macos, windows). | |
os_name / osName | String | OS name. | |
os_version / osVersion | String | OS version. | |
arch | String | CPU architecture. | |
hostname | String | Guest hostname. | |
initialized | bool | SystemService.Init has run. | |
features | Vec<SpacesdFeature> | Feature flags. | |
json | String | The full response as proto3 JSON. |
SpacesdFeature record#
One capability flag.
| Field | Type | Default | Description |
|---|---|---|---|
name | String | Feature name (for example a11y, stream.h264, audio.desktop). | |
supported | bool | Supported in this guest. | |
limitation | Option<String> | Limitation when degraded or unsupported. | |
attributes | HashMap<String, String> | Extra attributes. |
SpacesdHttpRequest record#
A plain-HTTP request to the spacesd port (for example MCP at /mcp).
| Field | Type | Default | Description |
|---|---|---|---|
method | String | Method, for example POST. | |
path | String | Absolute path under the endpoint, for example /mcp. Never a URL. | |
headers | Vec<SpacesdHttpHeader> | [] | Extra headers. Credentials (authorization and the env headers) are the client's and cannot be set here. |
body | Vec<u8> | Request body (empty for none). | |
timeout_ms / timeoutMs | Option<u32> | None | Whole-request timeout; 30 s when unset. |
max_response_bytes / maxResponseBytes | Option<u64> | None | Response body cap; 16 MiB when unset. |
SpacesdHttpResponse record#
The spacesd's HTTP answer.
Returned by SpacesdClient.http.
| Field | Type | Default | Description |
|---|---|---|---|
status | u16 | Status code. | |
headers | Vec<SpacesdHttpHeader> | Response headers, in order. | |
body | Vec<u8> | Response body. |
SpacesdHttpHeader record#
One HTTP header (duplicates are kept in order).
| Field | Type | Default | Description |
|---|---|---|---|
name | String | Header name. | |
value | String | Header value. |
SpacesdDownload#
A download in progress (SpacesdClient.open_download).
Returned by SpacesdClient.open_download.
| Method | Description |
|---|---|
next_chunk | The next chunk, or None once the whole file arrived. |
| Accessor | Returns | Description |
|---|---|---|
cancel() | Stops the transfer. |
SpacesdDownload.next_chunk#
The next chunk, or None once the whole file arrived.
async def next_chunk(self) -> Optional[bytes]Returns Option<Vec<u8>> · Async · Raises CuaError
SpacesdForward#
A loopback (or bind) TCP port that reaches a guest port through
cua-spacesd's tunnel (SpacesdClient.forward_tcp). Stopped by stop
or when dropped.
Returned by SpacesdClient.forward_tcp.
| Method | Description |
|---|---|
stop | Stops listening and revokes the driver-side forward (also done when it is dropped). |
| Accessor | Returns | Description |
|---|---|---|
guest_port() | u16 | Guest port. |
local_addr() | String | host:port accepting connections. |
SpacesdForward.stop#
Stops listening and revokes the driver-side forward (also done when it is dropped).
async def stop(self) -> NoneAsync · Raises CuaError
Without cua-spacesd#
Any OCI image is a full Space on the container and microVM kinds: when the image carries no cua-spacesd (alpine:3.20, node:20), Cua puts a static one into it and runs it beside the image's own command, so exec, files and ports work. Pass spacesd=False to run the image as it is. The sandboxes without cua-spacesd are those: the macOS 15 image (macOS 26 runs cua-spacesd) and a VM of an image that ships no Cua disk (use kind container or microvm, or cua build FROM a Cua image), so sandbox.spacesd() fails for them. A local Lume sandbox is still reachable: commands over lume ssh, screenshots and the display over the VM's VNC endpoint. cua sb exec, cua sb screenshot and cua sb view use the same calls. Other sandboxes fail with Unsupported.
Python programs usually use the high-level API instead: cua_sandbox shell and screen.
Agentless methods#
Methods of Sandbox.
Sandbox.lacks_spacesd#
Whether this sandbox has no cua-spacesd: it declares no env
service, or its image says it does not carry one. spacesd() fails
for these; guest_sh, guest_screenshot and guest_display reach a
local Lume sandbox without it.
def lacks_spacesd(self) -> boolReturns bool
Sandbox.guest_sh#
Runs line with /bin/sh -c in the guest without cua-spacesd, to
completion (default timeout 120 s). Local macOS Lume sandboxes only:
over lume ssh, stdout and stderr kept apart, no stdin. Others fail
with Unsupported.
async def guest_sh(self, line: str, timeout_ms: Optional[int] = None) -> ProcessOutput| Parameter | Type | Default |
|---|---|---|
line | String | required |
timeout_ms | Option<u32> | None |
Returns ProcessOutput · Async · Raises CuaError (Unsupported)
Sandbox.guest_screenshot#
Captures the guest framebuffer as PNG without cua-spacesd. Local Lume sandboxes only: over the VM's VNC endpoint.
async def guest_screenshot(self) -> ScreenshotReturns Screenshot · Async · Raises CuaError
Sandbox.guest_display#
The guest display without cua-spacesd: the VM's VNC endpoint and a
host command that opens it (lume attach). Local Lume sandboxes
only.
async def guest_display(self) -> GuestDisplayReturns GuestDisplay · Async · Raises CuaError
GuestDisplay#
The guest display of a sandbox without cua-spacesd
(Sandbox.guest_display). An object, not a record, so no binding's
default string form (repr, str, description, toString, Debug) can show
the VNC password: url() is masked, and only the explicit
url_with_password() returns it.
Returned by Sandbox.guest_display.
| Accessor | Returns | Description |
|---|---|---|
open_command() | Vec<String> | A host command that opens a viewer on it (lume attach <vm>); empty when there is none. It handles the password itself. |
url() | String | The display URL (vnc://HOST:PORT) with any password masked as ****. Safe to print and log. |
url_with_password() | String | SENSITIVE: the display URL with the VNC password (vnc://:PASSWORD@HOST:PORT), for handing to a VNC client. Never print or log it. |
via() | String | How the display is reached (vnc). |