Skip to content

Changelog

14 November 20269 changes

SDKs and CLI 1 · Sandboxes 8

3 min read

OlderFollow by RSS

Catalog MCP servers in a sandbox are withdrawn

GET /v1/mcp/catalog and /v1/sandboxes/{id}/mcp return 404 route_not_found, with a message that says what to use instead. The SDKs' mcp clients, runtime sandboxes mcp and the runtime_sandboxes_mcp tool are removed. To run an MCP server in a sandbox, start it as a process and share its port with a preview (MCP servers in a sandbox). Runtime's own MCP server is unchanged.

A paused sandbox wakes for its own timers

A sandbox paused after its idle seconds wakes by itself shortly before the soonest timer of one of its processes is due: a sleep, a poll or wait with a timeout, a timerfd, alarm() or timer_create() that was pending the whole time it sat idle. A loop that polls every ten minutes, or sleep 600 && ./next.sh, now runs on time instead of waiting for the next call. Each such wake is billed as any wake. A timer armed and fired again and again while the sandbox was idle wakes nothing, and a sandbox you paused yourself never wakes on its own.

Environment variables on create

POST /v2/sandboxes and POST /v1/sandboxes take env: up to 32 variables and 32,768 bytes of names and values, set for every command and process in the sandbox and for its start command. Values are stored encrypted and are never returned. A fork or a copy of a snapshot keeps its source's variables. Before, /v1 ignored env and /v2 refused it.

Resize a running sandbox

POST /v2/sandboxes/{id}:update takes vcpu, memoryGB and diskGB (and POST /v1/sandboxes/{id}:resize takes vcpu, memoryMiB and diskMiB). The sandbox grows while it runs: its disk and file system, its memory and its vCPUs, with its commands running on. The new size counts against your limits; a size past them returns 403. A smaller size, or a sandbox that is not running, returns 409 with the reason, and nothing changes.

Run a sandbox as root with one setting

POST /v2/sandboxes and POST /v2/sandboxes/{id}:update take user: runtime (the default: uid 1000, with passwordless sudo) or root. Every exec and process in the sandbox runs as that user when the call names no user; a call's own user still overrides it for that call. An image kept from a sandbox keeps its user as the default for sandboxes created from it, and a fork or a copy of a snapshot keeps its source's. Every SDK takes it: create({ user: "root" }). The per-call value sandbox is now runtime; /v1 and the MCP tools still take sandbox.

Job secrets can be deleted, and their names reused

POST /v1/secrets/{id}:delete deletes a job secret (with an optional expectedVersion), and GET /v1/secrets/{id} returns one. After a delete, POST /v1/secrets with the same name creates a new secret. Job secrets are now the same secrets as /v2/secrets (visible ones): they appear in its list, and machines get them in their environment as before.

A fork makes all its copies or none

POST /v2/sandboxes/{id}:fork with count is admitted as one start: when the copies together would pass one of your limits (running vCPU or memory) or find no room, the request returns the error and makes no copy. Before, it made copies until the limit and refused the rest. A fork counts as one start against your starts-per-second limit, whatever its count.

Network rules on create

POST /v2/sandboxes takes network (the same {default, rules} that PUT /v2/sandboxes/{id}/network takes), and POST /v1/sandboxes and the runtime_sandboxes_create MCP tool take network in their own shape (internet, allow, deny, connect). The rules hold from the sandbox's first start. Before, v1 and MCP dropped network and the sandbox started with the default rules. A create from a snapshot refuses network with 400: set the rules with PUT /v2/sandboxes/{id}/network after it starts.

A command runs to its end

POST /v2/sandboxes/{id}:exec (and /v1/sandboxes/{id}:exec, and the runtime_sandboxes_exec MCP tool) with no timeoutMs no longer stops the command after 60 seconds: it runs until it exits and returns its exit code and output. timeoutMs still sets a limit when you name one. Every SDK waits for the command to end when you name no limit, with no client timeout, and if the answer is cut while the command runs (for example by a release of the API), the SDK sends the request again with the same idempotency key and returns the same run's result, without running it twice.

Other days.

Cut your cloud billby 75%.

No card to start. Billed by the second after.

Start free, no card