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
Install$ pnpm add @agntn/browsers
Callbrowsers_scrape("https://example.com", "steel")recorded 2026-09-29 · 01 / 8
Provider / steel

Steel

One POST to /v1/scrape for a page, a session for everything else.

Route

  1. createdone
  2. sessionskipped
  3. scrapedone
  4. releaseskipped

Answer

  1. <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>
  2. </body></html>
Came back
raw HTML
Size
12,348 characters
Time
1,915 ms
Session
none, one call
operations 4 / 13

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()

Callprovider.capabilities()8 providers · 13 operations
Operations per provider: one call, inside a session, or not supported
Providerscrapescreenshotelementpdfcrawllinksa11y treeextractsearchsessionscdpnavigateevaluate
steelone callinside a sessionnot supportednot supportednot supportednot supportednot supportednot supportednot supportedone callone callnot supportednot supported
browserbaseone callnot supportednot supportednot supportednot supportednot supportednot supportednot supportednot supportedone callone callnot supportednot supported
kernelinside a sessioninside a sessionnot supportednot supportednot supportednot supportednot supportednot supportednot supportedone callone callinside a sessioninside a session
browserlessone callone callone callone callnot supportednot supportednot supportednot supportednot supportedone callone callinside a sessioninside a session
hyperbrowserone callone callnot supportednot supportedone callnot supportednot supportedone callone callone callone callnot supportednot supported
anchornot supportedinside a sessionnot supportednot supportednot supportednot supportednot supportednot supportednot supportedone callone callnot supportednot supported
cloudflareone callone callone callone callone callone callone callone callnot supportedone callone callnot supportednot supported
playwrightone callinside a sessioninside a sessionone callone callone callnot supportednot supportednot supportedone callnot supportedinside a sessioninside 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
Read MCP, Pi and OMP
Callbrowsers_capabilities("steel")8 providers
Provider / steel

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
MCP · Pi · OMPbrowsers mcp · stdio

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
Read Custom providers
Filereader.tsfolded · copy is whole
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");
Startpnpm add @agntn/browsersNode.js 26 or newer

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…"