MCP server: a hosted browser for coding agents
Connect Claude Code or any MCP client to Browserberg: a hosted endpoint, tools for browsing, delegated tasks, workflows and the audit log, plus a skill.
Last updated:
What MCP gives you
The MCP server puts a real, hosted browser in the hands of any MCP-capable agent — Claude Code, the Claude Agent SDK, Cursor, and the rest. Behind the tools sits the same session API the SDKs use, with the same safety gates on every action, and the same three verified task outcomes.
It is hosted: the control plane serves the server at /v1/mcp over streamable HTTP, authenticated with your API key in the Authorization header. Nothing is installed. The tool list is filtered to what your deployment can actually do, so an agent is never offered a tool that would only refuse.
Session handling stays deliberately boring. One session is created lazily on the first tool call that needs it, is reused by every call after that, and is released when the connection ends — unless a task is still running on it, in which case it is left to its own deadline so the task can finish and be polled. Every browser tool accepts an optional sessionId for the cases where you want two sites at once.
Connect your agent
The hosted endpoint is the recommended way: add it to your agent’s MCP configuration with your key in the header. The stdio form runs the open-source package locally with `npx` and suits clients without HTTP transport or a self-hosted deployment.
{
"mcpServers": {
"browserberg": {
"type": "http",
"url": "https://browserberg.com/v1/mcp",
"headers": { "Authorization": "Bearer bb_your_key_here" }
}
}
}
{
"mcpServers": {
"browserberg": {
"command": "npx",
"args": ["-y", "@browserberg/mcp"],
"env": { "BROWSERBERG_API_KEY": "bb_your_key_here" }
}
}
}
The browser tools
Inference cost is per tool call and shown in the second column. Reading a page and managing sessions cost nothing; one plain-language action costs one model call; a delegated task costs several.
| Name | Type | Description |
|---|---|---|
browser_navigate
|
no model call | Opens a URL as a plain deterministic step; the usual first move. |
browser_observe
|
no model call by default | Reads the live page and returns actionable candidates. Without an instruction it makes no model call; with one, the model filters what it found. |
browser_act
|
one model call | Performs one plain-language action. A plan-cache replay of a step the platform has seen before is free. A step the safety gates withhold comes back as content with the reason, not as an error. |
browser_extract
|
one model call | Pulls structured data out of the page, optionally against a JSON Schema, with German number and date formats left exactly as the page writes them. |
browser_run_task
|
several model calls | Hands a multi-page goal to the hosted agent and waits up to `waitSeconds` (default 45). Takes a `startUrl` — a session with no page open and no start URL is refused, so the agent never begins on a blank tab, and a task with a start URL stays pinned to that site unless `pinToStartSite` is set to false. A task still running then returns a `taskId`; the outcome is `completed`, `terminated` or `failed`. |
browser_task_status
|
no model call | Polls a task by id — with an optional wait — and returns the answer, data and the reviewer’s verdict once it has finished. Needs no browser. |
browser_new_session
|
no model call | Opens another session: a second site in parallel, a stored profile, vault credentials by id, a reserved pool, or a different locale and time zone. |
browser_list_sessions
|
no model call | Lists the sessions this connection holds and the organisation’s other open sessions, which can be attached by id after a reconnect. |
browser_close_session
|
no model call | Releases a session. Refuses, and says so, while a task this connection started is still running on it. |
browser_session_info
|
no model call | Reports a session’s id, expiry and CDP endpoint. It never creates one, so it is safe to call at any moment. |
browser_watch_url
|
no model call | Returns a dashboard link a person opens to watch the session live and, as an owner, take it over — for a one-time code, a consent wall, or a login the vault cannot do. |
Workflows, triggers, vault and audit
The management surface, listed only where the deployment has it. None of these tools costs a model call; a workflow run costs what its blocks cost.
| Name | Type | Description |
|---|---|---|
workflow_list · workflow_get · workflow_publish
|
no model call | Recorded, versioned jobs. Publishing validates the whole definition at once and returns every problem; versions are immutable and a run executes the version it started with. |
workflow_run · workflow_run_status · workflow_cancel_run
|
the blocks’ cost | Runs a workflow in a session with the same bounded wait as a task, polls a run by id, or asks it to stop between blocks. |
workflow_heal_list · workflow_heal_decide
|
no model call | Drift-repair proposals written after a selector stopped matching. Adopting publishes a new version; nothing changes until a person decides. |
trigger_create · trigger_list · trigger_set_status · trigger_firings
|
no model call | Schedules a workflow with a cron expression and an IANA time zone, pauses and resumes it, and answers why a trigger did or did not fire. Webhook triggers are created in the dashboard, because their signing secret is shown once and must not pass through a conversation. |
credential_list · profile_list
|
no model call | Vault credentials by name and field names — never a value — and stored browser profiles, both referenced by id when opening a session. No tool creates or reads back a credential. |
audit_log
|
no model call | The tamper-evident record of what was actually done, filtered to the current session by default. The verifiable export for an auditor stays `GET /v1/audit/export`. |
Three outcomes, and the handle
browser_run_task ends in one of three states, and they are not the same thing. completed means the work was done and a separate reviewer confirmed it against the re-read page. terminated means the agent looked and the site genuinely does not offer this — the right response is to tell the user what the reviewer saw, not to retry. failed means something broke, and one retry is reasonable.
A task is asynchronous by contract. The tool waits a bounded time and returns the finished result when it can; a task still running afterwards returns a taskId and continues in the background, to be polled with browser_task_status. An agent that starts the task again because the first call “came back early” is doing the one thing the tool description most warns against. Waiting tools send MCP progress notifications, so a client that asked for them can keep its own timeout from firing.
What never passes through the conversation
No tool creates a credential or reads one back. Logins use the vault by reference: credential_list shows names and field names, the id goes into browser_new_session or a workflow login block, and the secret is typed inside the browser, site-checked, and never returned. Webhook signing secrets are handled the same way — created by a person in the dashboard, shown once — which is why trigger_create accepts schedules only.
When a person is needed — a one-time code, an unexpected consent wall, a login the vault cannot do — browser_watch_url returns a dashboard link. The person watches the session live and, as an organisation owner, can take over the mouse and keyboard; the agent waits until they say they are done.
Errors, self-hosting and the skill
When a tool call goes wrong — a withheld destructive click, an expired session, a refused extraction — the failure comes back as the tool’s result, not as an MCP protocol error. The agent can read the message and react, instead of the whole conversation dying on a transport fault.
For the local form, BROWSERBERG_API_KEY is required and BROWSERBERG_BASE_URL points the server at a self-hosted deployment. The package needs a server speaking wire protocol 1.3.0 or newer and refuses an older one at startup with a message saying which side to upgrade. The hosted endpoint takes an API key, or an OAuth token from the control plane’s own authorization server for clients such as claude.ai — see Connect claude.ai.
The npm package ships a skill — skills/browserberg/ — that teaches an agent when to read a page itself, when to delegate a task, when to record a workflow, how to read the three outcomes, and what never to type. Install it alongside the server; it is what turns the tool list into good behaviour. For how the MCP integration compares with driving the API directly, see the MCP integration page.