Space lifecycle
Register, provision, list and release Spaces.
Register, provision, list and release Spaces.
| Tool | Description |
|---|---|
add_space | Add an existing machine as a Space by address and token. |
remove_space | Forget a registered Space without touching it. |
list_spaces | List the Spaces this connection can see. |
create_space | Create a Space: a new sandbox on this machine, on one of your machines, or in the cloud. |
delete_space | Delete a Space's sandbox and forget it. |
stop_space | Turn a Space off: suspend it (memory kept) or stop it (disk kept). |
start_space | Turn a Space back on: resume or boot it. |
Add an existing machine as a Space by address and token.
Tries a GetCapabilities handshake with the Space's cua-spacesd first. A local:<name> or cloud:<name> id without one is still a Space, with an empty capability set (its declared services, tunnels and public URLs work); a direct URL without one is added as an MCP Space when it answers MCP initialize (service mcp), and refused with spacesd_not_available when it answers neither. The Space is stored in ~/.cua/spaces.json and its token in ~/.cua/spaces-credentials.json (0600). Re-adding the same address updates it.
| Providers | all (cloud, local, direct, relay) |
| Platforms | all (macos, windows, linux) |
| Metering | free |
| Approval | permission spaces:add_space; mutating, idempotent |
| Swift SDK | SpacesConnection.addSpace(url:token:) |
| Rust | Spaces::add |
| Parameter | Type | Default | Description |
|---|---|---|---|
name | string | none | Display name. Default: the guest's hostname. |
service | string | mcp | For an MCP endpoint URL: the service name to register it under. Default mcp. |
token | string | none | The spacesd token (or the bearer an MCP endpoint needs). Stored in a separate 0600 credentials file, never in spaces.json. |
url | string | required | The Space's cua-spacesd: http(s)://host:port (port defaults to 3211), host:port, or a Space id (cloud:<name>, local:<name>). Any other MCP endpoint (for example http://host:8765/mcp) is added as a Space with one MCP service and no spacesd capabilities. |
JSON: the registered Space (id, name, provider, spacesd_version, features, os, services, added_at) and phase: "ready".
invalid_argument, unauthenticated
Forget a registered Space without touching it.
Only the registration and its stored token are removed. The sandbox keeps running, including a Space in your cloud (its cloud resources and relay machine stay); delete_space deletes a Space that create_space made.
| Providers | all (cloud, local, direct, relay) |
| Platforms | all (macos, windows, linux) |
| Metering | free |
| Approval | permission spaces:remove_space; mutating, idempotent |
| Swift SDK | SpacesConnection.removeSpace(_:) |
| Rust | Spaces::remove |
| Parameter | Type | Default | Description |
|---|---|---|---|
space | string | required | Space id or name. |
JSON: {"removed": <Space>}, the registration that was removed.
invalid_argument, not_found, ambiguous_sandbox
List the Spaces this connection can see.
Every registered Space (cloud, local, direct and relay) with its id (local:<name>, cloud:<name>, direct:<host:port>, relay:<machine-id>), provider, spacesd version (empty without one) and supported features as of the last handshake. The signed-in account's machines on the relay are listed too: those are the names create_space accepts as on="host:<machine>". A Space a machine provides carries host (that machine's id) and host_name; group them under it when you show them. A Space in your cloud carries cloud (the provider: aws, gcp, modal), cloud_place (account and region, to show with it) and cloud_delete (where delete_space can delete it: here, host:<machine>, or elsewhere).
| Providers | all (cloud, local, direct, relay) |
| Platforms | all (macos, windows, linux) |
| Metering | free |
| Approval | permission spaces:list_spaces, in spaces:readonly; read-only, idempotent |
| Swift SDK | SpacesConnection.spaces() |
| Rust | Spaces::list |
No parameters.
JSON: an array of Spaces (id, name, provider, spacesd_version, features, os, services, added_at, for a Space one of your machines provides host and host_name, for a Space that can be turned off and on power (suspend or stop) and power_state, and for a Space in your cloud cloud, cloud_place and cloud_delete), each with phase: "ready".
invalid_argument, relay, unauthenticated
Create a Space: a new sandbox on this machine, on one of your machines, or in the cloud.
Creates a new sandbox where on says (local: this machine, free; cloud: Cua cloud, metered; aws, gcp or modal: the user's own cloud account, connected with cloud_connect, billed there; default: the user's default location, else local), waits until it is ready (its spacesd when the image runs one, else its declared services), and registers it as local:<name> or cloud:<name>. kind (auto, container, vm) and runtime (auto, or an engine the location offers for the kind) are chosen automatically by default: the canonical Linux image runs as a gVisor container, macOS images as Lume VMs, Windows and disk-only images as VMs (QEMU locally, KubeVirt in the cloud). An impossible combination fails with invalid_placement and lists the valid values. Any image works; without cua-spacesd the capability set is empty. reuse=true returns a reachable registered Space in the same location with the requested services instead of creating one. On the user's own machines: on="host:<machine>" creates the Space on a machine set up with cua host setup --provide-spaces (for example "spin up 2 macOS Spaces on my spare Mac mini" is on="host:spare mac mini", image="macos", count=2). The machine is matched by id, exact name, or the words of its name; when several fit equally the call fails with ambiguous_host listing them (ask the user which, then pass on="host:<id>"). The host runs it with its own runtimes (Lume for macOS VMs on a Mac, Docker for Linux), the Space joins the relay and is returned as relay:<machine> with host set. A Mac runs at most two macOS VMs (Apple's macOS license, enforced by Apple Virtualization); a host at a limit fails with limit_exceeded. Only the machine's owner and the accounts it is shared with as editors can create there, from an enrolled device. on="direct:<addr>" is not accepted here: a direct address is one already-running Space, attached with add_space, not a host this call can create on.
| Providers | cloud only (cloud:<name>), local only (local:<name>), relay only (relay:<machine-id>) |
| Platforms | all (macos, windows, linux) |
| Metering | cloud |
| Approval | permission spaces:create_space; destructive |
| Swift SDK | Spaces.create(options) |
| Rust | Spaces::create |
| Parameter | Type | Default | Description |
|---|---|---|---|
command | string[] | none | Entrypoint override (argv), for example ["python", "-m", "my_mcp", "--port", "8765"]. |
count | integer | none | How many Spaces to create, 1 to 8 (default 1), all with the same settings (a name gets -2, -3, ... suffixes). With more than one the result is an array. At least 0. |
env | map of string | none | Guest environment variables. |
image | string | none | Guest image. Default: the canonical Linux image (ghcr.io/trycua/linux:24.04), whose variant follows the kind. |
kind | "auto" | "container" | "vm" | auto | What kind of machine. Default auto (from the image). auto: From the image: macOS and Windows images are VMs, an image with a container rootfs is a container, a disk-only image is a VM. container: A container (gVisor, or runc locally). vm: A virtual machine (QEMU or Lume locally, KubeVirt in the cloud). |
name | string | none | Name. Default: a generated space-<hex>. |
on | string | none | Where it runs: local (this machine, free), cloud (Cua cloud, metered), or host:<machine>: one of the user's own machines that provides Spaces (cua host setup --provide-spaces on it), named by id or by words from its name ("host:spare mac mini" matches "Mac mini (spare)" or dillons-mac-mini). Default: the user's default location (cua config set default.on, CUA_DEFAULT_ON), else local. Not direct:<addr>: that is one already-running Space at a fixed address, attached with add_space, not a host this can create on. An existing machine is added with add_space, not created. |
reuse | boolean | false | Return a reachable registered Space in the same location that has the requested services instead of creating one (get-or-create). Default false. |
runtime | string | auto | Which engine. Default auto: the safest one for the location and kind. Local: gvisor or runc (containers), qemu or lume (VMs). Cloud: gvisor (containers), kubevirt (VMs). Anything else fails with invalid_placement, listing the valid values. |
services | map of integer | none | Named services (name to guest port), for example {"mcp": 8765}. Each is probed for readiness and reachable with list_tools / call_tool (service=<name>). |
spacesd | boolean | true | Whether the image runs cua-spacesd. Default: true for the canonical images (and no image), false for any other image. A Space without it has an empty capability set: only its services work. |
timeout | integer | 600 | Seconds to wait for readiness (local). Default 600. At least 0. |
wait | boolean | true | Wait until the Space is ready (its spacesd, or its declared services). Default true. |
JSON: the registered Space, phase: "ready" and reused (true when reuse returned an existing Space); with wait: false, {"id", "phase": "starting"} at once; with count above 1, an array of them.
invalid_argument, invalid_placement, fleet, fleet_admission_denied, cloud_credit_exhausted, sandbox, timeout, ambiguous_host, limit_exceeded
cua auth login); local needs a container engine, QEMU or Lume (cua runtime doctor).Delete a Space's sandbox and forget it.
Deletes the sandbox of a Space that create_space made (cloud: metering stops; local: the instance is deleted; on one of your machines, on="host:...": that machine deletes it and it leaves the relay) and forgets it. A Space in your cloud (list_spaces: cloud, cloud_place, cloud_delete) is deleted permanently through the records of the device that created it: cloud_delete "here" deletes it from this device; "host:<machine>" asks that host (it must be online, and only its owner may); "elsewhere" is refused with where it was created: delete it there, or remove_space. Another Space added by address (direct:, relay:) is only forgotten: cua did not create it. Any hotspot on the Space is stopped first. To forget a Space without deleting anything, use remove_space.
| Providers | all (cloud, local, direct, relay) |
| Platforms | all (macos, windows, linux) |
| Metering | free |
| Approval | permission spaces:delete_space; destructive |
| Swift SDK | Spaces.delete(space) |
| Rust | Spaces::delete |
| Parameter | Type | Default | Description |
|---|---|---|---|
space | string | required | Space id or name. |
Text: what was deleted (Deleted <id> (...)), or Removed <id> (...) for a Space added by address.
invalid_argument, not_found, ambiguous_sandbox, fleet, sandbox
Turn a Space off: suspend it (memory kept) or stop it (disk kept).
Turns a Space off the way its provider can: a local container or QEMU VM is suspended (its memory is kept and it resumes where it was), a local Lume VM is stopped (its disk is kept and it boots again), a Space one of your machines provides is stopped by that machine, which frees its memory, and a Space in your own cloud (on="aws", "gcp") is stopped there: compute billing stops, its disk stays (storage is still billed). Anything streaming from the Space and any hotspot on it end first. A Fleet cloud Space, a Modal sandbox, a Space added by address and your own computers on the relay cannot be turned off (wrong_provider); delete_space deletes a Space instead. start_space turns it on again.
| Providers | all (cloud, local, direct, relay) |
| Platforms | all (macos, windows, linux) |
| Metering | free |
| Approval | permission spaces:stop_space; mutating, idempotent |
| Swift SDK | Spaces.stop(space) |
| Rust | Spaces::stop |
| Parameter | Type | Default | Description |
|---|---|---|---|
space | string | required | Space id or name. |
JSON: space, state (suspended or stopped), power (suspend or stop) and message.
invalid_argument, not_found, ambiguous_sandbox, wrong_provider, sandbox, relay, permission_denied, cloud
power: suspend or stop; absent when it cannot) and how they were left (power_state).Turn a Space back on: resume or boot it.
Turns a Space stop_space turned off on again: resumes a suspended one, boots a stopped one (a Space one of your machines provides, or one in your cloud, joins the relay again), and leaves a running one as it is. Returns once it answers again (bounded). The same Spaces turn on as turn off.
| Providers | all (cloud, local, direct, relay) |
| Platforms | all (macos, windows, linux) |
| Metering | free |
| Approval | permission spaces:start_space; mutating, idempotent |
| Swift SDK | Spaces.start(space) |
| Rust | Spaces::start |
| Parameter | Type | Default | Description |
|---|---|---|---|
space | string | required | Space id or name. |
JSON: space, state (running), power (suspend or stop) and message.
invalid_argument, not_found, ambiguous_sandbox, wrong_provider, sandbox, relay, permission_denied, cloud, timeout