ID@agntn/browsersv0.4.0
One scrape call. Eight browsers behind it.
Steel scrapes in one HTTP call. Kernel wants a live session first. Browserbase hands you a CDP URL. A model will mix those up, so this is one scrape() over all of them, in TypeScript, in the terminal and in your agent, and each backend says flag by flag what it can do.
- Providers
- 8
- 13 flags each
- Agent tools
- 12
- the same on MCP, Pi and OMP
- Keys to start
- 0
- Playwright runs here
$ pnpm add @agntn/browsersSteel
One POST to /v1/scrape for a page, a session for everything else.
Route
- createdone
- sessionskipped
- scrapedone
- releaseskipped
Answer
- <html lang="en"><head><meta charset="utf-8"><link rel="icon" href="data:,"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Example Domain</title><style>html{color-scheme:light dark;background:light-dark(#eee,#222)}body{font:16px/1.6 system-ui,sans-serif;max-width:30em;min-height:100vh;margin:auto;padding:4.75em 2em 20vh;box-sizing:border-box;display:grid;place-content:center;text-align:center}</style></head><body><style>body{padding:2em 2em 20vh;place-items:center}svg{opacity:.55}p{grid-area:2/1}span{transition:opacity .4s}p+p span{opacity:0}@media(prefers-reduced-motion){*{transition:none}}</style><svg viewBox="0,0,20,20" width="44" height="44" fill="currentColor" aria-hidden="true"><path fill="none" stroke="currentColor" stroke-width="1.3" stroke-linejoin="round" d="M6 4H3v12q4 0 7 1.5-1-3.5-4-4.5V2q3.5 1 4 3v12.5q3-1.5 7-1.5V4q-4.5 0-7 1"></path><g transform="rotate(-6,13.6,8.3)"><path id="q" d="M11.5 6.6h1.8v1.8l-1 1.6-.6-.3.8-1.3h-1z"></path><use href="#q" x="2.4"></use></g></svg><p><span>T</span><span>h</span><span>i</span><span>s</span><span> </span><span>d</span><span>o</span><span>m</span><span>a</span><span>i</span><span>n</span><span> </span><span>i</span><span>s</span><span> </span><span>f</span><span>o</span><span>r</span><span> </span><span>u</span><span>s</span><span>e</span><span> </span><span>i</span><span>n</span><span> </span><span>d</span><span>o</span><span>c</span><span>u</span><span>m</span><span>e</span><span>n</span><span>t</span><span>a</span><span>t</span><span>i</span><span>o</span><span>n</span><span> </span><span>e</span><span>x</span><span>a</span><span>m</span><span>p</span><span>l</span><span>e</span><span>s</span><span> </span><span>w</span><span>i</span><span>t</span><span>h</span><span>o</span><span>u</span><span>t</span><span> </span><span>n</span><span>e</span><span>e</span><span>d</span><span>i</span><span>n</span><span>g</span><span> </span><span>p</span><span>e</span><span>r</span><span>m</span><span>i</span><span>s</span><span>s</span><span>i</span><span>o</span><span>n</span><span>.</span><span> </span><span>T</span><span>h</span><span>i</span><span>s</span><span> </span><span>i</span><span>s</span><span> </span><span>n</span><span>o</span><span>t</span><span> </span><span>a</span><span> </span><span>s</span><span>e</span><span>r</span><span>v</span><span>i</span><span>c</span><span>e</span><span>,</span><span> </span><span>a</span><span>v</span><span>o</span><span>i</span><span>d</span><span> </span><span>r</span><span>e</span><span>l</span><span>y</span><span>i</span><span>n</span><span>g</span><span> </span><span>o</span><span>n</span><span> </span><span>i</span><span>t</span><span> </span><span>f</span><span>o</span><span>r</span><span> </span><span>t</span><span>e</span><span>s</span><span>t</span><span>i</span><span>n</span><span>g</span><span> </span><span>a</span><span>n</span><span>d</span><span> </span><span>m</span><span>o</span><span>n</span><span>i</span><span>t</span><span>o</span><span>r</span><span>i</span><span>n</span><span>g</span><span> </span><span>p</span><span>u</span><span>r</span><span>p</span><span>o</span><span>s</span><span>e</span><span>s</span><span>.</span></p><p lang="ar" dir="rtl"><span>هذا</span><span> النطاق</span><span> مُخصص</span><span> للاستخدام</span><span> في</span><span> أمثلة</span><span> التوثيق</span><span> دون</span><span> الحاجة</span><span> إلى</span><span> إذن.</span><span> هذه</span><span> ليست</span><span> خدمة،</span><span> يُرجى</span><span> تجنب</span><span> الاعتماد</span><span> عليها</span><span> لأغراض</span><span> الاختبار</span><span> والمراقبة.</span></p><p lang="zh"><span>该</span><span>域</span><span>名</span><span>仅</span><span>用</span><span>于</span><span>文</span><span>档</span><span>示</span><span>例</span><span>,</span><span>无</span><span>需</span><span>获</span><span>得</span><span>许</span><span>可</span><span>。</span><span>这</span><span>并</span><span>非</span><span>一</span><span>项</span><span>服</span><span>务</span><span>,</span><span>请</span><span>勿</span><span>将</span><span>其</span><span>用</span><span>于</span><span>测</span><span>试</span><span>和</span><span>监</span><span>控</span><span>目</span><span>的</span><span>。</span></p><p lang="fr"><span>L</span><span>’</span><span>u</span><span>s</span><span>a</span><span>g</span><span>e</span><span> </span><span>d</span><span>e</span><span> </span><span>c</span><span>e</span><span> </span><span>d</span><span>o</span><span>m</span><span>a</span><span>i</span><span>n</span><span>e</span><span> </span><span>e</span><span>s</span><span>t</span><span> </span><span>r</span><span>é</span><span>s</span><span>e</span><span>r</span><span>v</span><span>é</span><span> </span><span>à</span><span> </span><span>d</span><span>e</span><span>s</span><span> </span><span>e</span><span>x</span><span>e</span><span>m</span><span>p</span><span>l</span><span>e</span><span>s</span><span> </span><span>d</span><span>e</span><span> </span><span>d</span><span>o</span><span>c</span><span>u</span><span>m</span><span>e</span><span>n</span><span>t</span><span>a</span><span>t</span><span>i</span><span>o</span><span>n</span><span>,</span><span> </span><span>s</span><span>a</span><span>n</span><span>s</span><span> </span><span>a</span><span>u</span><span>t</span><span>o</span><span>r</span><span>i</span><span>s</span><span>a</span><span>t</span><span>i</span><span>o</span><span>n</span><span> </span><span>p</span><span>r</span><span>é</span><span>a</span><span>l</span><span>a</span><span>b</span><span>l</span><span>e</span><span>.</span><span> </span><span> </span><span>I</span><span>l</span><span> </span><span>n</span><span>e</span><span> </span><span>s</span><span>’</span><span>a</span><span>g</span><span>i</span><span>t</span><span> </span><span>p</span><span>a</span><span>s</span><span> </span><span>d</span><span>’</span><span>u</span><span>n</span><span> </span><span>s</span><span>e</span><span>r</span><span>v</span><span>i</span><span>c</span><span>e</span><span> </span><span>;</span><span> </span><span>s</span><span>o</span><span>n</span><span> </span><span>u</span><span>t</span><span>i</span><span>l</span><span>i</span><span>s</span><span>a</span><span>t</span><span>i</span><span>o</span><span>n</span><span> </span><span>à</span><span> </span><span>d</span><span>e</span><span>s</span><span> </span><span>f</span><span>i</span><span>n</span><span>s</span><span> </span><span>d</span><span>e</span><span> </span><span>t</span><span>e</span><span>s</span><span>t</span><span> </span><span>o</span><span>u</span><span> </span><span>d</span><span>e</span><span> </span><span>s</span><span>u</span><span>r</span><span>v</span><span>e</span><span>i</span><span>l</span><span>l</span><span>a</span><span>n</span><span>c</span><span>e</span><span> </span><span>e</span><span>s</span><span>t</span><span> </span><span>à</span><span> </span><span>é</span><span>v</span><span>i</span><span>t</span><span>e</span><span>r</span><span>.</span></p><p lang="ru"><span>Д</span><span>а</span><span>н</span><span>н</span><span>ы</span><span>й</span><span> </span><span>д</span><span>о</span><span>м</span><span>е</span><span>н</span><span> </span><span>п</span><span>р</span><span>е</span><span>д</span><span>н</span><span>а</span><span>з</span><span>н</span><span>а</span><span>ч</span><span>е</span><span>н</span><span> </span><span>д</span><span>л</span><span>я</span><span> </span><span>и</span><span>с</span><span>п</span><span>о</span><span>л</span><span>ь</span><span>з</span><span>о</span><span>в</span><span>а</span><span>н</span><span>и</span><span>я</span><span> </span><span>в</span><span> </span><span>п</span><span>р</span><span>и</span><span>м</span><span>е</span><span>р</span><span>а</span><span>х</span><span> </span><span>д</span><span>о</span><span>к</span><span>у</span><span>м</span><span>е</span><span>н</span><span>т</span><span>а</span><span>ц</span><span>и</span><span>и</span><span> </span><span>б</span><span>е</span><span>з</span><span> </span><span>н</span><span>е</span><span>о</span><span>б</span><span>х</span><span>о</span><span>д</span><span>и</span><span>м</span><span>о</span><span>с</span><span>т</span><span>и</span><span> </span><span>п</span><span>о</span><span>л</span><span>у</span><span>ч</span><span>е</span><span>н</span><span>и</span><span>я</span><span> </span><span>п</span><span>р</span><span>е</span><span>д</span><span>в</span><span>а</span><span>р</span><span>и</span><span>т</span><span>е</span><span>л</span><span>ь</span><span>н</span><span>о</span><span>г</span><span>о</span><span> </span><span>р</span><span>а</span><span>з</span><span>р</span><span>е</span><span>ш</span><span>е</span><span>н</span><span>и</span><span>я</span><span>.</span><span> </span><span>Э</span><span>т</span><span>о</span><span> </span><span>н</span><span>е</span><span> </span><span>с</span><span>е</span><span>р</span><span>в</span><span>и</span><span>с</span><span>;</span><span> </span><span>н</span><span>е</span><span> </span><span>р</span><span>е</span><span>к</span><span>о</span><span>м</span><span>е</span><span>н</span><span>д</span><span>у</span><span>е</span><span>т</span><span>с</span><span>я</span><span> </span><span>е</span><span>г</span><span>о</span><span> </span><span>и</span><span>с</span><span>п</span><span>о</span><span>л</span><span>ь</span><span>з</span><span>о</span><span>в</span><span>а</span><span>н</span><span>и</span><span>е</span><span> </span><span>д</span><span>л</span><span>я</span><span> </span><span>т</span><span>е</span><span>с</span><span>т</span><span>и</span><span>р</span><span>о</span><span>в</span><span>а</span><span>н</span><span>и</span><span>я</span><span> </span><span>и</span><span> </span><span>м</span><span>о</span><span>н</span><span>и</span><span>т</span><span>о</span><span>р</span><span>и</span><span>н</span><span>г</span><span>а</span><span>.</span></p><p lang="es"><span>E</span><span>s</span><span>t</span><span>e</span><span> </span><span>d</span><span>o</span><span>m</span><span>i</span><span>n</span><span>i</span><span>o</span><span> </span><span>e</span><span>s</span><span>t</span><span>á</span><span> </span><span>d</span><span>e</span><span>s</span><span>t</span><span>i</span><span>n</span><span>a</span><span>d</span><span>o</span><span> </span><span>a</span><span>l</span><span> </span><span>u</span><span>s</span><span>o</span><span> </span><span>e</span><span>n</span><span> </span><span>e</span><span>j</span><span>e</span><span>m</span><span>p</span><span>l</span><span>o</span><span>s</span><span> </span><span>d</span><span>e</span><span> </span><span>d</span><span>o</span><span>c</span><span>u</span><span>m</span><span>e</span><span>n</span><span>t</span><span>a</span><span>c</span><span>i</span><span>ó</span><span>n</span><span> </span><span>s</span><span>i</span><span>n</span><span> </span><span>n</span><span>e</span><span>c</span><span>e</span><span>s</span><span>i</span><span>d</span><span>a</span><span>d</span><span> </span><span>d</span><span>e</span><span> </span><span>p</span><span>e</span><span>r</span><span>m</span><span>i</span><span>s</span><span>o</span><span>.</span><span> </span><span>E</span><span>s</span><span>t</span><span>o</span><span> </span><span>n</span><span>o</span><span> </span><span>e</span><span>s</span><span> </span><span>u</span><span>n</span><span> </span><span>s</span><span>e</span><span>r</span><span>v</span><span>i</span><span>c</span><span>i</span><span>o</span><span>,</span><span> </span><span>e</span><span>v</span><span>i</span><span>t</span><span>a</span><span>r</span><span> </span><span>u</span><span>t</span><span>i</span><span>l</span><span>i</span><span>z</span><span>a</span><span>r</span><span>l</span><span>o</span><span> </span><span>p</span><span>a</span><span>r</span><span>a</span><span> </span><span>r</span><span>e</span><span>a</span><span>l</span><span>i</span><span>z</span><span>a</span><span>r</span><span> </span><span>p</span><span>r</span><span>u</span><span>e</span><span>b</span><span>a</span><span>s</span><span> </span><span>o</span><span> </span><span>m</span><span>o</span><span>n</span><span>i</span><span>t</span><span>o</span><span>r</span><span>e</span><span>o</span><span>s</span><span>.</span></p><a href="https://iana.org/help/example-domains">Learn more</a><script src="/s.js"></script>
- </body></html>
- Came back
- raw HTML
- Size
- 12,348 characters
- Time
- 1,915 ms
- Session
- none, one call
capabilities() is the list
Six of the eight scrape in one call. Kernel only scrapes inside a session, which the tools and the CLI open and release for you. Anchor doesn't scrape at all, and says so instead of handing back an empty page. Everything past that is a flag per operation, read off a live instance, so a README can't drift from it. This grid is those flags.
Import(await create("cloudflare")).capabilities()
| Provider | scrape | screenshot | element | crawl | links | a11y tree | extract | search | sessions | cdp | navigate | evaluate | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| steel | one call | inside a session | not supported | not supported | not supported | not supported | not supported | not supported | not supported | one call | one call | not supported | not supported |
| browserbase | one call | not supported | not supported | not supported | not supported | not supported | not supported | not supported | not supported | one call | one call | not supported | not supported |
| kernel | inside a session | inside a session | not supported | not supported | not supported | not supported | not supported | not supported | not supported | one call | one call | inside a session | inside a session |
| browserless | one call | one call | one call | one call | not supported | not supported | not supported | not supported | not supported | one call | one call | inside a session | inside a session |
| hyperbrowser | one call | one call | not supported | not supported | one call | not supported | not supported | one call | one call | one call | one call | not supported | not supported |
| anchor | not supported | inside a session | not supported | not supported | not supported | not supported | not supported | not supported | not supported | one call | one call | not supported | not supported |
| cloudflare | one call | one call | one call | one call | one call | one call | one call | one call | not supported | one call | one call | not supported | not supported |
| playwright | one call | inside a session | inside a session | one call | one call | one call | not supported | not supported | not supported | one call | not supported | inside a session | inside a session |
Twelve tools, one executor
browsers mcp, the Pi extension and the OMP extension call the same executors, so a fix lands once and a model reads the same text on every host. The console asks browsers_capabilities about the provider in the panel above. The dialog holds exactly what a model would get.
- A scrape stops at 20,000 characters unless you pass maxChars, and says how much it cut
- Links come 500 at a time, with the offset to ask for next
- A slow crawl hands back its job ID instead of a timeout
Steel
The flags come off a live instance, not a table in a README. What the model reads is what the next call will run into.
- supports
- 4 of 13 operations
- scrape
- one call
- needs
- STEEL_API_KEY
Bring your own backend
The built-ins are eight classes behind one interface, and yours is the same shape in one file. This one puts Jina Reader behind scrape(): one GET, markdown back, and an honest no for everything it can't do.
- A class that implements BrowserProvider and a factory that builds it
- notSupportedViaRest turns every missing operation into a typed refusal
- register(name, defaultURL, factory) and create(name) finds it
import { create, notSupportedViaRest, register } from "@agntn/browsers";class Reader implements BrowserProvider { /* baseURL, name() and capabilities(): scrape only */ async scrape(url) { /* GET r.jina.ai/<url>, markdown back */ } /* createSession … evaluate: notSupportedViaRest("reader", …) */}register("reader", "https://r.jina.ai", (config) => new Reader(config));const page = await (await create("reader")).scrape("https://example.com");Start with the one that needs no key
One install gives you the library, the browsers CLI and the MCP server. Playwright runs on your machine, so the first scrape costs nothing. Later, set a vendor key and swap the name for resolveProvider(), and the call goes to the cloud.
- PinPre-1.0, so pin exact versions.
- ChromiumPlaywright takes the Chrome already on your PATH, or the one playwright-core installs.
- BillsEvery vendor but Playwright meters its own account. The key is yours.
First call
$ pnpm add @agntn/browsersimport { create } from "@agntn/browsers";const provider = await create("playwright");provider.capabilities().statelessScrape; // trueconst page = await provider.scrape("https://example.com");page.text; // "This domain is for use in documenta…"