Undetectable browser infrastructure

Cloud browsers that don't look automated.

Most cloud browsers are just Playwright over CDP in someone else's data center. browserscale replaces the control plane — automation runs inside the Chromium engine, so sites see a real user. Drive thousands of parallel sessions from Go or TypeScript — or let your coding agent write the program that drives them.

First script in under 5 minutes·Or scaffolded by your agent in one command·Pay-as-you-go credits·No browser farm to run

worker.ts
01import { rentBrowser, BrowserConfig, css } from "browserscale-ts";0203const cfg = new BrowserConfig("sk_...", 300, "", 0, "", "");04const browser = await rentBrowser(cfg);05await browser.navigate("https://example.com");06await browser.wait(css("h1"));0708console.log((await browser.evaluate("document.title")).value);09await browser.stopBrowser();
Undetectable by architectureReal consumer GPUsFlat frame treeEvent-driven waitsHuman-like inputManaged proxiesCaptcha solvingNetwork interceptionLive WebRTC controlSession persistenceGo & TypeScript SDKMCP for agentsAgent-ready scaffoldMulti-threaded boilerplateUndetectable by architectureReal consumer GPUsFlat frame treeEvent-driven waitsHuman-like inputManaged proxiesCaptcha solvingNetwork interceptionLive WebRTC controlSession persistenceGo & TypeScript SDKMCP for agentsAgent-ready scaffoldMulti-threaded boilerplate
< 0 ms

cold spin-up per session

0+

isolated sessions per job

0

injected scripts or CDP signals

Go · TS

SDKs, plus a CLI and MCP for agents

Agent mode

Your agent doesn't click for you. It ships the program.

Scaffold a project, open the folder in Cursor, Claude, Codex or whatever you use, and describe the job. What comes back is not a session someone watched happen — it is a multi-threaded Go program you can read, review and run again tomorrow.

One command, a running project

browserscale-cli init asks for a lifecycle and a worker count, then writes a Go module that already compiles and runs — harness, config schema, worker loop, proxy pool and rent-with-backoff, plus a worked browser flow to pattern-match against.

Your agent reads signatures, not vibes

Every scaffold ships an AGENTS.md and the whole SDK reference offline, so the agent greps real method names instead of inventing ones that don't exist. Fewer wrong-API round-trips, fewer tokens burned on guesses.

It can run and fix its own work

browserscale-cli dev rebuilds, restarts and streams the logs from one command. The agent starts the run, reads what actually happened and iterates — no hand-rolled build-and-kill loop in the middle of your session.

browserscale-cli initcompiles as-is
orders-bot/
main.gohands off to the harness
module.goconfig schema + workers
flow.gothin dispatcher
register.goa worked browser flow
run.goqueue loop, 8 workers
rent.goproxy pool + backoff
AGENTS.mdthe agent reads this first
docs/the whole SDK, offline
data/proxies.txt · accounts.csv
go run . works before you write a line8 workers

Included: browserscale-kit

The scaffold imports the kit, so everything a real bot needs around the browser flow is already wired — and neither you nor your agent writes it again.

Worker harnessConfig TUIWork queuesProxy poolsSQLite storeIMAP OTP fetchTree loggerPer-run artifacts

MCP server

A live browser, right inside your IDE.

browserscale runs a hosted MCP server, so the agent writing your flow can watch the real page while it does. It rents a session, reads the DOM with observe, tries a selector, takes a screenshot — and then writes the code that does it for good.

mcp.jsonpaste and go
{  "mcpServers": {    "browserscale": {      "url": "https://mcp.browserscale.cloud/mcp",      "headers": {        "Authorization": "Bearer sk_…"      }    }  }}

The same verbs as the SDK

observe, wait, click, fill, evaluate, screenshot, solve_captcha and the rest map one-to-one onto SDK methods. Whatever the agent proves out by hand translates line for line into the flow it writes.

Stateless, so sessions outlive the chat

rent hands back a sessionId that every later call carries. The agent can also attach to the browser a failed run left behind and look at the real page instead of reconstructing it from a stack trace.

Any MCP client, one URL

Cursor, Claude, Codex, or something you wrote yourself. The key travels as an Authorization header, never as a tool argument, so it stays out of the model's context.

The tools it exposes

Every browser action your agent needs, named the way the SDK names it — so moving from probing to code is a copy, not a translation.

rentnavigateobservewaitclickfilltypeselectpress_keyinsert_textmove_toscroll_todragevaluatescreenshotsolve_captchaget_cookiesset_cookiesget_storageset_storagestop+ more

The cost of autonomy

Tool calls burn tokens. Code doesn't.

Both setups start with a model and a browser. What separates them is where the logic ends up: in a context window that gets thrown away, or in a program that keeps running without one.

Elsewhere

The agent as a remote control

An MCP server on its own turns the model into a pair of hands. Useful for looking around, expensive as a way to get work done.

One run costs
tokens for every single step
Run number 1000 costs
the same again, a thousand times
Parallelism
one session per conversation
When something breaks
re-prompt and hope
What you keep
a chat transcript
browserscale

The agent as the author

The scaffold gives the model somewhere to put the logic. It spends tokens once, on writing Go, and the program carries the work from then on.

One run costs
tokens once, while it writes the code
Run number 1000 costs
no model in the loop at all
Parallelism
as many workers as you configure
When something breaks
logs, artifacts and a store you can query
What you keep
a Go program in your repo

Developer experience

Calls you can't write anywhere else.

The point isn't fewer lines — it's that these calls have no equivalent in a CDP-based tool. When automation runs inside the engine, the page's own boundaries stop being yours.

Native inputelsewhere: synthetic el.click()
await b.click(js(`  [...document.querySelectorAll("button")]    .find(b => b.textContent      === "Continue"`));

Real clicks on JS-resolved elements

Hand any JavaScript that returns an element — browserscale dispatches a real, trusted pointer event at its actual coordinates. A CDP resolver only runs through evaluate, which can just fake the click.

Multi-waitelsewhere: hand-rolled Promise.race
const wr = await b.waitAny([  css("#ok"), css("#err"),  js("captchaUp()")]);// wr.index → which one won

Race outcomes in one call

Wait for success, error and captcha together; the result tells you which condition won and in which frame — no racing promises, no tearing down the losers.

Closed shadow DOMelsewhere: el.shadowRoot === null
await b.click(js(`  __wrc.shadow(host)    .querySelector("button")`));// closed OR open — same call

Reach where the page hides things

__wrc.shadow(host) returns a closed shadow root and reads it natively in the renderer — no page JS, invisible to the site. Target actions with the same expression.

And it keeps going: .inAllFrames() searches every frame including cross-origin iframes, readCanvas returns tainted canvas pixels, captcha solving runs in-flow. Every action lands as a real, trusted input event — which is exactly what an AI agent that reasons in code needs: emit a resolver, get a human-grade action.

Under the hood

Wired into the engine, not bolted on top.

Playwright and Puppeteer drive the browser from outside, over the DevTools protocol. browserscale control runs below the page — native in the browser engine — which is where both the undetectability and the speed come from.

No JS trace, no side effects

Commands run natively inside Chromium itself, straight in the renderer process. Nothing is injected into the page, no Runtime.enable, no DevTools handshake — page JavaScript cannot observe the automation at all.

Waits without polling

CDP-based stacks ask “is it there yet?” in a round-trip loop over a WebSocket. A browserscale wait is armed once inside the engine, runs fully async and fires the instant the condition is met.

Steady-time built in

An element is only reported back once it exists and holds position in the DOM. Animations and layout shifts are absorbed before your click — not discovered after it missed. And it's all configurable from the SDK — relax the checks to match hidden or off-screen elements when you need to.

wait(css("button.pay"))resolves in-engine
CDP-based toolspolls over WebSocket
exists?no ·exists?no ·exists?no ·exists?found

every check is a round-trip — and the element can still move right after the last one

browserscaleevent-driven, in-engine
armed in renderer······ async ······→rendered & steady → resolved

one call in, one event out — steady-time check included

0 injected scriptsno CDP session1 round-trip per wait

Parallelism & spin-up

Thousands of browsers, ready in milliseconds.

No VM to boot, no container to warm. Every session is its own isolated browser context that spins up in under 50 ms — so you can fan out to thousands of unique, fully isolated browsers in parallel without queueing on cold starts.

Contexts, not VMs

A session is an isolated browser context, not a fresh VM or OS process. There's no machine to boot and no cold container to warm, so a browser is ready in under 250 ms instead of seconds.

Unique and fully isolated

Every context carries its own cookies, storage, cache and fingerprint. Nothing leaks between tasks, so thousands of jobs run side by side without ever sharing or colliding on state.

Fan out to thousands

Launch one browser or ten thousand from the same SDK. Spin-up stays flat because there's no per-session VM overhead to amortize — scaling out is just more contexts.

rentBrowser() ×1000context-isolated
ctx·8a3f
ctx·8b56
ctx·8c6d
ctx·8d84
ctx·8e9b
ctx·8fb2
ctx·90c9
ctx·91e0
ctx·92f7
ctx·940e
ctx·9525
ctx·963c
ctx·9753
ctx·986a
ctx·9981
ctx·9a98
ctx·9baf
ctx·9cc6
< 250 ms

cold spin-up per context

0 shared

state between contexts

How it compares

Not another Playwright wrapper in the cloud.

The short version, side by side. Everyone else drives Chromium from the outside over CDP; browserscale replaced the control plane and wrapped a real platform around it.

CapabilitybrowserscalePlaywright / PuppeteerOther cloud browsers
Where control livesInside the browser engineOutside, over CDPPlaywright/CDP, hosted
Automation tracesNone — no injected JS, no Runtime.enableCDP control-plane + injected scriptSame CDP signals
Fingerprint & GPUReal consumer GPUs, no spoof layerWhatever your machine isSpoofing layer / hash database
Frames & OOPIFsOne flat frame treePer-frame contexts to juggleSame juggling, remotely
WaitingEvent-driven in-engine + steady-timePolling / actionability checksPolling over the wire
Spin-up & scaleContexts, < 250 ms, thousandsBrowsers you host & scaleVMs/containers, cold starts
Captcha solvingBuilt in, solved in-flowDIY or third-party serviceAdd-on / external API
Network interceptionAt the network source, no racesCDP route handlers, racyCDP-based
Watch & take over liveWebRTC stream + input takeoverNoneView-only, if any
What you drive it withGo & TypeScript SDK + MCPLanguage bindingsMostly a raw endpoint
How a coding agent uses itMCP to look, CLI to ship codeYou write every line yourselfMCP remote control, per click
Infra to runNone — fully managedYou host and scale itManaged
wait(css(".pay").inAllFrames())flat tree
mainframeId="F0"document
└─ iframeframeId="F1"same-origin
└─ iframeframeId="F2"OOPIF · cross-origin
✓ .pay matchedresult.frameId = "F2"
click(node(id).inFrame("F2")) — no frame switching

Frames & OOPIFs

Reach into any iframe — no juggling.

With Playwright, Puppeteer or raw CDP you juggle flattened sessions, async Runtime.enable and a fresh execution context for every cross-origin frame. browserscale collapses all of that into one flat frame tree where an OOPIF is just another node.

One flat frame tree

Every frame — main document, same-origin iframe or cross-origin OOPIF — is just a string frameId in one tree. No execution-context bookkeeping, no waiting on Runtime.enable to hand you a context per frame.

Act across all frames at once

Wait and click in every frame with one call, or scope to a single iframe. Whether the target sits in a nested OOPIF or the top document is irrelevant — the SDK resolves the nesting for you.

Wait tells you where it hit

Search across all frames and the WaitResult hands back the frameId that matched, ready to pass straight into the next action. No second lookup, no manual frame switching.

Browser agents

Built for browser agents.

Hand your model a compact view of the page instead of a megabyte of raw HTML. browserscale returns only the visible, interactive elements — as text or JSON — so your agent reasons over what matters and spends tokens where they count.

Prompt-sized snapshots

One line per visible element, under headers with the URL, title and scroll offset — so the model never spends a round-trip asking where it is.

Sees inside every frame

Nested iframes, cross-origin OOPIFs and closed shadow roots all show up in the same observation, each tagged with its frame.

Live form state

The value actually typed into a field, checkbox state, select options, and a flag when an id is duplicated — no JS probing needed.

getObservation()one line per element
# frame 8F03BF2E… https://shop.example/checkout
# title "Checkout"
h1[32] "Checkout"
input#email[44] type="email" name="email" value="ada@…" required click "E-Mail"
iframe[51] src="js.stripe.com" frameId=A91C…
input[7] name="cardnumber" value="" required click "Card number"
button[9] type="submit" click "Pay"
a[63] href="/help" click "Need help?"
URL, title and live values included · 2 frames~340 tokens

Remote browser

See and steer every session live.

Every cloud browser streams straight to your screen over WebRTC. Watch automation run in real time, then grab the controls and finish any flow by hand.

example.com/checkout
LIVE
Checkout
Step 2 of 3 · Payment
Email
alice@example.com
Card number
4242 4242 4242 4242
Expiry
09 / 28
CVC
•••
Order summary
Pro plan · annual$192.00
Tax$36.48
Total$228.48
Place order
WebRTC
MouseKeyboardTake over

Low-latency H.264 stream

Chromium encodes natively and streams over WebRTC, so the view stays smooth even under load.

Take over with mouse & keyboard

Input rides dedicated data channels, so you can jump in and drive any session by hand.

Debug what your script sees

Spot failed selectors, redirects and surprise popups by watching the real rendered page instead of guessing from logs.

Returning visitor

fp_8a3f2c…

pinned
User agent
Canvas & WebGL
Audio stack
Cookies & storage
Locale & timezone
Fonts & screen
Run #1 · MonRun #128 · Fri

same identity, weeks apart

Session persistence

Come back as the same user.

Pin a fingerprint and reuse it across rentals. The user agent, canvas, WebGL, audio and locale replay alongside cookies and storage, so sites see a returning visitor instead of a brand-new install.

Replayable fingerprints

WithFingerprint(id) restores the whole browser identity, not just cookies.

Cookies & storage that stick

GetCookies/SetCookies and GetStorage/SetStorage carry login state and localStorage across separate rentals.

Reattach from anywhere

ConnectSession picks up a running session from another worker or process.

Real hardware

Rendered on real silicon, not simulated.

Most cloud browsers run on VM cores and answer canvas and WebGL probes from a spoofing layer or a fingerprint database. browserscale sessions execute on real consumer GPUs — our own hardware — so every pixel a site reads back was actually rendered.

Real consumer GPUs, our own hardware

Every session runs hardware-accelerated on real consumer GPUs that browserscale owns and operates — not on VM cores with a WebGL faking layer bolted on. Nothing is simulated; it executes on the silicon.

No fingerprint database to maintain

Spoofing stacks live off stored canvas hashes, toDataURL answers and getImageData lookups — and break when a site probes something new. browserscale has nothing to look up: every readback is real pixels, rendered fresh and replayable on the same real GPU.

Future-proof against new checks

Passive bot protections probe rendering deeper every year. A faking layer has to chase each new check; real execution passes them by default, because there's nothing to unmask.

session.renderinghardware-accelerated
WebGL rendererreal consumer GPU
canvas.toDataURL()real pixels, no hash DB
getImageData()rendered on silicon
WebGL spoofing layernone — nothing to unmask
VM cores + faked GLnot here
executed for real — replayable on the same GPU

Captcha

Captchas, solved in the same run.

Passive anti-bot checks pass on their own thanks to real fingerprints, real hardware and clean, CDP-free control. For interactive challenges, browserscale's own AI solver completes the challenge right in the live browser — the provider's own JavaScript issues the token, no external solver API in the loop.

awaitbrowser.solveCaptcha({ retryAmount: 2 })
DetectSolveContinue

In-house AI solver

Learns the known challenge types — puzzle, OCR, slide, hold and more — on its own, and keeps improving as they evolve. Solving runs inside browserscale, not at an external provider.

No token generation, no external APIs

browserscale never synthesizes a token. The challenge is completed in the live session and the provider's own JavaScript runs untouched in a valid browser, issuing the token exactly as it would for a real user. No extra accounts, keys or per-solve contracts.

Future-proof, even for unknown checks

Because everything runs in a genuine browser on real hardware, protections browserscale has never seen before pass too — there's no emulated environment or synthesized response for a new check to expose.

waitForAnyResponse("*/api/checkout")armed in-engine
F0GET/assets/app.js→ observed
F1GET/tracker/collectblocked
F2 · OOPIFPOST/api/checkout✓ matched
F0GET/api/profileheaders modified
resolved— response body captured, zero requests slipped

Network

Every request passes through you.

CDP-based interception hooks in from outside — and races navigations, late-attaching frames and OOPIFs, where requests slip through before the handler lands. browserscale sits directly at the browser's networking source, so every request from every frame is yours to observe, block, mutate or await.

Sits at the source

Interception lives in the browser's network stack itself, so every request from every frame — main document, iframes, cross-origin OOPIFs — flows through one choke point. Nothing slips past unobserved.

No handler races

CDP-based route handlers race navigations and freshly attached frames — a request that fires before the hook lands is gone. A browserscale wait is armed once inside the engine, so even the request that fires a millisecond later is caught.

Block, mock, mutate, await

WaitForAnyRequest and WaitForAnyResponse race URL patterns and resolve on the first hit. ModifyRequest rewrites headers or body in flight, SetBlockList drops what you never want loaded — all with the same wildcard vocabulary.

Bandwidth & cost

Stop re-downloading the same assets.

Repeating a flow usually means pulling the same JavaScript, CSS and images through your proxy on every run. Mark them as static paths once and browserscale serves them from a server-side cache — only the bytes that matter travel through your proxy.

Cache once, reuse forever

SetStaticPaths snapshots JS, CSS and images by wildcard for the whole session.

Less proxy bandwidth

Repeat runs skip the heavy static fetches instead of re-downloading them.

Faster, cheaper loads

Pages render from the server-side cache rather than the network.

Proxy bandwidth / runsetStaticPaths()
Without cache4.2 MB
With static paths0.4 MB
~90%less proxy traffic on repeat runs

Platform

Everything around the browser, handled.

Rent the browser from your SDK and let browserscale take care of the hard parts: identity, input, proxies, captchas, networking and live inspection. One platform — not a raw endpoint you build everything on.

Engine-level control

Every command runs natively inside Chromium — no DevTools protocol, no injected JS, nothing for a page to observe.

Isolated in < 250 ms

A fresh browser context per task with its own cookies, storage and fingerprint — not a VM to boot.

Real-GPU fingerprints

Canvas, WebGL, audio and codecs render on real consumer GPUs we own — no spoofing layer to unmask.

Human-like input

Clicks travel realistic pointer paths and typing streams real key events — not synthetic DOM dispatches.

Everything around the browser, handled

Managed proxies, captcha solving, network interception, cookie & storage persistence, live WebRTC control — one SDK, no extra services to stitch together.

The everyday toolkit

The small commands you reach for every day, all through the same SDK.

Scroll & hoverDrag & dropSelect dropdownsCookies & storageScreenshotsRequest mockingHeader editsElement waitsKeyboard inputSession restoreDOM evaluation+ many more

FAQ

Questions, answered.

What browserscale is, how it stays undetectable, how coding agents build on it, and how it handles the parts of browser automation that usually break.

What is browserscale?

browserscale is a browser-as-a-service platform that runs real Chromium browsers in the cloud. You rent an isolated session and drive it from Go or TypeScript instead of installing, scaling and babysitting your own headless browser farm.

What is browserscale used for?

browserscale is used for large-scale web scraping and data collection, automated testing, and driving AI browser agents — anywhere you need real Chromium sessions that stay undetectable and scale to hundreds or thousands of parallel tasks, driven from Go (browserscale-go) or TypeScript (browserscale-ts).

How is browserscale different from Playwright or Puppeteer?

Playwright and Puppeteer drive the browser from outside over the DevTools protocol (CDP). browserscale runs natively inside Chromium itself: commands execute in the renderer process, nothing is injected into the page, there is no Runtime.enable and no DevTools handshake. That removes the automation traces sites look for and makes execution faster — and you get undetectable fingerprints, human-like input, captcha solving, proxies and live remote control on top.

Is browserscale a real browser or a headless one?

It's a real, full Chromium engine running in the cloud — real pages, frames, cookies, storage and a complete network stack — not a headless DOM emulator or an HTTP client with a JavaScript shim. Sites get a genuine browser environment, which is part of why automation stays undetectable.

Can I migrate my Playwright or Puppeteer scripts to browserscale?

browserscale isn't a drop-in replacement — you drive it through its own Go (browserscale-go) or TypeScript (browserscale-ts) SDK rather than the Playwright or Puppeteer API. But the concepts map closely: the same click, fill, wait, evaluate and network primitives are there, so porting a script is mostly mechanical. In return you drop the CDP-based stack that sites can detect and gain engine-level control, a flat frame tree and managed proxies.

Will websites detect that I'm automating the browser?

That's the core thing browserscale is built to avoid. Because control happens inside the engine with no injected JavaScript and no CDP control-plane signals, page scripts can't observe the automation. Combined with real, replayable fingerprints (canvas, WebGL, audio, codecs, WebRTC) and human-like mouse movement, sessions look like a genuine user's browser rather than a headless bot.

Does browserscale fake WebGL and canvas fingerprints?

No — and that's the point. browserscale sessions run hardware-accelerated on real consumer GPUs that browserscale owns and operates, so canvas and WebGL readbacks like toDataURL or getImageData return genuinely rendered pixels. There is no spoofing layer and no fingerprint hash database that a new bot-protection probe could unmask, which also makes sessions future-proof as passive checks get deeper.

Will my clicks and typing look human?

Yes. Mouse movement uses browserscale's own motion algorithm with realistic paths instead of teleporting the cursor straight to the target, and input is delivered as genuine browser-level events rather than synthetic DOM dispatches. Together with real fingerprints and engine-level control, interactions read like a person rather than a script.

Which languages have an SDK?

browserscale ships official SDKs for Go (browserscale-go) and TypeScript (browserscale-ts). Both drive the exact same browser API, so you can use the same session concepts and commands from backend workers, scripts or services.

Do I need to install Chromium or run my own browser farm?

No. There is no chromium binary on your machine and no infrastructure to manage. You rent a real browser session over the API and drive it remotely; browserscale handles the browsers, proxies, scaling and lifecycle server-side.

How do I stay logged in across separate runs?

Capture state with GetCookies and GetStorage, then replay it on the next rental with SetCookies and SetStorage to carry the cookie jar and localStorage across sessions. Pair it with a pinned fingerprint so the site sees a returning visitor instead of a brand-new install, and you skip logging in every run.

Can I reuse the same browser identity over time?

Yes. Fingerprints are server-side IDs you can pin and reuse. WithFingerprint(id) restores the whole browser identity — user agent, canvas, WebGL, audio, locale and more — not just cookies, so repeat runs look like the same machine coming back.

My waits are flaky and clicks miss elements that are still moving — does browserscale help?

Yes. browserscale waits are armed once inside the engine and resolve event-driven the instant the condition is met — no polling loop that can race the page. Built-in steady-time checks only report an element back once it exists and holds its position in the DOM, so animations and layout shifts are absorbed before your click. The checks are configurable if you need to match hidden or off-screen elements too.

How do I work with iframes and cross-origin frames (OOPIFs)?

browserscale collapses the main document, same-origin iframes and cross-origin OOPIFs into one flat frame tree — every frame is just a frameId. No flattened CDP sessions, no waiting on Runtime.enable for a per-frame execution context. Wait and Click can act across all frames at once or scope to a single iframe, and Wait hands back the frameId that matched so you can act on it directly.

Can browserscale solve captchas?

Yes. Passive anti-bot checks tend to pass on their own thanks to real fingerprints, real hardware and clean, CDP-free control. For interactive challenges, a single SolveCaptcha call detects, solves and wires the token back into the page within the same run. Solving is done by browserscale's own AI solver, which learns the known challenge types — puzzle, OCR, slide, hold and more — on its own and keeps improving as they evolve. browserscale never synthesizes a token: the challenge is completed in the valid live browser and the provider's own JavaScript issues the token itself. That's also why it's future-proof — protections browserscale has never seen before pass too, because there's no emulated environment or synthesized response for a new check to expose.

Can I inspect, modify, mock or block network traffic?

Yes — and unlike CDP-based route handlers that race navigations and late-attaching frames, browserscale interception sits in the browser's network stack itself. Every request from every frame, including cross-origin OOPIFs, passes through it; nothing slips by. From the SDK you can wait for specific requests or responses as part of the flow, modify headers, mock responses, or block matching requests by pattern — without leaving your script.

How do I cut proxy bandwidth and cost on repeat runs?

Mark repeated JS, CSS and image paths as static once with SetStaticPaths. browserscale then serves them from a server-side cache, so repeat runs skip re-downloading the heavy static assets through your proxy — only the bytes that actually change go over the network.

Do I have to bring my own proxies?

Either way works. Pass your own host, port and credentials, or leave them empty and browserscale allocates a managed proxy server-side. You can also switch the proxy mid-session with SetProxy without relaunching the browser.

Can I run many browsers in parallel, and how fast do they start?

Yes — that's what browserscale is built for. Each session is an isolated browser context rather than a fresh VM or OS process, so there's no machine to boot: a browser spins up in under 250 ms. Every context has its own cookies, storage, cache and fingerprint, so large queues never share or collide on state. You can fan out from one job to thousands of concurrent sessions without managing browsers yourself.

Can another worker pick up a running session?

Yes. The browser lives server-side, so ConnectSession lets any other worker, process or machine attach to a running session by its sessionId and gRPC URL. The browser survives a worker restart or redeploy instead of dying with the process that launched it.

Can I use browserscale with AI browser agents?

Yes. GetObservation returns a compact, token-budgeted view of the visible, interactive elements — as text or JSON — across every frame, each tagged with a node handle you can hand straight to an action. Your model reasons over what matters instead of a megabyte of raw HTML.

Can an AI coding agent build my browserscale automation for me?

That's what browserscale-cli is for. Running browserscale-cli init scaffolds a Go module that already compiles and runs — the worker harness, a config schema, the lifecycle loop, a proxy pool and rent-with-backoff — plus a worked browser flow to pattern-match against. Open the folder in Cursor, Claude, Codex or any other coding agent and describe the job: it fills in the flow against real API signatures, because every scaffold ships an AGENTS.md and the full SDK reference offline. browserscale-cli dev rebuilds, restarts and streams the logs from one command, so the agent can run its own work and fix what broke.

Does browserscale have an MCP server?

Yes, a hosted one at https://mcp.browserscale.cloud/mcp. It exposes the browser as tools that map one-to-one onto the SDK — rent, navigate, observe, wait, click, fill, type, evaluate, screenshot, solve_captcha and the cookie and storage tools. Add the URL to any MCP client with an 'Authorization: Bearer <api-key>' header; the key stays in the client config and never becomes a tool argument. The server is stateless: rent returns a sessionId that later calls carry, so an agent can also attach to a session a failed run left behind and inspect the real page.

Do I need to know Go to use browserscale?

No. If you drive the browser yourself, the TypeScript SDK needs nothing but Node. If you want a coding agent to build the automation, the scaffold is Go and you need the Go toolchain installed — but the idea is that you describe the job and review the result rather than writing SDK calls by hand.

Why have an agent write code instead of just clicking through the browser for me?

For exploring an unfamiliar page, clicking through with the MCP tools is exactly right. For work you repeat, it isn't: every step costs tokens on every run, you get one session per conversation, and when the chat ends nothing is left. Having the agent write a program moves the logic into code once. After that it runs with as many parallel workers as you configure, with no model in the loop, and you keep something you can review, diff and re-run.

Can I watch a session live and take control?

Every cloud browser streams to your screen over WebRTC as a low-latency H.264 video. You can watch automation run in real time to debug failed selectors, redirects or surprise popups, and take over with mouse and keyboard over data channels to finish any step by hand.

How much does browserscale cost?

Pricing is pay-as-you-go and credit-based: you top up, earn bonus credits at higher tiers, and scale without per-seat fees or a monthly minimum. See the pricing page for the current tiers.

How do I get started?

Install the Go or TypeScript SDK, grab an API key from your dashboard, rent a browser and drive it — your first script runs in under five minutes. The Quickstart walks through the whole flow. If you'd rather have a coding agent build the automation, install browserscale-cli instead and run browserscale-cli init to get a project that runs before you write a line.