What Browser Automation With Claude Actually Means
Browser automation with Claude means handing Claude a real browser to drive, not just code about one. Claude Code ships no browser of its own: WebFetch returns raw HTML, runs no JavaScript, keeps no cookies and clicks nothing. You close that gap with an MCP server — usually Playwright MCP — which gives the model a browser it can navigate, click and read. Claude plans and repairs; the browser executes; your script holds whatever must not vary between runs.
📌 TL;DR Executive Summary
- Core Takeaway: Claude Code has no browser of its own. Add one with
claude mcp add playwright -- npx -y @playwright/mcp@latestand the model gets a browser it can navigate, click and read through accessibility snapshots. - Key Risk/Challenge: Agentic clicking is slow and token-hungry, and most MCP launches start from a clean browser context — so logins, cookies and the profile identity you spent time building disappear between runs.
- Recommended Solution: Use Claude to explore a flow and fix selectors, then freeze the working version into a script pinned to one isolated profile with its own fingerprint and proxy. Send.win runs those profiles locally or in the cloud.
How It Works Under the Hood
Claude Code Has No Browser of Its Own
Claude Code is a terminal agent. You install it with npm install -g @anthropic-ai/claude-code, and it reads and writes files, runs shell commands and inspects what comes back. That loop is genuinely useful for automation work: it scaffolds a Playwright project, runs it, reads the stack trace and patches the selector that broke.
What it cannot do alone is render a page. WebFetch retrieves raw HTML. On a server-rendered page that is often enough. On anything that mounts content client-side, needs a login or draws into a canvas, Claude receives a shell with empty containers. No prompt fixes that, because the JavaScript has to execute somewhere.
MCP Servers Are the Bridge
Model Context Protocol servers give Claude new tools, registered from the terminal with claude mcp add. Remote servers take --transport http; local servers use the default stdio transport, and everything after -- passes to the server process untouched. Giving Claude a browser is one command:
claude mcp add playwright -- npx -y @playwright/mcp@latest
# optional: drive Firefox instead of the installed Chrome
claude mcp add playwright -- npx -y @playwright/mcp@latest --browser firefox
That server needs Node.js 18 or later and no account. It drives whichever Chrome is already installed, so there is no extra browser download and no sign-in step. Because nothing has to authenticate, it is the fastest way to prove your MCP plumbing works before you add anything stateful. If the browser tools never appear after a restart, stop there: browser automation with Claude depends entirely on that registration succeeding.
Scope decides where the server lives. --scope user registers it for every project on the machine; --scope project writes a .mcp.json into the repo so teammates inherit the same setup when they pull it. A project file mixing both kinds of server looks like this:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest", "--headless"]
},
"claude-code-docs": {
"type": "http",
"url": "https://code.claude.com/docs/mcp"
}
}
}
For a zero-configuration test, add Anthropic’s hosted docs server — no auth, full-text search over the Claude Code documentation — with claude mcp add --transport http claude-code-docs https://code.claude.com/docs/mcp. The Claude Code MCP quickstart recommends it as the first entry to try. If it connects, your transports, scopes and config resolution all work, and a later failure points at the browser server rather than your setup.
What the Model Actually Sees
Playwright MCP hands Claude an accessibility snapshot rather than a screenshot, and that difference drives cost. Screenshot-driven agents pay a model call per step, because the model has to look at an image and choose the next move. Snapshot-driven agents pass a text tree instead.
Quoted examples put PinchTab at roughly 800 tokens per text extraction and about 10,500 for a full snapshot, while the same round-up measured agent-browser at 3,000–5,000 tokens per page and Chrome DevTools MCP above 10,000. Those figures depend on the page and the snapshot mode, so read them as the shape of the curve: text trees are cheap, full DOM dumps and screenshot loops are not.
One environment detail matters if you write your own server. Claude Code sets CLAUDE_PROJECT_DIR in the spawned MCP server’s environment to the project root. A server that wants to limit its own filesystem access should implement the MCP roots/list request instead of guessing from the working directory.
Why It Matters — and Where Agentic Control Stops Paying Off
Three groups get real value here. Developers use Claude to write and repair Playwright scripts without leaving the terminal. Sellers and marketplace operators use the browser side to reach dashboards and pull reports from pages that will not render without JavaScript. Agencies use it for exploration — find the field, work out the flow — on accounts they would otherwise click through by hand.
The trade-off is simple, and it shapes what browser automation with Claude is worth. Agentic control is flexible and poor at repetition. Claude Computer Use reads screenshots and moves the mouse, so every step is a model call; one published test ran Claude in Chrome across 49,000 browser operations over 55 days before concluding it is better not to let the agent look at the screen and click. For one open-ended task that overhead buys adaptability. For a routine you run a thousand times, it buys nothing.
| Dimension | Claude drives the browser (agentic) | Claude writes the script (Playwright) |
|---|---|---|
| Best fit | Unfamiliar sites, one-off flows, selector discovery | Fixed routines run repeatedly |
| Cost model | A model call per decision or screenshot | Compute plus proxy traffic, no per-step tokens |
| When the page changes | Usually recovers on its own | Fails loudly until you update the selector |
| Speed per run | Seconds to minutes of reasoning | Seconds |
| Reproducibility | Varies between runs | Identical every time |
| Scheduling | Needs a live model session | Runs from cron or CI unattended |
The working pattern is explore-then-freeze. Let Claude drive the browser until the flow works and the selectors are stable, capture those selectors, then move the routine into a script. Reopen the agent when the site changes.
Setup Checklist: From Zero to a Repeatable Run
- Install the prerequisites. Node.js 18 or later, then
npm install -g @anthropic-ai/claude-code. Playwright MCP needs nothing else, though a local Playwright project pulls three browser binaries that add roughly 900 MB of disk. - Check your plan if you intend to use Chrome integration. That feature requires a direct Anthropic plan (Pro, Max, Team or Enterprise) and is off for API-key or
claude setup-tokensessions. Playwright MCP needs no account at all. - Prove MCP works by adding the hosted docs server and asking Claude a question it can only answer from that server.
- Add the browser.
claude mcp add playwright -- npx -y @playwright/mcp@latest, then restart and confirm the browser tools appear. - Pick a scope. User scope for your own machine, project scope when the whole repo needs the same browser tooling. Anything written into a committed
.mcp.jsonis visible to everyone with repo access. - Decide what drives the browser — Claude in Chrome for your signed-in daily profile, Playwright MCP for anything you want isolated or headless.
- Pin the automation to one persistent profile instead of letting each launch create a fresh context (see the script below).
- Dry-run twice, then commit and schedule the frozen script — not the agentic version.
Step 7 is the one most people skip. Pointing a script at an already-running, isolated profile looks like this in Python:
from playwright.sync_api import sync_playwright
# Attach to a browser you control instead of launching a throwaway one.
# Copy the CDP endpoint from the profile's automation settings in Sendwin Browser.
CDP_URL = "http://127.0.0.1:PORT"
with sync_playwright() as p:
browser = p.chromium.connect_over_cdp(CDP_URL)
context = browser.contexts[0]
page = context.pages[0] if context.pages else context.new_page()
page.goto("https://example.com/dashboard")
page.fill("#search", "order 10482")
page.click("button[type=submit]")
page.wait_for_selector("table.results")
print(page.title())
browser.close()
If you would rather keep the whole stack inside the terminal, the same server can be pinned through .claude/settings.json, where the entry is a command of npx with args of ["@playwright/mcp@latest"]. Custom launch options such as --headless and --port go in the same args array.
Claude in Chrome: Convenient, and Awkward for Multi-Account Work
Claude in Chrome is a Chrome Web Store extension (version 1.0.36 or later) paired with Claude Code and a direct Anthropic plan. It drives your signed-in Chrome profile, which is exactly why it feels convenient and exactly why it is a poor fit for juggling accounts. Per-site permissions are inherited from the extension’s own settings rather than from Claude Code, so you configure them inside the browser. Toggle the integration with --chrome at launch or /chrome mid-session; in VS Code you type @browser.
Recent versions smoothed some sharp edges: from v2.1.211 Claude Code starts normally when Chrome is not running at all, and from v2.1.287 a VS Code session can connect to the browser at startup when “Enabled by default” is on. Anthropic still labels it a beta browsing agent, so the Claude in Chrome documentation is the page to check before you build a routine on top of it.
Which Browser Layer to Give Claude
There is no single best answer, because these tools optimise for different things. Match the layer to the task shape, and treat any star count from an aggregator round-up as a snapshot of one day.
| Tool | Shape | Setup | Watch out for |
|---|---|---|---|
| Playwright MCP (Microsoft) | MCP server, accessibility snapshots, cross-browser | claude mcp add playwright -- npx -y @playwright/mcp@latest |
Needs Node 18+; drives installed Chrome unless you pass --browser |
| Claude in Chrome | Beta Chrome extension tied to Claude Code | Store extension 1.0.36+, direct Anthropic plan | Uses your real signed-in profile; off for API-key sessions |
| Browser MCP (ByteDance) | Puppeteer-based MCP, local and remote connections | Manual install | Chrome and Chromium only |
| BrowserMCP (browsermcp/mcp) | Lightweight control of your existing Chrome profile | npx browsermcp |
Limited feature set compared with the others |
| agent-browser (Vercel Labs) | Rust CLI on a Playwright backend, shell-command output | Install the CLI | On Windows set AGENT_BROWSER_HOME to avoid a UNC path crash |
| PinchTab | Local HTTP server on port 9867 using the accessibility tree | Run locally | Narrow scope, but the cheapest context per page in one comparison |
| browser-use | Python agent framework | Install as a library | Heavyweight; suits complex multi-field forms |
| Computer Use | Screenshot and mouse control | Anthropic API | A model call per step; poor fit for fixed routines |
If you also route traffic through proxies and care about how the browser presents itself, the comparison in this best proxy browser for automation review covers the browser side of the same decision.
Keeping Logins and Cookies Alive Across Runs
Most MCP browser launches start from a clean context. That is a feature when you want a neutral test and a bug when the workflow depends on a signed-in account, a filled cart or a marketplace session that took three steps to establish. The failure looks identical every time: run one works, run two lands on a login wall, and Claude starts improvising a sign-in flow it was never meant to touch. This is the most common way browser automation with Claude breaks in production.
Two fixes. Pin the automation to one persistent profile instead of letting the server launch a disposable one — for a hand-written script, connect over CDP to a browser you started yourself, as in the snippet above. Then isolate per account. Two accounts sharing one browser profile share cookies, localStorage and a fingerprint, and the second account inherits the first one’s history. Playwright multiple browser profiles covers the mechanics of running those side by side.
.mcp.json as public to anyone with repo access.
Proxies and the Only Metric That Matters
Residential proxy list prices in 2026 run from roughly $1/GB at the budget pay-as-you-go end to $5–10+/GB at the premium, low-volume end, with the middle of the market around $3–8/GB. Published 2026 rates show the spread: Bright Data lists $4.00/GB pay-as-you-go, IPRoyal quotes $5.25/GB at a 10 GB step and $4.90/GB at 50 GB, and Decodo lists $35 for 10 GB and $275 for 100 GB.
Sticker price is not the number to optimise. The metric that survives contact with reality is cost per successful request — the per-GB rate divided by your success rate. A $2/GB plan that fails a third of the time costs more per page than a $5/GB plan that almost never does, once you count retries, wasted tokens and the model calls spent diagnosing a block page.
Check three things before committing: whether country targeting is included (it usually is), whether city or ASN targeting and sticky sessions are paid add-ons (often), and whether unused traffic expires at month end. Monthly-expiry traffic with a large minimum is a different product from pay-as-you-go traffic that never expires, even when the headline rate looks better. For the wiring details, see this proxy rotation setup walkthrough.
Common Mistakes and How to Fix Them
A JSON entry with a URL but no type
Claude Code reads an entry that has a url and no type as stdio, skips it, and reports that it needs "type": "http" (or sse or ws). Before v2.1.202 the same mistake surfaced as the unhelpful “command: expected string, received undefined”. From v2.1.219 Claude Code reports a skipped --mcp-config entry in the init event’s mcp_server_errors field, which is what your scripts should read to detect that a server never loaded. From v2.1.265 the client tries HTTP first and falls back to SSE, and streamable-http works as an alias for the http type in .mcp.json, ~/.claude.json and claude mcp add-json.
Expecting WebFetch to render a page
WebFetch returns HTML, not a rendered DOM, and it keeps no cookies between calls. If the data only appears after JavaScript runs, reach for an MCP browser rather than a longer prompt.
Leaving an agentic loop on a fixed routine
Any flow you run daily should not be re-decided every time. Convert it to a script once the selectors settle, and keep the agent for the days when the site changes.
Treating Puppeteer MCP as a supported default
The official Puppeteer MCP package is deprecated; only community-maintained servers remain. Playwright MCP is Microsoft-maintained and reaches Chromium, Firefox and WebKit from one API, so it is the sensible default unless you have a specific reason to go elsewhere.
Scheduling an automation you never dry-ran twice
A single successful run proves nothing about a selector. Run the flow again, capture the selectors, commit them, and check what the job does when the page returns an error or a login wall. Behaviour at scale, once accounts and fingerprints are in play, is its own topic — this stealth automation guide covers it.
Where Send.win Fits in a Claude Automation Stack
Claude decides what to do; something has to supply the browsers and keep them separate. Sendwin Browser is a desktop app for Windows, macOS and Linux with a patched-Chromium engine and the Sendwin Stealth engine built in. Canvas, WebGL, audio, fonts and hardware attributes are spoofed at the engine level and kept coherent, so no two profiles share a fingerprint — the difference between a fleet of accounts and one account with a lot of open tabs.
Every plan includes residential proxies, and timezone, locale, WebRTC and geolocation follow the proxy’s exit IP automatically, so a profile does not announce one country while browsing from another. On the Team plan the local Automation API covers Selenium, Puppeteer and Playwright: you attach a script by copying the profile’s CDP endpoint from its automation settings, which keeps the browser identity stable across runs instead of regenerating it on every launch.
🏆 Send.win Verdict
Claude solves the deciding part of browser automation and none of the identity part. Playwright MCP gives the model a browser, but a fresh context per launch means fresh cookies, a fresh canvas hash and a fresh set of tells for every account you touch. Send.win covers that layer: isolated profiles with coherent fingerprints, built-in residential proxies that set timezone and geolocation from the exit IP, and — on Team — a local automation API so your Selenium, Puppeteer or Playwright script attaches to a profile that stays the same between runs.
Try Send.win free today — 30 days of the full desktop browser, $0 today, cancel anytime; 10 profiles and 1 GB of residential proxy traffic are included from day one.
Frequently Asked Questions
Does Claude Code have built-in browser control?
No. Claude Code is a terminal agent that runs shell commands and reads their output, and its WebFetch tool returns raw HTML without executing JavaScript, storing cookies or clicking anything. Browser automation with Claude comes from an MCP server you add, most commonly Playwright MCP.
How do I add the Playwright MCP server to Claude Code?
Run claude mcp add playwright -- npx -y @playwright/mcp@latest and restart the session. It needs Node.js 18 or later and no account, and it drives the Chrome already installed on your machine unless you append a browser flag such as --browser firefox.
Why does Claude Code skip my MCP server that has a URL but no type?
Claude Code defaults a URL-only entry to the stdio transport, finds no command to run, and skips it while warning that the entry needs "type": "http" (or sse or ws). Older versions reported the same failure as “command: expected string, received undefined”, and from v2.1.219 the skipped entry appears in the init event’s mcp_server_errors field.
Should I use Playwright MCP or Puppeteer MCP?
Playwright MCP, in most cases. It is Microsoft-maintained, reaches Chromium, Firefox and WebKit from one API, and is documented in the official MCP quickstart. The official Puppeteer MCP package has been deprecated, leaving only community-maintained servers.
Can Claude fill in forms and click buttons reliably?
For short, unfamiliar flows it works well enough to be useful. Reliability drops on repetitive routines, because each decision is a model call and the page state can drift between steps. Freeze the flow into a script once you know the selectors, and keep the agent for discovery and repair.
Can I schedule a Claude browser agent to run daily?
You can, but an agentic run needs a live model session and makes decisions that may differ between days. For daily work, convert the flow to a Playwright or Puppeteer script and schedule that, then run the agent manually when the site changes.
Does Claude in Chrome work with multiple accounts?
It drives your signed-in Chrome profile, with per-site permissions inherited from the extension’s own settings, so it is not an account-isolation tool. Running several client or marketplace accounts through one signed-in profile means they share cookies and a fingerprint. Keep those accounts in separate isolated profiles and attach automation to the profile you need.
How many tokens does a page snapshot cost?
It varies with the page and the snapshot mode. Quoted examples range from about 800 tokens for a text extraction in PinchTab to roughly 10,500 for a full snapshot, with agent-browser measured at 3,000–5,000 tokens per page and Chrome DevTools MCP above 10,000. Prefer text extraction over screenshot loops wherever the structure is predictable.
Automate Browser Automation With Claude With Send.win
Send.win pairs isolated, fingerprint-managed browser profiles with a full Automation API, so your scripts run in profiles that look and behave like real, separate users:
- Selenium, Puppeteer & Playwright support – drive any profile programmatically (Team plan)
- Isolated profiles – each with its own fingerprint, cookies, and storage
- Built-in residential proxies – with automatic timezone, locale, and WebRTC matching
- Desktop app for Windows, macOS & Linux – plus cloud sessions when you don’t want a local install
Try the instant cloud browser demo — no install, straight from your browser. Then compare plans: a 30-day free trial with no credit card, and paid plans from $6.99/month billed annually.