The Capability dataclass
A capability is (name, protocol, url, params) - concrete wire data carrying the real address of something serving the protocol.
Each protocol has a factory (
Capability.ssh, .mcp, .cdp, .rfb, .robot) - a classmethod that builds a valid Capability for that protocol, so you don’t fill in the four fields by hand. It normalizes the URL (fills in the default scheme and port), sets the right protocol id, and packs the protocol-specific params. cap.to_manifest() / Capability.from_manifest(data) round-trip it on the wire.
Spinning up a capability
Every capability points at a daemon. A daemon that already exists (a managed service, a remote box) is described with its factory and you’re done. A daemon the environment runs itself follows the same four steps inside an@env.initialize hook:
- Launch it as a subprocess or background task, bound to
127.0.0.1. - Block until it is listening before publishing. A subprocess returns before its port is bound, so poll the port (or
asyncio.sleepfor a daemon you know starts fast). The environment runs every@env.initializehook to completion before accepting a client, so a capability published here is live the moment any agent connects. - Publish its address with
env.add_capability(...). - Tear it down in
@env.shutdown.
127.0.0.1: the environment exposes a single control port, and the HUD client transparently forwards a 127.0.0.1 capability through that port to the daemon inside. A capability already on a public address is used as-is.
Factories
ssh - a sandboxed shell
Workspace, so you rarely call this factory directly. env.workspace(root) starts a workspace, publishes its ssh capability, and stops it with the env.
mcp - your own tools
Example env.py
Example env.py
env.py
cdp - a browser
Playwright ships the Chromium binary (
playwright install chromium). Add --no-sandbox to the launch flags only when running as root in a container.
Example env.py
Example env.py
env.py
rfb - a virtual screen
On Linux,
Xvfb paints the framebuffer and x11vnc serves it (apt install xvfb x11vnc).
Example env.py
Example env.py
env.py
robot - an observation/action loop
The robot control loop (beta) runs over the
openpi/0 protocol. It is openpi-like: it reuses openpi’s msgpack-numpy wire format and flat observation/action naming, but the environment is the server (it owns the world and pushes observations) and the agent is the client (it acts, replying with actions). The environment drives its simulator through a RobotEndpoint, which builds the capability once started:
Workspace file tracking
Workspace file tracking records what changed in aWorkspace over a run, so HUD can show file diffs in the trace. It runs with the workspace lifecycle and is not a tool the agent calls. env.workspace(...) enables it by default (the HUD_FILE_TRACKING_ENABLED setting); set HUD_FILE_TRACKING_ENABLED=false or pass track_files=False to opt out:
env.py
Harness clients
Spinning up a capability is the environment side. The harness side is the mirror: it opens a capability to get a live client it can drive. The capability clients live inhud.capabilities:
The bundled provider agents open these automatically based on which capabilities the manifest advertises (see Agents). To write your own harness, attach to the capability you need and define your tool spec.
Workspace
AWorkspace is not itself a capability - it’s the built-in workspace daemon. It serves ssh for agent access and, when enabled, file tracking for rollout telemetry. For mcp, cdp, and rfb you stand up the daemon yourself.
Concretely it’s a directory plus a bwrap-isolated SSH server (bash + chroot’d SFTP). env.workspace(root, ...) wires its whole lifecycle; construction is pure data, with keys, sockets, and the root directory materializing only at serve time. To run one outside an env, drive its lifecycle directly and publish ws.capability():
Use a relative path (
"workspace", created next to env.py). Sandbox isolation (bwrap) is Linux-only - unisolated elsewhere, isolated in a built image.
A
Mount (hud.environment) configures a single bwrap mount, Mount(kind, src, dst, optional), where kind is one of ro, rw, tmpfs, symlink, proc, dev.
For authoring a complete environment around a capability, see creating an environment; for the object and serving API, see environment.