Running Workbenches
Projects, status, studio, and MCP
These commands organize and watch local work. They are local to your machine and work the same with or without wb login.
Projects#
wb project create "Demo"
wb project create "Demo" --json
wb project list
wb project list --json
wb run project-core --project demo --task "Review this migration" --detachA project groups sessions. It is a row in the local wb.db with a name and a slug, and it can span any number of directories.
- Names are trimmed, keep their display case, are 1 to 64 characters, and cannot contain control characters.
- Each project has a lowercase hyphenated slug. Names and slugs are unique case-insensitively.
--project <name-or-slug>onrunmust resolve an existing project and never creates one. An unknown name fails before anything is dispatched and suggests a close match.- Resumes and continuations keep the session's project. Sessions started without
--projectare not tracked in Studio.
wb project list --json returns each project's name, slug, counts of tasks that need you, are running, are done, and failed, and created_at.
wb status#
wb status # one line per run
wb status --line # one line for a status bar
wb status --json # run summaries for other toolswb status shows live progress for every active run on the machine, plus runs that finished in the last 10 minutes: a plan bar from the agent's todo list with the current todo, elapsed time, and cost. A run waiting on input is shown first, with its wb answer command.
When the current todo runs past a typical todo's tool calls, the line adds the count in orange. That also reveals a todo list the agent stopped updating. Typical is the run's own median once three todos have finished, otherwise the median over the Workbench's finished runs.
--line suits any status bar that runs a command. For Claude Code:
{
"statusLine": {
"type": "command",
"command": "wb status --line",
"refreshInterval": 1
}
}Status folds each run's events into a cached row in the local database, so frequent polling reads only new events.
wb studio#
wb studio # start, or open the running dashboard
wb studio --no-open
wb studio --port 9392 --api-port 9393
wb studio status
wb studio status --json
wb studio stopwb studio starts the local Studio API in a detached process and runs the dashboard in Docker. The dashboard is published at 127.0.0.1:9292 and the API binds 127.0.0.1:9293. Startup fails before launching either when a port is busy.
| Option | Effect |
|---|---|
--image <ref> |
Use another dashboard image. |
--port <port> |
The loopback dashboard port. |
--api-port <port> |
The loopback API port. |
--no-open |
Do not open the browser. The open link is printed instead. |
--json |
Print JSON. |
Studio shows local tracked sessions only and makes no request to workbenches.dev. Starting it again opens the running dashboard with a fresh open link and never restarts it. studio stop is idempotent.
JSON status contains running, url, image, and image_id, plus open_url when the browser was not opened. The open link works once, within 5 minutes. The API token is kept only in the owner-only file $WORKBENCH_HOME/studio/state.json while Studio runs and is never printed.
The default image is pinned by digest. Studio pulls it when missing, runs it by its resolved image ID, and refuses an image built for another version of wb:
Studio image <image> does not match this version of wb. Drop --image to use the default image, or update wb.Studio needs Docker running with Linux containers. Otherwise it fails with Docker isn't running. Start Docker and run wb studio again., or asks you to switch Docker Desktop to Linux containers.
How the browser is admitted#
The dashboard only serves a browser holding its access cookie, so a Docker-sandboxed run or another local user that reaches the port cannot drive your sessions. Each wb studio writes a one-time handoff page, readable only by you, and opens it; the page redirects to the open link without a referrer. The container accepts each open code once, before it expires, and sets an HttpOnly, SameSite=Strict cookie. Restarting Studio revokes it. This gate is not authentication; it proves the browser is the one wb studio opened. Cookies ignore ports, so the browser also sends it to other servers on 127.0.0.1 and localhost.
The container runs read-only with --tmpfs /tmp, --cap-drop ALL, and --security-opt no-new-privileges.
The local Studio API#
All routes are beneath /v1 on the API port, use snake_case JSON, and require the bearer token provisioned to the dashboard. Host must be 127.0.0.1:<api-port>, localhost:<api-port>, or host.docker.internal:<api-port>. Authentication failures are 401, Host failures 403, an unknown run 404, each with { "error": { "code", "message" } }.
| Method | Path | Result |
|---|---|---|
| GET | /status |
Engine version. |
| GET | /projects |
Project summaries by newest activity, empty projects last. |
| GET | /tasks?project=<name> |
Tracked tasks, newest first. |
| GET | /tasks/:id |
One task and its runs, oldest run first. |
| GET | /runs/:id |
One run. |
| GET | /runs/:id/events?after=<seq>&limit=<n> |
Normalized events. limit defaults to 100, from 1 to 500. |
| WS | /runs/:id/events?after=<seq> |
Replay, then live events. Closes after a terminal event. |
| POST | /runs/:id/commands |
Submit send, steer, queue, answer, or cancel. |
| GET | /runs/:id/outcome/files |
Outcome artifact metadata. |
| GET | /runs/:id/outcome/files/<path> |
Original artifact bytes. |
| WS | /live |
Status, then changed task and project summaries. |
A command is { "kind", "payload", "idempotency_key" }. Text commands use { "text" }, answers { "request_id", "response" } with a string or an array of string arrays, and cancel an empty object. The response is 202 with { "command": { "id", "status", "message" } }. A repeated idempotency key returns the original result while the API server runs.
Artifact bytes are served inline only for PNG, JPEG, GIF, WebP, AVIF, video, audio, PDF, or plain text, and otherwise as application/octet-stream attachments, always with nosniff and Content-Security-Policy: sandbox; default-src 'none'.
wb mcp#
claude mcp add wb -- wb mcpwb mcp serves Workbench tools to a coding agent over stdio, for local work. It is covered on Local wb mcp.