Workbenches is an open standard. Read why
Docs Publishing

Building Workbenches

Publishing

The registry at workbenches.dev stores immutable Workbench versions per organization. Every organization Workbench is internal until it is published: members and organization keys see it, nobody else does, and anyone else gets a plain 404. Publishing is the one explicit act that makes a stored version public, and it always goes through review.

A public GitHub repository with packages under .workbenches/<name>/ is already installable without the registry, with wb add https://github.com/owner/repo --name <name>. Use the registry for versions, internal sharing, review, and a stable org/name.

Before publishing#

  1. The package passes wb validate and wb smoke on every declared runtime, and has been trialed on real tasks.
  2. The manifest version is higher than the last stored version. Bump it for any content change.
  3. The package directory holds only what should ship. wb push and wb publish upload the whole directory with no ignore rules: make sure no .env, credential file, private notes, or build output sits inside it. Limits: 256 files, 10 MiB total, 2 MiB per file, no symlinks.
  4. For public versions: nothing private. No internal project names, customer code, or copied proprietary text.

Sign in#

wb login                 # browser approval; the first login becomes the default
wb login --org acme      # connect acme and make it the default
wb org list              # held organizations, default and expiry
wb org use acme          # change the default
wb whoami                # default organization, user, scopes, key expiry
wb logout --org acme     # revoke that key and forget it

wb login runs a browser approval that connects exactly one organization and stores a key for it in ~/.workbench/credentials.json (mode 0600). Every account has a personal organization. --org must match the organization approved in the browser, or nothing is stored. wb login --no-browser does not open the browser. Keys expire; wb login --org <org> refreshes one. wb logout without a flag signs out of the default organization.

wb push, wb publish, wb unpublish, and wb image push use the default organization, or the one named with --org <slug>.

Push: share with your organization#

wb push .#core                 # stores acme/core@<version>, internal
wb push .#core --as core-tools # store under another registry name
wb push my-alias               # a saved alias works too

wb push [source] [--org <slug>] [--as <name>] uploads the package as a new immutable version. source is a local package reference (.#name, /path#name, default .) or a saved alias. The Workbench is created as internal when missing. Output:

Pushed acme/ios-expert@1.2.0 (internal)
  • Each push needs a manifest version greater than the latest stored one. Pushing the same version with identical bytes again changes nothing.
  • A public Workbench takes new versions only through wb publish. The registry rejects a push to one with a conflict, and the CLI prints its message unchanged.
  • Pushing a new Workbench past the plan's private Workbench cap is refused with plan_limit.

Teammates save it after their own wb login --org acme:

wb add acme/core

Saved internal Workbenches show as internal in wb list --saved and wb view.

Publish: submit for public review#

wb publish acme/core            # submit the latest stored version
wb publish .#core --org acme    # submit a local package directly

wb publish <org/name | source> [--org <slug>] [--version <semver>] submits for public review and prints the submission ID, status, and dashboard URL.

  • With org/name, it submits the latest stored version. --version is accepted only when it names that latest version.
  • With a local source, it submits the package directly, without storing an internal version first. This is how a public Workbench takes a new version.
  • approved means public now. Anything else means it is waiting for review. A pending submission is not public.

Reviewers approve an exact digest, request changes with feedback, or reject with feedback. Approval publishes those bytes and labels the version human_reviewed or trusted_publisher. Rejection leaves the Workbench internal and the version stored. If a newer version is pushed while a review is open, approval fails and the newer version must be submitted. Follow submissions in the dashboard. Review validates manifests, referenced files, paths, and size; it does not execute submitted code or certify security.

For a new registry identity, the organization slug and the manifest's name form the published coordinate. The manifest name must be a URL-safe slug. A local alias or directory name does not choose the registry name.

From GitHub#

The dashboard's sources page connects a GitHub repository, lists its packages, and submits the versions you select. Repository pushes never publish automatically. Publishing files from a private repository requires acknowledging that they become publicly downloadable after approval.

Cloud runs#

Any Workbench can be published, including a local-only one. Cloud runs and the hosted MCP server offer only sandboxed Workbenches: those whose runtimes include docker or e2b with an image, or daytona. See Running on workbenches.dev.

Unpublish#

wb unpublish acme/core

wb unpublish <org/name> [--org <slug>] flips a public Workbench back to internal at once and withdraws its open submissions. --org, when given, must match the reference. Copies already downloaded stay with their clients.

Publish an image#

daytona needs a published image. e2b can build from the package's Dockerfile, but a published image avoids a template build on each new tag, and docker consumers benefit from one instead of building locally.

wb login --org acme
docker build --platform linux/amd64 -t core-local .workbenches/core
wb image push core-local --org acme --as core --tag 1.2.0

That publishes images.workbenches.dev/acme/core:1.2.0. Reference it from the manifest:

runtimes:
    docker:
        image: images.workbenches.dev/acme/core:1.2.0
    daytona:
        class: linux
        image: images.workbenches.dev/acme/core:1.2.0

wb image push <image> --as <name> [--org <slug>] [--tag <tag>] [--client <executable>] exports the local image, skips blobs already in the registry, uploads missing blobs in bounded chunks, and publishes the original OCI manifest. The source image can have any local name. Progress goes to stderr; on success a terminal shows Pushed image · <ref>. --client selects an OCI client that supports the Docker image save interface.

  • Use a versioned tag, never latest. Never overwrite a tag a released version references. Bump the image tag and the Workbench version together.
  • Sandbox providers run linux/amd64. Build with --platform linux/amd64 on Apple silicon.
  • Prefer wb image push over a direct docker push, which is subject to the registry's per-request body limit.

Standard OCI clients can log in too:

wb image login --org acme
docker tag core-local images.workbenches.dev/acme/core:1.2.0
docker push images.workbenches.dev/acme/core:1.2.0

wb image login takes --org and --client (default docker).

Images are private until a public Workbench references them. A repository is pullable anonymously only while at least one public, approved version in that organization names an image in it. Otherwise a pull needs a key of the owning organization. See Images.

Errors#

Error Fix
Sign in first with wb login Run wb login.
Not signed in to organization X. Held: a, b. Run wb login --org X Connect that organization.
Your Workbench CLI login for X has expired. Run wb login --org X again. Refresh the login.
--publisher was replaced by --org. Use --org <slug> Use --org.
Workbench package exceeds 256 files, exceeds 10485760 bytes, file is too large Remove build output, assets, and anything not needed at run time from the package directory.
Only the latest version can be published for now Publish the local package directly: wb publish .#<name> --org <org>.
A version conflict Bump version in workbench.yml and push or publish again.
A push to a public Workbench is refused Public Workbenches take new versions only through wb publish.
A 404 for a publisher you hold no key for wb login --org <publisher>.