Skip to main content

AnyBrowser

A browser-automation and agent runtime you can take apart. Three interfaces — the browser, the transport, the model — each with a registry and a conformance suite, so "implement your own" is something you can verify rather than hope for.

from anybrowser import open_engine

async with await open_engine("playwright") as engine:
    await engine.navigate("https://example.com")
    page = await engine.snapshot()
    await engine.click(page.elements[0])

Same code against Chrome attached to your own logged-in window, against Safari, or against a browser nobody has written a backend for yet.


Why this exists

Most browser automation assumes it owns the browser: a fresh profile, a clean window, a driver launched with the right flags. That assumption breaks the moment the job is to work in the browser a person actually uses — their tabs, their sessions, their logins, already open. You cannot ask them to log in again inside a throwaway profile, and you cannot attach WebDriver to a window that was not started for automation.

AnyBrowser assumes it does not own the browser. Every abstraction here comes from driving real Chrome and Safari windows in production, and every one of the three ideas below is a failure mode that cost someone a week.

Backends differ in kind, not quality. Safari has no CDP; Apple's Web Inspector protocol needs private entitlements. WebDriver cannot adopt your open window. So an engine declares what it can do and callers route around the gaps, instead of discovering them by catching an exception halfway through a task. See capabilities.

A no-op is not a success. The most common way an agent dies is a click that hit nothing, reported as "success", read back by the model as progress, and repeated forever. Every action returns changed alongside ok, and the conformance suite fails an engine that clicks dead space and calls it a change. See truthful outcomes.

The contract is executable. pytest --pyargs anybrowser_conformance --engine yours is the definition of a working backend.


Install

pip install anybrowser[playwright]      # the reference engine, easiest start
pip install anybrowser[chrome]          # attach to your own Chrome
pip install anybrowser[all]             # everything

Python 3.10+. import anybrowser pulls in no browser driver, no HTTP server and no LLM SDK — every backend is an extra.

The Playwright engine needs its browser binaries once, which pip cannot fetch for you:

playwright install chromium

Running a contract against something whose extra is missing skips rather than fails, and says which extra to install — so pip install anybrowser[all] is the shortcut if you would rather not think about it.


The three interfaces

You want to Implement Registry group Ships with
Drive a different browser BrowserEngine anybrowser.engines playwright, chrome, safari
Change how clients reach the daemon DaemonTransport anybrowser.transports websocket, unix, memory
Use a different model ModelProvider anybrowser.models openai, anthropic

Register with an entry point and yours is selectable by name everywhere:

[project.entry-points."anybrowser.engines"]
firefox = "my_package.engine:FirefoxEngine"
pytest --pyargs anybrowser_conformance --engine firefox     # the engine contract
pytest --pyargs anybrowser_conformance --transport grpc     # the transport one

Each flag selects a contract and skips the other. The suite is capability-gated. A backend that honestly declares it cannot drag is skipped, not failed. A backend that claims it can drag and then doesn't is failed — the suite tests truthfulness as hard as it tests function.

Full walkthrough: Writing an engine.


Engine status

Engine Attaches to your session Trusted input Engine contract Gated by CI
chrome (DevTools) no — needs the launch flag yes 28 passed, 4 skipped yes
chrome (extension) yes — your own windows yes passes (local run) no — needs a browser with the extension loaded
playwright no — own profile yes 28 passed, 4 skipped yes, the reference engine
safari yes — accessibility + extension yes needs a local setup (guide) only that it refuses cleanly off-setup

The engine contract is 32 tests. The 4 skips are the capability gate working as intended: those tests assert the error an engine raises for something it does not declare, so they stand down for an engine that declares it. Run the whole suite directory and you will see more skips still — the transport and model contracts, idle because you passed neither --transport nor --model.

Pointing the engine contract at the remote engine grades the whole daemon stack — transport, protocol, codec, dispatch — and it scores the same 28 passed, 4 skipped over both the memory and websocket transports.

The Chrome engine has two pipes behind one interface. devtools talks to a browser started with --remote-debugging-port — standard, and the only mode that runs in CI. extension relays CDP through a browser extension and is the one that matters, because it attaches to the browser you already have open, with your tabs and your logins. Same engine either way; the connection reports which it is, and the declared attach_to_user_session capability is derived from that rather than asserted next to it.

Both Chrome pipes pass the contract. To drive the browser you already have open, see driving your own Chrome — note that --load-extension is silently ignored by Chrome stable, which is a memorable afternoon if nobody tells you.

Safari is implemented in both halves: a Swift helper for trusted background input and occlusion-proof capture, and a Web Extension for the DOM and pointer gestures. It needs a local build and a one-time Accessibility grant, so it skips rather than fails where that has not been done — see driving Safari.


Layout

src/anybrowser/
  core/          interfaces and value types — imports no backend
  engines/       chrome, safari, playwright
  perception/    turning a page into a snapshot, engine-agnostic
  daemon/        protocol, transports, the server that owns an engine
  agent/         planner, tools, executor, memory
  models/        LLM providers
conformance/     the executable contract
docs/            architecture, guides, ADRs

Docs


Contributing

Start with CONTRIBUTING.md. Good first issues are labelled good first issue; a new backend is the highest-value contribution there is, and the conformance suite means you can tell when it's done.

By participating you agree to the Code of Conduct. Security reports go to SECURITY.md, not the issue tracker.

License

Apache-2.0. See LICENSE and NOTICE.

Metadata

Release files for anybrowser 0.1.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 anybrowser 0.1.0
File Size Uploaded
anybrowser-0.1.0.tar.gz 149.0 kB Details

Built distribution (wheel)

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

Total release size: 304.4 kB

Release files / anybrowser-0.1.0.tar.gz

Download URL anybrowser-0.1.0.tar.gz
Size 149.0 kB
Tags Source
SHA-256 checksum
How to use checksums
ef03452de2998ae0eb2879e6a588d0ea9ea2ff8a528e0114cbb7ee4df60a2e4b
BLAKE2b-256 checksum
How to use checksums
33062922445a9b200dfab45f84b09aca77905bcbde85a23225a434e6735a3151
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 2, 2026.

Transparency log

Release files / anybrowser-0.1.0-py3-none-any.whl

Download URL anybrowser-0.1.0-py3-none-any.whl
Size 155.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fba0799211b379a09dbdb31dfadf749419afdec4b4292172bbfb2454a2d3f0f1
BLAKE2b-256 checksum
How to use checksums
6be87d32701629c0dd5eafa79f915e4e5f83adc3196c3b23dcfeeccf0385e6e1
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 2, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.0

2 release files

This release

0.1.0 This release

2 release files

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