The first thing I tried to do with Anthropic's new browser tool was install it.

There's nothing to install. No claude mcp add. No npm package. browser_toolset_20260801 is a line in the tools array of a Messages API request — and the browser it drives is one you host, in your app, driven by a handler you write.

That single fact reframes the whole comparison. Playwright MCP is something you plug into Claude Code to test an app. The browser toolset is something you build into a product that happens to drive a browser. They read the same accessibility tree and they answer different questions.

Which doesn't mean the overlap is zero. If you're a QA engineer who already drives a browser from an agent, there are three places where the choice actually bites — and one of them will quietly turn a bug into a passing step if you get it wrong.

What shipped

Two things, both on 19 August 2026, in the Claude Platform release notes:

Computer use went GA as computer_toolset_20260801. No beta header anymore, batch actions (several actions in one turn), zoom on by default, and per-member configuration through configs. Earlier beta versions still work; upgrading changes the request shape.

The browser use tool launched as browser_toolset_20260801. A client toolset: it works inside a browser viewport your application hosts, reads the page itself — accessibility tree, elements, forms, tabs — and adds element references, direct form input, tab management, download reporting and opt-in file upload on top of the screenshot-and-click model. 31 member tools, 27 enabled by default, 4 opt-in.

Both are available on Opus 5, Sonnet 5, Opus 4.8, Mythos 5 and Fable 5 — on the Claude API only. Not on Bedrock, Vertex or Foundry. Not in Managed Agents. If your CI talks to Claude through a cloud provider, the decision is already made for you.

Meanwhile, on the other side: Playwright MCP v0.0.79 (6 August 2026) extended --codegen to python, java and csharp alongside TypeScript, added WebP screenshots, and made the post-action settle delay configurable via --timeout-settle. That's the release that matters here, and I'll explain why in a minute.

The same flow, run both ways

Scenario: log in, add an item to the cart, verify the total matches the sum of the line items. Boring on purpose — it's the shape of about forty percent of every e-commerce suite I've ever touched.

Route A — Playwright MCP inside Claude Code

claude mcp add playwright -- npx @playwright/mcp@latest \
  --codegen typescript --caps testing --isolated

The prompt:

Using the Playwright MCP tools, against http://localhost:3000:

1. Log in as demo@example.com (password in $DEMO_PASSWORD).
2. Add "Wireless Keyboard" to the cart.
3. Open the cart and verify the order total equals the sum of the line items.

Rules:
- Call browser_find before browser_snapshot. Never snapshot the whole page
  when you only need one element.
- Every assertion goes through a browser_verify_* tool. Do not assert by
  reading the page yourself and telling me it looks right.
- When you're done, give me the generated Playwright code.

What comes back is a call sequence — browser_navigate, browser_find, browser_click, browser_fill_form, browser_find, browser_click, browser_find, browser_verify_text_visible — and then the thing you actually wanted:

await page.goto('http://localhost:3000');
await page.getByRole('link', { name: 'Sign in' }).click();
await page.getByRole('textbox', { name: 'Email' }).fill('demo@example.com');
// …
await expect(page.getByTestId('order-total')).toHaveText('$149.98');

A file. You commit it. It runs tomorrow without an API key.

Route B — browser_toolset_20260801

There is no CLI. You send this:

{
  "model": "claude-opus-5",
  "max_tokens": 2048,
  "tools": [{ "type": "browser_toolset_20260801" }],
  "messages": [{
    "role": "user",
    "content": "Log in as demo@example.com, add the Wireless Keyboard to the cart, and tell me whether the order total matches the line items."
  }]
}

Claude replies with member calls that carry "toolset_name": "browser":

{ "type": "tool_use", "name": "navigate",  "toolset_name": "browser",
  "input": { "url": "http://localhost:3000" } }
{ "type": "tool_use", "name": "read_page", "toolset_name": "browser",
  "input": { "filter": "interactive" } }

Your handler executes each one against your own browser session and returns tool_result blocks. read_page gives Claude the tree with references:

link "Sign in" [ref_1]
textbox "Email" [ref_2]
textbox "Password" [ref_3]
button "Continue" [ref_4]

and Claude targets them back:

{ "type": "tool_use", "name": "left_click", "toolset_name": "browser",
  "input": { "target": { "type": "ref", "ref": "ref_1" } } }

You can also attach a browser_state block to any result so Claude tracks tabs, downloads and tab_opened / download_completed events.

At the end you have a correct answer and a transcript. You do not have a test.

Three questions that actually decide it

1. Artifact or outcome?

--codegen gives you a spec file — TypeScript, and since v0.0.79 also Python, Java and C#. The browser toolset gives you a conversation. ref_2 is scoped to a tab and valid only until navigation or a material DOM change. There is nothing in that transcript you can commit, schedule, or hand to someone who doesn't have an API budget.

If your deliverable is a regression test, this question ends the discussion before the other two get asked.

2. Who is your test oracle?

Playwright MCP has real assertions behind --caps testing: browser_verify_text_visible, browser_verify_value, browser_verify_element_visible, browser_verify_list_visible. Playwright executes them. They pass or fail the same way twice.

The browser toolset has no assertion member at all. A "pass" is the model's reading of a screenshot or a tree. For a product feature — "did the agent successfully book the flight?" — that's exactly right. As a test oracle it's a coin with good odds, which is not the same as a coin that always lands the same way.

3. What happens when the element has no accessible name?

This is the one that will get you.

The browser toolset accepts two targeting styles. When there's no accessible name, the model falls back to coordinates:

{ "type": "coordinate", "x": 640, "y": 380 }

Every pointer action takes it. The flow keeps going. The docs are upfront that this is intentional — it's how you drive canvases, embedded content and virtualized lists.

Playwright MCP's ref-based tools have no such fallback unless you explicitly enable --caps vision for browser_mouse_click_xy. On paper: a point for the toolset. It's more robust!

For QA that robustness is the failure. An interactive control with no accessible name is two findings at once — an accessibility defect, and a locator nobody can write. A silent coordinate fallback converts both into a green step and a screenshot that looks fine.

So if you do use the toolset in a testing context, do one of two things: keep coordinate targeting out of the loop entirely, or log every single call where the model targeted by coordinate instead of by ref. That log is not debug output. That log is your accessibility backlog, generated for free, and it's the most useful by-product of the whole exercise.

The token question, honestly

I'm not giving you a benchmark. I'd have to run both against the identical page with identical settle timing to say anything real, and I haven't. What I can tell you is that both have a deliberate cheap path and they're shaped differently:

  • Playwright MCP: browser_find searches the accessibility snapshot for text or a regex and returns matching nodes with a few lines of surrounding context — snippets, not the page. (I went deep on this in browser_find and the token diet.)
  • Browser toolset: find takes natural language and returns up to 20 matches. read_page takes filter: "interactive" and a depth cap, and its output is hard-capped at 50,000 characters. get_page_text returns plain visible text for prose-heavy pages.

Screenshots and zoom are images on both sides and count as image tokens; the toolset docs note that above 20 images per request, stricter per-image limits kick in and there's no server-side downscaling — you resize before you send.

Measure it yourself with the three-step flow above and log tokens per step. It takes an afternoon and the number is specific to your DOM, which is the only number worth having.

The decision table

SituationPick
The deliverable is a spec file you commitPlaywright MCP (--codegen)
You're testing your own app's UIPlaywright MCP
You need a deterministic pass/fail oraclePlaywright MCP (--caps testing)
You're shipping a feature that drives a browser inside your productbrowser_toolset_20260801
The browser lives in your app's viewport and you own the sessionbrowser_toolset_20260801
You reach Claude via Bedrock / Vertex / FoundryPlaywright MCP — the toolset is Claude API only
The target isn't a browser (desktop app, installer, native dialog)computer_toolset_20260801
You need console + network inside the agent's loopEither — toolset configs, or MCP's browser_console_messages / browser_network_requests

What I'd flag before you build on this

  • The toolset is days old. Launched 19 August 2026. I have no long-run experience with it and neither does anyone else. Treat any confident claim about its reliability — including mine — as provisional.
  • Prompt injection is real on both sides. The toolset docs are blunt: page text, tab titles and URLs are untrusted input, isolate the browser, allowlist domains at the network layer, keep javascript_exec and file_upload off. Every word of that applies to Playwright MCP pointed at a staging environment with seeded test data — and almost nobody applies it there.
  • --codegen output is a recording, not a designed test. It still needs the same review pass as anything else an agent writes for you. Nothing about a new browser tool changes that.
  • Batch actions cut both ways. Both toolsets now run several member calls per turn, stopping at the first failure. Fewer round trips, but a failure mid-batch means the later calls come back as "not executed" — your handler needs to report that honestly rather than swallowing it.

Takeaways

  1. browser_toolset_20260801 is not a Playwright MCP replacement. It's an API primitive for a browser your app hosts, and you write the driver.
  2. Ask "artifact or outcome?" first. If you need a committed spec file, --codegen decides it and the other differences don't matter.
  3. Playwright MCP has real assertions (--caps testing). The browser toolset has none. Don't use model judgement as a pass/fail oracle.
  4. The toolset's coordinate fallback is a feature for products and a hazard for testing. Log every coordinate-targeted click — that log is your accessibility backlog.
  5. Claude API only. Bedrock, Vertex and Foundry users don't have this choice yet.

Next up: the toolset's read_console and read_network members are opt-in for a reason, and wiring them into an agent's loop changes what the agent is willing to claim about a failing page. That one deserves its own post.

Last Update: August 23, 2026