Services
Named services, port forwards, public URLs and MCP clients of a sandbox.
Named services, port forwards, public URLs and MCP clients of a sandbox.
Reach ports inside a sandbox: sandbox.service(name) for a declared service, sandbox.forward(port) for any port, sandbox.public_url(...) for a shareable URL, and McpClient for an MCP server. None of them needs cua-spacesd.
Python programs usually use the high-level API instead: cua_sandbox services, tunnels and MCP.
| To reach a guest port | Use | Works |
|---|---|---|
| From your code, by name | sandbox.service(name).request(...) or .url() | Declared services, locally and in the cloud |
| From local tools (a browser, a client) | sandbox.forward(port) | Any port; a loopback listener |
| From someone else | sandbox.public_url(service, ttl_seconds, label) | Declared services; a bearer URL that expires |
| From an MCP client | sandbox.mcp_config(service, path) or sandbox.mcp(service, path) | An MCP server behind a declared service |
Methods of Sandbox.
Sandbox.service#A named service (for example "server" or "env").
def service(self, name: str) -> Service| Parameter | Type | Default |
|---|---|---|
name | String | required |
Returns Service · Raises CuaError
Sandbox.services#Declared services.
def services(self) -> dict[str, int]Returns HashMap<String, u16>
Sandbox.forward#Forwards a loopback port to guest port: a TCP forward locally (and
over cua-spacesd's tunnel when the image has it); in the cloud
without cua-spacesd, a loopback HTTP/WebSocket proxy through the
Fleet gateway. Either way url() is a loopback URL.
async def forward(self, port: int) -> PortForward| Parameter | Type | Default |
|---|---|---|
port | u16 | required |
Returns PortForward · Async · Raises CuaError
Sandbox.public_url#A shareable URL for service that stops working after ttl_seconds
(60 s to 24 h, default 1 h). Cloud: a Fleet signed service URL.
Local: a loopback URL with its own token, served by the cua daemon
(started if needed; CUA_BIN names the CLI).
async def public_url(self, service: str, ttl_seconds: Optional[int] = None, label: Optional[str] = None) -> PublicUrl| Parameter | Type | Default |
|---|---|---|
service | String | required |
ttl_seconds | Option<u32> | None |
label | Option<String> | None |
Returns PublicUrl · Async · Raises CuaError
Sandbox.revoke_public_url#Revokes a URL from public_url.
async def revoke_public_url(self, id: str) -> None| Parameter | Type | Default |
|---|---|---|
id | String | required |
Async · Raises CuaError
Sandbox.mcp_config#Where the MCP server behind service is (URL of its endpoint at
path, default /mcp, plus the headers every request needs), for
any MCP client. Embedded: the service route itself (loopback, or the
Fleet gateway with a fresh bearer and claim header). Daemon: the
daemon's streaming passthrough with its loopback bearer.
async def mcp_config(self, service: str, path: Optional[str] = None) -> McpConfig| Parameter | Type | Default |
|---|---|---|
service | String | required |
path | Option<String> | None |
Returns McpConfig · Async · Raises CuaError
Sandbox.mcp#An MCP client (the official Rust SDK) for the MCP server behind
service at path (default /mcp).
async def mcp(self, service: str, path: Optional[str] = None) -> McpClient| Parameter | Type | Default |
|---|---|---|
service | String | required |
path | Option<String> | None |
Returns McpClient · Async · Raises CuaError
Service#A named service of a sandbox.
Returned by Sandbox.service.
| Method | Description |
|---|---|
endpoint | Where this service is reachable from this process: base URL plus the headers every request needs. |
mcp | An MCP client (the official Rust SDK) for this service's endpoint at path (default /mcp). |
mcp_config | The MCP endpoint of this service at path (default /mcp). |
public_url | A shareable URL for this service that stops working after ttl_seconds (60 s to 24 h, default 1 h): the same as Sandbox.public_url(name, ...). |
request | One HTTP request to path on the service. |
url | A URL for the service usable from this machine with no credentials (no trailing slash): the published loopback port locally, a signed service URL (1 h, renewed on later calls) in the cloud. |
| Accessor | Returns | Description |
|---|---|---|
name() | String | Service name. |
Service.endpoint#Where this service is reachable from this process: base URL plus the headers every request needs. Any HTTP client can use it (SSE, long-lived streams and every method pass through unchanged).
async def endpoint(self) -> ServiceEndpointReturns ServiceEndpoint · Async · Raises CuaError
Service.mcp#An MCP client (the official Rust SDK) for this service's endpoint at
path (default /mcp).
async def mcp(self, path: Optional[str] = None) -> McpClient| Parameter | Type | Default |
|---|---|---|
path | Option<String> | None |
Returns McpClient · Async · Raises CuaError
Service.mcp_config#The MCP endpoint of this service at path (default /mcp).
async def mcp_config(self, path: Optional[str] = None) -> McpConfig| Parameter | Type | Default |
|---|---|---|
path | Option<String> | None |
Returns McpConfig · Async · Raises CuaError
Service.public_url#A shareable URL for this service that stops working after
ttl_seconds (60 s to 24 h, default 1 h): the same as
Sandbox.public_url(name, ...). Cloud: a Fleet signed service URL.
Local: a loopback URL with its own token, served by the cua daemon.
async def public_url(self, ttl_seconds: Optional[int] = None, label: Optional[str] = None) -> PublicUrl| Parameter | Type | Default |
|---|---|---|
ttl_seconds | Option<u32> | None |
label | Option<String> | None |
Returns PublicUrl · Async · Raises CuaError
Service.request#One HTTP request to path on the service. Credentials (Fleet bearer
and claim) are attached by the runtime. headers are sent as given
(for example content-type, or accept and mcp-session-id for
MCP over Fleet); authorization is refused on Fleet, where the
gateway bearer owns it.
async def request(self, method: str, path: str, body: Optional[bytes], timeout_ms: Optional[int], headers: Optional[List[HttpHeader]] = None) -> HttpResponse| Parameter | Type | Default |
|---|---|---|
method | String | required |
path | String | required |
body | Option<Vec<u8>> | required |
timeout_ms | Option<u32> | required |
headers | Option<Vec<HttpHeader>> | None |
Returns HttpResponse · Async · Raises CuaError
Service.url#A URL for the service usable from this machine with no credentials (no trailing slash): the published loopback port locally, a signed service URL (1 h, renewed on later calls) in the cloud.
async def url(self) -> strReturns String · Async · Raises CuaError
ServiceEndpoint record#Where a sandbox service is reachable from this process.
Returned by Service.endpoint.
| Field | Type | Default | Description |
|---|---|---|---|
url | String | Base URL (append the path). | |
headers | Vec<HttpHeader> | Headers every request needs. |
HttpHeader record#An HTTP header.
Returned by Space.websocket_headers.
| Field | Type | Default | Description |
|---|---|---|---|
name | String | Name. | |
value | String | Value. |
HttpResponse record#An HTTP response from a sandbox service.
Returned by Service.request.
| Field | Type | Default | Description |
|---|---|---|---|
status | u16 | Status. | |
headers | Vec<HttpHeader> | Headers. | |
body | Vec<u8> | Body. |
PortForward#An active port forward. Closed on close() or when dropped.
Returned by Sandbox.forward.
| Method | Description |
|---|---|
close | Stops the forward. |
| Accessor | Returns | Description |
|---|---|---|
guest_port() | u16 | Guest port. |
local_addr() | Option<String> | Loopback host:port accepting connections (local/direct). |
url() | Option<String> | URL to use (loopback URL, or the Fleet gateway URL). |
PortForward.close#Stops the forward.
async def close(self) -> NoneAsync · Raises CuaError
PublicUrl record#A shareable URL of a sandbox service that expires.
Returned by Sandbox.public_url, Service.public_url.
| Field | Type | Default | Description |
|---|---|---|---|
id | String | Id for Sandbox.revoke_public_url. | |
url | String | The URL. | |
expires_at_unix / expiresAtUnix | i64 | When it stops working (unix seconds). | |
service | String | Service name. | |
provider_details / providerDetails | HashMap<String, String> | Provider internals (cloud: namespace, claim; local: upstream). |
McpClient#An MCP client (rmcp, streamable HTTP; protocol 2026-07-28 when the server supports it, else the server's revision). Results are the server's JSON, unchanged.
Returned by Sandbox.mcp, Service.mcp, mcp_connect, mcp_connect_url.
| Method | Description |
|---|---|
call_tool | Calls name with a JSON object of arguments (None: {}); returns the tools/call result JSON verbatim (a tool error is isError). |
close | Closes the connection (ends the session on servers that keep one). |
get_prompt | Renders prompt name; the prompts/get result JSON. |
list_prompts | Every prompt (all pages), JSON array. |
list_resource_templates | Every resource template (all pages), JSON array. |
list_resources | Every resource (all pages), JSON array. |
list_tools | Every tool (all pages) as a JSON array of MCP Tool objects. |
read_resource | Reads uri; the resources/read result JSON. |
request | Any other JSON-RPC method (extensions such as skills/list, skills/get); returns its result JSON. |
| Accessor | Returns | Description |
|---|---|---|
server_info_json() | Option<String> | The server's serverInfo/negotiated version as JSON, when known. |
McpClient.call_tool#Calls name with a JSON object of arguments (None: {}); returns
the tools/call result JSON verbatim (a tool error is isError).
async def call_tool(self, name: str, arguments_json: Optional[str]) -> str| Parameter | Type | Default |
|---|---|---|
name | String | required |
arguments_json | Option<String> | required |
Returns String · Async · Raises CuaError
McpClient.close#Closes the connection (ends the session on servers that keep one).
async def close(self) -> NoneAsync · Raises CuaError
McpClient.get_prompt#Renders prompt name; the prompts/get result JSON.
async def get_prompt(self, name: str, arguments_json: Optional[str]) -> str| Parameter | Type | Default |
|---|---|---|
name | String | required |
arguments_json | Option<String> | required |
Returns String · Async · Raises CuaError
McpClient.list_prompts#Every prompt (all pages), JSON array.
async def list_prompts(self) -> strReturns String · Async · Raises CuaError
McpClient.list_resource_templates#Every resource template (all pages), JSON array.
async def list_resource_templates(self) -> strReturns String · Async · Raises CuaError
McpClient.list_resources#Every resource (all pages), JSON array.
async def list_resources(self) -> strReturns String · Async · Raises CuaError
McpClient.list_tools#Every tool (all pages) as a JSON array of MCP Tool objects.
async def list_tools(self) -> strReturns String · Async · Raises CuaError
McpClient.read_resource#Reads uri; the resources/read result JSON.
async def read_resource(self, uri: str) -> str| Parameter | Type | Default |
|---|---|---|
uri | String | required |
Returns String · Async · Raises CuaError
McpClient.request#Any other JSON-RPC method (extensions such as skills/list,
skills/get); returns its result JSON.
async def request(self, method: str, params_json: Optional[str]) -> str| Parameter | Type | Default |
|---|---|---|
method | String | required |
params_json | Option<String> | required |
Returns String · Async · Raises CuaError
McpConfig record#Where an MCP endpoint is and what every request needs. Hand it to any MCP client (Claude Code, Cursor, the Python or TypeScript SDKs). On Fleet the headers carry a short-lived gateway bearer: fetch a fresh config per connection.
Returned by Sandbox.mcp_config, Service.mcp_config.
| Field | Type | Default | Description |
|---|---|---|---|
url | String | Streamable-HTTP endpoint URL. | |
headers | Vec<HttpHeader> | Headers to send with every request. |
mcp_connect#Connects an MCP client to config (from Sandbox.mcp_config).
async def mcp_connect(config: McpConfig) -> McpClient| Parameter | Type | Default |
|---|---|---|
config | McpConfig | required |
Returns McpClient · Async · Raises CuaError
mcp_connect_url#Connects an MCP client to an endpoint URL (http://host:8765/mcp; a
bare origin means /mcp) with headers on every request.
async def mcp_connect_url(url: str, headers: Optional[List[HttpHeader]]) -> McpClient| Parameter | Type | Default |
|---|---|---|
url | String | required |
headers | Option<Vec<HttpHeader>> | required |