Skip to main content

Frankensurf

One read() call for AI agents, stitched from 28 web tools.

Every web tool breaks somewhere. Frankensurf sits in front of all of them and gives your agent one call. It tries the cheapest tool first, checks the page is real, climbs to a stronger tool only when a site pushes back, and returns clean page data with a receipt of how it got there.

  • Cheapest first. Plain HTTP, Jina Reader, a local browser, free stealth browsers, hosted browsers, then paid unblockers only if you allow them.

  • Every page checked. A challenge page, a login wall, or a search page whose results never loaded counts as a failure, not a success.

  • Shows its work. Every result says which tools ran, how long each took and what it cost.

Website and docs: https://frankensurf.dev · Why I built it

Try it

Python 3.12 or newer, on Linux, macOS, or Windows through WSL (each release is installed from PyPI on fresh Ubuntu 24.04 and macOS machines and checked):

pip install "frankensurf[mcp]"
frankensurf setup        # Chromium + the free stealth browsers, a few minutes
frankensurf read "https://www.walmart.com/search?q=air+fryer" --explain

No account or key needed. The read climbs until it gets the real page:

https://www.walmart.com/search?q=air+fryer
  ✗ http                   CAPTCHA                0.4s
  ✗ local                  CAPTCHA                1.5s
  ✓ camoufox               got the page           15.6s

air fryer - Walmart.com
24,192 characters via camoufox, complete (107 results), free

Drop --explain for the full JSON: text or markdown, JSON-LD, the page’s embedded and fetched JSON, images, and the receipt.

Free or paid

Everything works with no keys. Paid tools are opt-in, and only come in once a site has walled a free tool, cheapest likely success first. From the newest benchmark below (150 sites picked before any was read, v0.33):

Setup

Sites read

Median

Cost per 1k

Free tools only (frankensurf setup)

84.7%

3.3 s

$0

Plus paid fallbacks (Firecrawl, Zyte, …)

95.3%

3.0 s

$1.06

To allow paid tools, set their keys (for example FIRECRAWL_API_KEY) and pass --paid (--max-cost USD caps a read; from Python, allow_paid_fallbacks and max_cost_usd). See Paid tools and budgets.

Use it

From an agent, as an MCP server (setup for each client):

claude mcp add frankensurf -- frankensurf-mcp

From Python:

from frankensurf import Runtime

async with Runtime("state") as web:
    page = await web.read("https://example.com", policy_overrides={"prefer_markdown": True})
    hits = await web.search("playwright python tutorial")

From the command line:

frankensurf read https://example.com --markdown
frankensurf search playwright python tutorial
frankensurf watch https://news.ycombinator.com/ --link-pattern 'item\?id=\d+'

What you get back is raw page data, not answers. Your agent decides what the page means, and if it isn’t what it wanted, it can ask again with retry_of=<trace_id> to skip every tool already tried.

Also in the box: profiles (log in once, reuse the session from any tool), human handoff for CAPTCHAs and 2FA, site modules (save what your agent learns about a site as data), and Web Bot Auth request signing.

Want the article, not the menus? Pass --main (MCP main_content=True) for main_text (best with pip install "frankensurf[main]").

Search takes --site, --exclude-domain, --recency and --region on every source, a --vertical (news, reference, discussions, qa, code, papers, books) backed by official free APIs, and --mode merge to fuse every source at once. Running on a server that reads URLs it didn’t choose? Set FRANKENSURF_BLOCK_PRIVATE_NETWORK=1.

Every page read carries receipt.quality: good, partial or poor, with flags such as paywall, menus or placeholder, so an agent (or a paid fallback) knows when a page didn’t really come through.

Slow page? A read with no page after 3 seconds starts two more free tools beside it and keeps the first complete page (--lightning races from the start). A URL that answers not found is looked up with the site’s own search, and receipt.rescued says so. Still walled? Allow a real Chrome on your machine (--real-browser, with its own profile, never yours) or a second connection (FRANKENSURF_EGRESS; frankensurf egress check shows where each comes out).

Keeping up with many sites? frankensurf watch-sites URL… --since DATE lists their new pages from the feeds and sitemaps they publish, polled with conditional requests. Running on a server? Run Steel beside it (docker compose up -d) and, if sites still refuse your data-centre address, set FRANKENSURF_PROXY to a proxy you bring.

Agents learn the tools from a bundled skill: the MCP server sends it as its instructions, and frankensurf skill install adds it to ~/.claude/skills.

Reading many pages from one site? Let Frankensurf learn it first:

frankensurf module discover https://www.example.com/ --query "desk lamp" --save

That finds the site’s search (its schema.org SearchAction, its search form, or by typing once into its search box), reads the results, and saves a site module: where the items live in the page’s own data, plus a search template. From then on every search on that site comes back as structured items, and batch_template runs many searches as one polite batch. Check the sample rows before saving; the draft can pick the wrong list.

How it works

Every way to fetch a page is a rung: plain HTTP and markdown negotiation, browsers, stealth browsers and signed requests, hosted browsers, paid unblockers, and finally a person clearing the wall in a visible browser. A read starts at the cheapest rung and climbs only when a page pushes back. Every tool is a plugin, so new ones slot in as another rung. See How escalation works and the full list of integrations.

Benchmark

scripts/toolbench.py runs each tool on its own, then Frankensurf, on the same pages with the same content checks. The newest: 150 sites in 15 categories picked before any was read (held-out set 6), read on 10 October 2026 with v0.33, raw rows in benchmarks/2026-10-10/:

Tool

Sites read

Median

Cost per 1k

Headless Chromium only

45.3%

2.6 s

free

Plain HTTP only

51.3%

1.0 s

free

Camoufox only

66.0%

8.5 s

free

Scrapling only

72.7%

6.8 s

free

Jina Reader only

74.0%

2.3 s

free

Firecrawl only

85.3%

4.8 s

$4.25

Zyte only

86.0%

12.0 s

not reported

Frankensurf, free tools only

84.7%

3.3 s

$0

Frankensurf, with paid fallbacks

95.3%

3.0 s

$1.06

Frankensurf with paid fallbacks read 18 sites Firecrawl missed; Firecrawl read none it missed. Of the 146 sites any tool read, it got 97.9%. Its median read is faster than Firecrawl’s, but its slowest reads are slower: p90 25.9 s against 11.3 s, when a read climbs several tools. Medians are over pages read; cost is per 1,000 pages read right. ZenRows is left out (its plan ran out of credits), as is Scrapfly.

Re-run with v0.34 the next morning: 95.3% again with paid fallbacks (median 3.0 s), free tools 84.0% with a median of 4.4 s. The free median depends on Jina Reader’s cache: the first run came an hour after other runs had read the same pages through it, and its first read of a page takes about 6 s.

Then once more on 150 sites never read before (held-out set 7, 11 October): 96.0% with paid fallbacks (median 2.9 s), free tools 88.0%, Firecrawl alone 84.7%. Frankensurf read 17 sites Firecrawl missed and Firecrawl none it missed (benchmarks/2026-10-11/).

Earlier fresh sets, same method: 152 sites on 6 October (v0.16) 89.5% against Firecrawl’s 80.3%; 139 sites on 9 October (v0.26) 88.5% against 74.1%. See Benchmarks.

Known walls

It’s an alpha, and some sites still win:

  • Need the paid tools: in a free-only spot check on 9 October, Etsy, Home Depot, Yelp, Crunchbase and G2 blocked every free tool.

  • Beat everything so far: Shopee, Temu and Idealista.

  • Social sites without a login: LinkedIn, X, YouTube, Threads, Bluesky and Reddit read fine. Instagram, TikTok, Facebook and Pinterest show only the public shell (name, bio, counts); the posts need a login.

  • Logged-in pages (your feeds, your orders) need a profile.

  • A slow tail: most reads take a few seconds, but one in ten climbs several tools and takes 25 s or more.

Found a site it can’t read? Report it; every report becomes a test case.

Develop

From a clone:

python3 -m venv .venv
.venv/bin/pip install -e '.[test,mcp]'
.venv/bin/frankensurf setup
PYTHONPATH=.:src .venv/bin/pytest -q

The product design is in SPEC.rst; contributor rules are in AGENTS.md. New tools are plugins, never branches in Core; see Writing a plugin for building, installing and trusting your own (frankensurf plugins), with a working example in examples/frankensurf-plugin-example. The website and docs live in site/.

Licence

Apache-2.0. See LICENSE.

Metadata

Release files for frankensurf 0.35.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for frankensurf 0.35.0
File Size Uploaded Provenance
frankensurf-0.35.0.tar.gz 533.3 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for frankensurf 0.35.0
File Interpreter ABI Platform
frankensurf-0.35.0-py3-none-any.whl Python 3 none any Details

Total release size: 885.4 kB

Release files / frankensurf-0.35.0.tar.gz

Download URL frankensurf-0.35.0.tar.gz
Size 533.3 kB
Tags Source
SHA-256 checksum
How to use checksums
8965cdb6c33ab31fed450aaecc0e992aa4f6916e2bb60803f6ee5fa03cc7a016
BLAKE2b-256 checksum
How to use checksums
582f81ad0f349c4dfa985759e11e00c12a13e02c83e3d56ee26a10691ef20728
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release files / frankensurf-0.35.0-py3-none-any.whl

Download URL frankensurf-0.35.0-py3-none-any.whl
Size 352.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c3670e5c1fc79622b798f8b4f1a8e2818e1f92cbeb4145211de8c658e520708c
BLAKE2b-256 checksum
How to use checksums
0630d64b420aebf5797e8c6c1942d1fd35bc6a0a0a52d93729c17b25ae414e7e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Security for frankensurf 0.35.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for frankensurf-0.35.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.35.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page