# Protocol

The gRPC contracts of cua-spacesd (cua.env.v1) and the cua daemon (cua.daemon.v1): ports, routes, auth and every RPC.

> Agent discovery: use [the Cua documentation index](https://cua.ai/docs/llms.txt) to find related pages and their Markdown URLs.





The gRPC contracts, generated from the `.proto` files in `libs/cua/proto`. `cua.env.v1` is served by cua-spacesd inside a sandbox; `cua.daemon.v1` is served by the local `cua daemon`. Changes are additive and pass `buf breaking`.

Contract revision: `cua.env.v1` protocol version 1, revision 8 (reported by `SystemService.GetCapabilities`).

Clients use the SDK's [`SpacesdClient`](</docs/cua-sdk/reference/spacesd>) or `cua spacesd ...`; `SpacesdClient.call_json` reaches any RPC below. Sandboxes do not require cua-spacesd: only the computer interfaces and the Spaces primitives need it. It never injects input itself; pointer and keyboard actions go to Cua Driver.

| Port | Carries |
| --- | --- |
| TCP 3211 | Native gRPC (HTTP/2) and gRPC-Web (HTTP/1.1), gRPC reflection, and the HTTP routes below |
| UDP 3212 | QUIC media datagrams (ALPN `rcdp/2`, certificate pinned through `StreamService.OpenMedia`) |

The default bind is `0.0.0.0:3211` with a token and `127.0.0.1:3211` without one; a non-loopback bind without a token is refused. Clients send the env token as `authorization: Bearer <token>` or `x-cua-env-authorization: Bearer <token>` (the Fleet gateway consumes `authorization`). The token grants full control of the machine: never put it in a URL; browsers use tickets and signed URLs.

| Route | Auth | Purpose |
| --- | --- | --- |
| `GET /health` | None | 204 while serving, 503 while shutting down |
| `GET`, `HEAD`, `PUT /files` | Signed URL from `CreateSignedUrl` | Upload and download with `Range`; 403 when expired or tampered |
| `POST /mcp` | Env token | Streamable-HTTP MCP over the Cua Driver tools; 501 when disabled |
| `GET /tunnel` (WebSocket) | Ticket from `TunnelService.Forward` | Port forwarding |
| `GET /hotspot` (WebSocket) | Ticket from `StartHotspot` | Reverse SOCKS egress |
| `GET /media` (WebSocket) | Ticket from `StreamService.OpenMedia` | Video (H.264) and audio (Opus), media wire v2 (`libs/cua/proto/MEDIA.md`) |

Tickets go in `?ticket=` or the WebSocket subprotocol `cua.ticket.<ticket>`. Tickets and signed URLs are keyed from the env token, so rotating the token revokes them.

## Services

| Service | Package | Page | RPCs |
| --- | --- | --- | --- |
| [`SystemService`](</docs/cua-sdk/reference/protocol/env-system#systemservice>) | `cua.env.v1` | [System](</docs/cua-sdk/reference/protocol/env-system>) | 10 |
| [`ProcessService`](</docs/cua-sdk/reference/protocol/env-process#processservice>) | `cua.env.v1` | [Processes](</docs/cua-sdk/reference/protocol/env-process>) | 8 |
| [`FilesystemService`](</docs/cua-sdk/reference/protocol/env-filesystem#filesystemservice>) | `cua.env.v1` | [Filesystem](</docs/cua-sdk/reference/protocol/env-filesystem>) | 16 |
| [`ComputerService`](</docs/cua-sdk/reference/protocol/env-computer#computerservice>) | `cua.env.v1` | [Computer and driver](</docs/cua-sdk/reference/protocol/env-computer>) | 7 |
| [`DriverService`](</docs/cua-sdk/reference/protocol/env-computer#driverservice>) | `cua.env.v1` | [Computer and driver](</docs/cua-sdk/reference/protocol/env-computer>) | 2 |
| [`WindowsService`](</docs/cua-sdk/reference/protocol/env-windows#windowsservice>) | `cua.env.v1` | [Windows and accessibility](</docs/cua-sdk/reference/protocol/env-windows>) | 11 |
| [`AccessibilityService`](</docs/cua-sdk/reference/protocol/env-windows#accessibilityservice>) | `cua.env.v1` | [Windows and accessibility](</docs/cua-sdk/reference/protocol/env-windows>) | 3 |
| [`StreamService`](</docs/cua-sdk/reference/protocol/env-stream#streamservice>) | `cua.env.v1` | [Streams and presence](</docs/cua-sdk/reference/protocol/env-stream>) | 5 |
| [`PresenceService`](</docs/cua-sdk/reference/protocol/env-stream#presenceservice>) | `cua.env.v1` | [Streams and presence](</docs/cua-sdk/reference/protocol/env-stream>) | 3 |
| [`TeleportService`](</docs/cua-sdk/reference/protocol/env-teleport-tunnel#teleportservice>) | `cua.env.v1` | [Teleport, tunnels and the volume](</docs/cua-sdk/reference/protocol/env-teleport-tunnel>) | 7 |
| [`TunnelService`](</docs/cua-sdk/reference/protocol/env-teleport-tunnel#tunnelservice>) | `cua.env.v1` | [Teleport, tunnels and the volume](</docs/cua-sdk/reference/protocol/env-teleport-tunnel>) | 6 |
| [`VolumeService`](</docs/cua-sdk/reference/protocol/env-teleport-tunnel#volumeservice>) | `cua.env.v1` | [Teleport, tunnels and the volume](</docs/cua-sdk/reference/protocol/env-teleport-tunnel>) | 3 |
| [`HostSpacesService`](</docs/cua-sdk/reference/protocol/env-host-spaces#hostspacesservice>) | `cua.env.v1` | [Host Spaces](</docs/cua-sdk/reference/protocol/env-host-spaces>) | 6 |
| [`SandboxService`](</docs/cua-sdk/reference/protocol/daemon-sandboxes#sandboxservice>) | `cua.daemon.v1` | [Daemon: sandboxes](</docs/cua-sdk/reference/protocol/daemon-sandboxes>) | 19 |
| [`RuntimeService`](</docs/cua-sdk/reference/protocol/daemon-runtimes#runtimeservice>) | `cua.daemon.v1` | [Daemon: local runtimes](</docs/cua-sdk/reference/protocol/daemon-runtimes>) | 5 |
| [`SpaceService`](</docs/cua-sdk/reference/protocol/daemon-spaces#spaceservice>) | `cua.daemon.v1` | [Daemon: Spaces](</docs/cua-sdk/reference/protocol/daemon-spaces>) | 17 |
| [`DaemonService`](</docs/cua-sdk/reference/protocol/daemon-service#daemonservice>) | `cua.daemon.v1` | [Daemon: service](</docs/cua-sdk/reference/protocol/daemon-service>) | 3 |

## Metadata and HTTP routes

Well-known metadata keys and HTTP paths (`cua_proto::metadata`).

| Constant | Value | Meaning |
| --- | --- | --- |
| `AUTHORIZATION` | `authorization` | Bearer token header: `authorization: Bearer <token>`. |
| `ENV_AUTHORIZATION` | `x-cua-env-authorization` | Alternate spacesd token header, `x-cua-env-authorization: Bearer <token>`, for paths where `authorization` belongs to an outer hop (the Fleet gateway consumes and strips it). Servers accept either header. |
| `PRINCIPAL_BIN` | `x-cua-principal-bin` | Binary metadata carrying a serialized `cua.env.v1.Principal`. |
| `HEALTH_PATH` | `/health` | Plain-HTTP, unauthenticated health route (204 when healthy). |
| `MEDIA_WS_PATH` | `/media` | Media WebSocket path (ticket-authenticated). |
| `TUNNEL_WS_PATH` | `/tunnel` | TCP-over-WebSocket tunnel path (ticket-authenticated). |
| `HOTSPOT_WS_PATH` | `/hotspot` | Reverse-SOCKS hotspot WebSocket path (ticket-authenticated). |
| `VOLUME_WS_PATH` | `/volume` | Cua Volume WebSocket path (ticket-authenticated): the client serves the guest's volume mount over it. |
| `FILES_PATH` | `/files` | Signed-URL file route. |
| `MCP_PATH` | `/mcp` | Streamable-HTTP MCP endpoint for the cua-driver tool registry. |
| `VIEWER_PATH` | `/viewer` | The web viewer (static page, unauthenticated; it reads its viewer ticket from the URL fragment). Served with and without the trailing slash; assets live under `/viewer/`. |

## gRPC-Web fallbacks

gRPC-Web cannot carry client streams, so every client-streaming RPC has a unary fallback (`cua_proto::CLIENT_STREAM_FALLBACKS`).

| Client stream | Unary fallback |
| --- | --- |
| `/cua.env.v1.ProcessService/StreamInput` | `/cua.env.v1.ProcessService/SendInput` |
| `/cua.env.v1.FilesystemService/WriteFile` | `/cua.env.v1.FilesystemService/UploadChunk` |

## Errors

Errors are `google.rpc.Status` with typed details: spacesd packs [`ErrorInfo`](</docs/cua-sdk/reference/protocol/env-common#errorinfo>) and the daemon packs [`DaemonErrorInfo`](</docs/cua-sdk/reference/protocol/daemon-service#daemonerrorinfo>).

