The browserless browser

Permissionless connectors to any application for your agents.

Unbrowse is an authenticated action surface. Agents ask for an outcome. We hit the site's own first-party APIs when they exist, keep a cloud browser when they don't, and compile the route into a versioned YAML harness your next call can reuse.

live routehn.top_stories@1
  1. 01

    Search

    Private Jev space · then public registry

  2. 02

    Resolve

    hn.top_stories · first_party_http

  3. 03

    Execute

    GET hn.algolia.com/api/v1/search

{
  "stories": [
    { "title": "Show HN: Unbrowse", "points": 412 },
    { "title": "Internal APIs Are All You Need", "points": 287 }
  ],
  "verified": true,
  "windows": 0
}
3.6×
mean speedup vs Playwright
5.4×
median, 94-domain paper
$10
per 10k calls
0
browser windows on a warm route

Ask it anything below.

First request is fulfilled. Routes are indexed in the background. Drop Unbrowse in as a native agent browser.

Remote MCP · discover → skill tool → execute

POST /api/mcp
tools/list { query: "flights from singapore to tokyo on skyscanner" }
→ unbrowse.skill.skyscanner_flights
tools/call that skill with the same task

The wedge

Agents should not browse websites. They should call the APIs already behind them.

Humans

A page

Buttons, type, layout. Beautiful for people. Slow to operate by hand, and not a contract.

Agents today

A DOM

Launch Chromium, wait, click, dump eight thousand tokens of HTML, hope the layout did not ship overnight.

Unbrowse

A route

The first-party JSON the page was already calling. Typed. Cached. Permission-aware. Verified.

5–30s → 50–200ms
warmed first-party call
~8,000 → ~200
tokens, DOM vs JSON
3.6× / 5.4×
mean / median vs Playwright
0 windows
on a compiled harness

Runtime

Search. Resolve. Execute. Index in the background.

01

Ask for an outcome

Natural language or a capability id. The first request is fulfilled — we do not make you wait for an index.

02

Private Jev, then the registry

Connected public and passworded sites sit as flat primitives. The public registry is second priority, connect-on-the-fly.

03

First-party, then browser

Validated network implementations win when permission, compatibility and effect safety hold. Otherwise a cloud browser learns the route.

04

Compile a YAML skill

A successful run becomes an observed harness. After validation it is a reusable Agent Skill — descriptions Jev can search.

Agent-skill native

SDK first. MCP around it. Skills on top.

Harnesses are versioned YAML. Descriptions are first-class, so Jev can search private and public primitives the same way an agent searches skills.

01

SDK

Typed TypeScript client for runs, requirements, artifacts and capability search. The source of truth. Wrap it from anything.

const ub = new Unbrowse({ apiKey })
const run = await ub.run({
  task: "top stories on Hacker News"
})

02

Remote MCP

A hosted harness over that SDK. Tools: run, inspect, resume, cancel, discover. When only a few skills match, those YAML contracts surface as native tools.

{
  "mcpServers": {
    "unbrowse": {
      "url": "/api/mcp"
    }
  }
}

03

Agent Skill

A thin public SKILL.md. Point any agent at Unbrowse with zero human-in-a-browser setup. Wire any API natively, on the fly.

npx skills add unbrowse

# YAML harnesses are skills.
# Jev searches their descriptions.

Jev search space

Private first. Public registry second.

Every connected origin — public websites and passworded ones — is a flat primitive with a comprehensive description. Jev ranks those before the shared registry of things you could connect on the fly. Auth stays in the broker. Agents receive opaque references, never cookies.

priority 0 · private primitives

records.example — passworded supplier exports (first-party)

github.com — session-bound private repos

priority 1 · public registry

news.ycombinator.com — front page Algolia feed

linear.app — connect to enable

notion.so — connect to enable

stripe.com — restricted keys never leave the broker

arXiv:2604.00694

Internal APIs are all you need.

The flagship paper: why the first-party routes already powering modern websites are the machine-native interface for autonomous agents, and how a shared route graph turns repeated browser rediscovery into collective memory. 94 live domains. 3.6× mean / 5.4× median speedup on warmed routes.

  • 94

    production domains in the benchmark

  • 90–96%

    cost reduction on warmed-cache execution

  • 3 paths

    local cache, shared graph, browser fallback

Read the paper

Drop-in

One skill. A native agent browser.

Install the thin public skill, or point any MCP host at the remote harness. Claude, Cursor, OpenClaw, Windsurf, or anything that can call HTTPS.

npx skills add unbrowse

# The skill wraps the SDK.
# You never drive a browser.
{
  "mcpServers": {
    "unbrowse": {
      "url": "https://v3.unbrowse.ai/mcp",
      "headers": {
        "Authorization": "Bearer ub_live_…"
      }
    }
  }
}
Open the installer

Metered

$10 per 10,000 calls.

A call is a verified run dispatch — network or browser — not a token of HTML. Failed policy checks are free.

See pricing

Limits, stated

Explicit, not magic.

Is this a headless browser?
No. Unbrowse is the browserless browser: an authenticated action surface. We prefer the site's own first-party APIs. A cloud browser is retained only for discovery and for sessions that still require a page.
Do you wrap official integrations only?
Official integrations are used when configured. Their absence does not block a task. First use can browse, verify the outcome, and compile a candidate harness.
Where do passwords live?
In the identity broker, never in tool arguments or YAML. Agents receive opaque account references. Workers get a scoped lease for a permitted destination.
When is a task succeeded?
Only when the declared business outcome is independently verified. HTTP 200, a YAML file, or a model confidence score is not enough.

Drop it in as the agent's browser. The first ask is already a route.