# Connect an agent

`mcp.workbenches.dev` is the Model Context Protocol server for workbenches.dev. A coding agent connected to it can search the registry, run Workbenches in the cloud or on your organization's workers, follow and steer those runs, read their changes, and push a Workbench as an internal version.

- Endpoint: `https://mcp.workbenches.dev`, Streamable HTTP at the root.
- Stateless: each request builds a fresh server.
- Every tool calls the public API with your credential, unchanged, so a tool can do only what that credential can.

There are two ways to authenticate: OAuth, for clients that support it, or an organization API key.

## OAuth

Clients that support MCP OAuth, such as Claude.ai and ChatGPT connectors, need no pasted key. Add `https://mcp.workbenches.dev` as a connector. The client:

1. calls the server without a credential and gets `401` with a `WWW-Authenticate` header naming `/.well-known/oauth-protected-resource`,
2. registers itself with the workbenches.dev authorization server,
3. sends you to a workbenches.dev consent page, where you sign in, pick an organization (your personal organization is preselected), and approve the requested scopes,
4. receives an organization key.

The key is labelled `MCP: <client name>`, holds the scopes you granted (`catalog:read`, `packages:write`, `runs:read`, `runs:write`; never `org:admin`), and lasts 90 days. There are no refresh tokens: when it expires, the client runs the flow again. Any member may approve, and the key appears on your organization's API keys page, where you can revoke it. It stops working the moment your membership ends.

The consent page labels the app "Unverified app" with the name it chose, and shows the scheme and host it will return to. Approve only clients you recognize.

### Claude Code

```sh
claude mcp add --transport http workbenches https://mcp.workbenches.dev
claude mcp login workbenches
```

The login opens your browser to sign in.

### Codex

```sh
codex mcp add workbenches --url https://mcp.workbenches.dev
```

Codex starts sign-in automatically. Complete the authorization in your browser; no separate login command is needed.

### Cursor

Use the Add to Cursor button on your organization's setup page in the dashboard, confirm the install in Cursor, then sign in when it asks.

### OpenCode

```sh
opencode mcp add workbenches --url https://mcp.workbenches.dev
opencode mcp auth workbenches
```

The auth command opens your browser to sign in. Add `--global` to the add command if you want the connection available in every project.

### Pi

Pi has no built-in MCP client. It can drive Workbenches through the `wb` CLI and the Workbench skills instead: `npx skills add pompeii-labs/workbenches`.

### Manage connections

The dashboard lists your OAuth connections with each client name, when it connected, when it was last used, and when it expires. Disconnecting one revokes its key; only the member who approved a connection can disconnect it.

## API key

Clients that cannot do OAuth use a key directly. Create one in the dashboard under your organization's API keys, choosing its scopes and expiry, then pass it as a bearer token:

```text
Authorization: Bearer wb_...
```

A key needs the scopes of the tools you use: see [Scopes](#scopes).

### Claude Code

```sh
claude mcp add --transport http workbenches https://mcp.workbenches.dev \
  --header "Authorization: Bearer <key>"
```

### Codex

With the key in an environment variable, in `~/.codex/config.toml`:

```toml
[mcp_servers.workbenches]
url = "https://mcp.workbenches.dev"
bearer_token_env_var = "WORKBENCHES_KEY"
```

### Other clients

Any MCP client that speaks Streamable HTTP and can send a header works. With the TypeScript SDK:

```ts
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';

const client = new Client({ name: 'my-agent', version: '1.0.0' });
await client.connect(
    new StreamableHTTPClientTransport(new URL('https://mcp.workbenches.dev'), {
        requestInit: { headers: { Authorization: `Bearer ${key}` } },
    })
);
const result = await client.callTool({
    name: 'search',
    arguments: { query: 'code review' },
});
```

## What the agent is told

On connect, the server names the organization and the key's scopes in its instructions, and explains the run loop. It also offers a prompt named `guide` with the longer version: how to find, run, and publish Workbenches, the run, wait, send, and answer loop, cursors, and what push does.

## Scopes

| Tool                                                         | Scope                                                                                             |
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------- |
| `search`, `view`                                             | None for public Workbenches. With `catalog:read` they also see your organization's internal ones. |
| `run`, `send`, `answer`, `cancel`, `create_project`          | `runs:write`                                                                                      |
| `wait`, `changes`, `runs`, `sessions`, `projects`, `workers` | `runs:read`                                                                                       |
| `push`                                                       | `packages:write`                                                                                  |

A tool that needs a scope the key lacks returns the API's error.

## Errors

Every result carries structured content and a short text summary. A failure comes back as a tool result with `isError` set and the HTTP status in the message, never as a thrown protocol error. A request with no credential gets `401` and the OAuth challenge; a rejected key gets the same with `error="invalid_token"`. Other refusals from the API keep their own status.

## Before a cloud run

A cloud run needs the organization to hold an `OPENROUTER_API_KEY` secret and a secret for every other environment variable the Workbench marks required. A run on a repository needs GitHub connected for its owner when the repository is private or the run should push. See [Running on workbenches.dev](/docs/cloud/runs).

## Local work

For runs on your own machine, use the `wb mcp` server that ships with the CLI instead. See [Local wb mcp](/docs/mcp/local).
