---
title: "Drive Studio with a browser agent"
description: "Register Verbatra Studio's review actions as WebMCP tools so a browser AI agent can work your open, authenticated dashboard tab."
type: "how-to"
---
# Drive Studio with a browser agent

Register Verbatra Studio's review actions as WebMCP tools so a browser AI agent can work your open, authenticated dashboard tab.

Use this to let a browser AI agent, such as Gemini or Claude in Chrome, check drift, work the review queue and fix entries in the Studio tab you have open. It is not for project setup or remote access.

You need:

- Studio running over your project ([Review in Studio](https://verbatra.kreitz-webdev.de/docs/review-in-studio.md#start-studio));
- Chrome 149 or later with `chrome://flags/#enable-webmcp-testing` enabled, or a browser with native WebMCP support, in a normal window rather than a headless one.

<Callout title="Experimental">
WebMCP is a new browser capability behind a flag, and its surface may still change.
</Callout>

## Turn the tools on [#turn-the-tools-on]

```bash
verbatra studio --expose-agent-tools
```

`VERBATRA_STUDIO_AGENT_TOOLS=1` does the same; [Spend and agent tools](https://verbatra.kreitz-webdev.de/docs/cli/studio.md#spend-and-agent-tools) shows how the flag and the variable resolve. Open the printed URL in the WebMCP browser, and the agent on that tab finds the tools. In a browser without WebMCP, Studio registers nothing.

To let the agent call your provider, start Studio with `--allow-spend` as well.

The agent reads every value unredacted, as the page shows it, because an agent on the tab can read the page anyway. The exceptions are the glossary tools and `verbatra_history_keyRevisions`: their values pass through secret redaction, so a value shaped like an API key comes back as a placeholder. To keep values from an agent, use the MCP server with [`--redact-values`](https://verbatra.kreitz-webdev.de/docs/cli/mcp.md#redacted-values) instead; for an NDA project, see [Studio and MCP](https://verbatra.kreitz-webdev.de/docs/data-handling.md#studio-and-mcp).

## Know what the agent can call [#know-what-the-agent-can-call]

Each tool is a Studio action with a `verbatra_` prefix. Read tools are marked read-only, write tools change only your local files, and spend tools register only with `--allow-spend`.

### Read tools [#read-tools]

| Tool | What it does |
| --- | --- |
| `verbatra_project_snapshot` | the loaded config, the capabilities, and, under `capabilities.limits`, the rate limits of `retranslate`, `reviewDecision` and the two value-replace methods |
| `verbatra_status_check` | coverage per locale |
| `verbatra_status_diff` | missing, changed and orphaned keys per locale |
| `verbatra_glossary_get` | the resolved glossary, secret-redacted |
| `verbatra_lock_state` | the lock file's state per locale |
| `verbatra_history_list` | recent commits to the locale files, with the author's name ([never the email](https://verbatra.kreitz-webdev.de/docs/data-handling.md#studio-and-mcp)) |
| `verbatra_history_keyRevisions` | one key's commits in one locale, with word diffs, keys scrubbed <AvailableFrom version="0.7.0" pkg="@verbatra/studio" /> |
| `verbatra_key_integrity` | placeholder, markup and ICU checks for one key, in the locales where its source changed |
| `verbatra_review_queue` | every machine-written value nobody has approved, from the committed files <AvailableFrom version="0.6.0" pkg="@verbatra/studio" /> |
| `verbatra_key_value` | one key's source and target, with who wrote the target |
| `verbatra_key_context` | one key's description, glossary terms and `maxLength`, and a check of an optional `draft` <AvailableFrom version="0.6.0" pkg="@verbatra/studio" /> |
| `verbatra_locale_values` | key values per target locale, 200 per page by default, narrowed by `locales`, `keys` or `query` |
| `verbatra_locale_integrity` | every translation that fails the integrity checks <AvailableFrom version="0.6.0" pkg="@verbatra/studio" /> |
| `verbatra_translation_estimate` | what a translate-pending call would send and cost, without calling a provider |
| `verbatra_usage_summary` | the last run's token usage and budget |
| `verbatra_usage_history` | recorded runs, newest first, with tokens, cost and coverage, as counts only <AvailableFrom version="0.7.0" pkg="@verbatra/studio" /> |

### Write tools [#write-tools]

| Tool | What it does |
| --- | --- |
| `verbatra_glossary_write` | change one term of a file-backed glossary <AvailableFrom version="0.4.0" pkg="@verbatra/studio" /> |
| `verbatra_review_approve` | record a named person's approval of one value <AvailableFrom version="0.6.0" pkg="@verbatra/studio" /> |
| `verbatra_review_reject` | record a named person's rejection, removing the value |
| `verbatra_translation_editEntry` | write one value through the integrity gate |

### Spend tools [#spend-tools]

| Tool | What it does |
| --- | --- |
| `verbatra_translation_retranslateEntry` | retranslate one key in one locale |
| `verbatra_translation_translatePending` | translate everything pending, optionally for some `locales` under a `maxTokens` ceiling <AvailableFrom version="0.6.0" pkg="@verbatra/studio" /> |

`verbatra_key_integrity` returns only the locales where the key's source changed, so an empty list means nothing needed checking. Its rows are flatter than the MCP server's [`key.integrity`](https://verbatra.kreitz-webdev.de/docs/cli/mcp.md#inputs-and-results). Only the MCP server has `project.doctor` and `report.provenance`. `verbatra_locale_values` pages like its `locale.values`, with the same `limit` and `cursor` ([More inputs and results](https://verbatra.kreitz-webdev.de/docs/cli/mcp.md#more-inputs-and-results)).

## Know the rules the tools follow [#know-the-rules-the-tools-follow]

Every call goes through the dashboard's own authenticated loopback RPC, with the same input validation and [integrity gate](https://verbatra.kreitz-webdev.de/docs/translation-safety.md): a value that fails a check is rejected, not written.

### Per-call rules [#per-call-rules]

<AvailableFrom version="0.6.0" pkg="@verbatra/studio" />

- **Provenance**: an agent's edit is recorded with the origin `agent` and stays in the review queue; a dashboard edit is `human`. The read tools report who wrote each value ([The lock file](https://verbatra.kreitz-webdev.de/docs/the-lock-file.md#provenance-who-wrote-each-value)).
- **Human work**: retranslating refuses a person's value with `KEY_PROTECTED` (except with `humanEdits: "overwrite"`) and a pinned key with `KEY_PINNED`, and editing refuses a pinned key ([Keep human translations](https://verbatra.kreitz-webdev.de/docs/protecting-human-translations.md)).
- **Review decisions**: approve and reject only relay your decision. Both need `reviewer`, the person's name, and `expectedValue`, the text reviewed; a changed value is refused with `REVIEW_VALUE_CHANGED`.
- **No bulk tools**: **Approve selected**, **Reject selected**, **Retranslate selected**, **Approve all in** and **Search and replace** stay person-only.
- **Estimate first**: an unknown locale is refused with `UNKNOWN_LOCALE` before anything is spent, and the lower of the call's and the config's `maxTokens` applies ([Estimate cost before a run](https://verbatra.kreitz-webdev.de/docs/estimating-cost.md)).
- **Rate limits**: per rolling minute, 20 retranslations, 20 edits, 20 glossary writes, 60 review decisions and 5 translate-pending calls, one at a time.

## Read a failed call [#read-a-failed-call]

Every tool returns the dashboard's envelope, so a failure reads `{ "ok": false, "error": { "code": ..., "message": ... } }`. Besides the SDK's own codes, the RPC layer adds:

| Code | Meaning |
| --- | --- |
| `REQUEST_INVALID` | the request or the answer was not a readable envelope |
| `METHOD_UNKNOWN` | the method does not exist on this Studio version |
| `SPEND_DISABLED` | a spend method while spending is off: Studio runs without `--allow-spend`, or the provider is `none`; the message names which |
| `PARAMS_INVALID` | a parameter failed validation; `issues` names each field |
| `METHOD_RATE_LIMITED` | over the rate limit; `retryAfterSeconds` says when the call fits |
| `BATCH_TOO_LARGE` | a batch exceeds a whole rate-limit window; send fewer entries |
| `ALREADY_IN_PROGRESS` | a second call for an entry still in flight (HTTP 409) |
| `SESSION_EXPIRED` | Studio restarted with a new token; open the URL it printed |
| `INTERNAL` | a handler failed with an unexpected error (HTTP 500); the message is generic |

## Fix degraded tools [#fix-degraded-tools]

If the browser rejects a registration, every view shows a warning such as:

> Agent tools degraded: 2 of the agent tool registrations failed with SecurityError. The dashboard itself is unaffected. The browser console lists every failing tool.

The console has one line naming each failure:

```text output
Verbatra agent tools: 2 of 20 tool registrations failed. verbatra_status_diff (SecurityError: ...); verbatra_key_value (SecurityError: ...)
```

Read the error name there first, then reload the tab, which runs registration again. A missing flag or a browser without WebMCP never shows this notice; it registers nothing, silently. A session without `--allow-spend` attempts two fewer registrations, which is not a failure.

## Weigh the spend risk [#weigh-the-spend-risk]

The tools add no network exposure: Studio still binds only to `127.0.0.1`, every request carries the session token, and tools that return project text mark it as untrusted, so the agent treats it as data.

<Callout type="warn">
With both `--allow-spend` and `--expose-agent-tools`, an agent can spend on your provider without a per-call confirmation, up to the rate limits. Studio cannot tell an agent's call from your click, so it adds no approval dialog. For read-and-edit only, leave `--allow-spend` off.
</Callout>

## Related [#related]

- [Review in Studio](https://verbatra.kreitz-webdev.de/docs/review-in-studio.md): the same workflow by hand.
- [`verbatra studio`](https://verbatra.kreitz-webdev.de/docs/cli/studio.md): every flag and the startup contract.
- [Connect an MCP client](https://verbatra.kreitz-webdev.de/docs/connect-an-mcp-client.md#the-verbatra-plugin): the plugin carries the `verbatra-studio-agent-tools` skill, but you start Studio yourself.
