Skip to main content

Browser-agnostic automation for AI agents

Project description

browsectl

Browser-agnostic automation for AI agents.

A lightweight CLI that lets AI agents (or humans) drive a real browser session: navigate, screenshot, click, type, extract DOM, and evaluate JavaScript. Designed so that agents can see client-side-rendered pages (like LinkedIn) that aren't curl-friendly.

How it works

You launch your browser with remote debugging enabled. browsectl connects to it and sends commands over the browser's native automation protocol. The agent takes screenshots to "see" the page and decides what to do next. When it hits a CAPTCHA or 2FA wall, it tells you and waits.

The core is browser-agnostic. Concrete browser support is provided by swappable backends (currently: CDP for Chrome/Chromium).

Requirements

  • Python 3.14+
  • Chrome or Chromium (for the CDP backend)

Installation

git clone <repo-url>
cd browsectl
python -m venv .venv
.venv/bin/pip install poetry
.venv/bin/poetry install

Quick start

1. Launch and connect (one step)

browsectl -s <session> launch

This auto-assigns a free port, starts Chrome with its own profile at ~/.browsectl/profiles/<session>/, waits for CDP readiness, connects, and saves the session. The port is stored in the session file so all subsequent commands find it automatically. Logins persist across runs. Your existing Chrome windows are unaffected.

You can also specify a port explicitly if needed:

browsectl -s <session> launch <port>

If the explicit port is already in use, launch fails immediately with a clear error.

For slow-starting environments, override the CDP readiness timeout (default 15s):

browsectl -s <session> launch --timeout 30

2. Use it

Every command requires -s <session>:

browsectl -s <session> goto "https://example.com"
browsectl -s <session> screenshot                    # saves screenshot.png
browsectl -s <session> screenshot /tmp/page.png      # custom path
browsectl -s <session> info                          # current URL and title
browsectl -s <session> html "h1"                     # extract innerHTML
browsectl -s <session> eval "document.title"         # run JavaScript
browsectl -s <session> click "#login-button"         # click by CSS selector
browsectl -s <session> type "#email" "me@example.com"
browsectl -s <session> scroll 500                    # scroll down 500px
browsectl -s <session> scroll -300                   # scroll up 300px
browsectl -s <session> wait ".results" 10            # wait for element (10s timeout)
browsectl -s <session> tabs                          # list open tabs
browsectl -s <session> newtab "https://github.com"   # open new tab
browsectl -s <session> switchtab <tab-id>            # switch to tab (ID from 'tabs')
browsectl -s <session> clear-cookies                 # clear all browser cookies

3. Manage sessions

browsectl sessions                    # list all sessions and their status
browsectl -s <session> stop           # kill Chrome and remove the session
browsectl stop-all                    # stop all sessions at once
browsectl profiles                    # list profile directories
browsectl profiles --prune            # remove orphaned profile directories

sessions shows each session's name, host:port, PID, and whether the process is running, dead, or external (connected manually, no PID tracked).

Connecting to an existing browser

If Chrome is already running with --remote-debugging-port, use connect instead of launch:

browsectl -s <session> connect <host> <port>

Both host and port are required.

Multiple sessions

Run multiple independent browser sessions simultaneously. Each gets its own auto-assigned port:

browsectl -s <session-a> launch
browsectl -s <session-b> launch
browsectl -s <session-a> goto "https://example.com"
browsectl -s <session-b> goto "https://github.com"

Each session gets its own Chrome process, profile directory, cookies, and localStorage. Ports are auto-assigned so agents never clash. Use browsectl sessions to see all active sessions, and browsectl -s <session> stop to shut one down. See docs/multi-session.md for details.

Backend selection

browsectl -s <session> -b cdp goto "https://example.com"   # explicit (default)

Available backends: cdp. The architecture supports adding others (WebDriver, Marionette, etc.) without changing the core.

Architecture

Hexagonal / ports-and-adapters. The core never imports a concrete browser adapter.

browsectl/
  models.py       # domain types (PageInfo, Screenshot, Tab, etc.)
  ports.py         # function signature contracts, generic over Session
  gateway.py       # BrowserGateway[S] -- frozen bundle of port functions
  core.py          # command dispatch, browser-agnostic
  main.py          # CLI entry point, wiring
  adapters/
    cdp.py         # Chrome DevTools Protocol implementation

Per-site guides

docs/sites/ contains navigation guides for specific websites. Each guide documents working selectors, SPA quirks, authentication patterns, and step-by-step browsectl workflows for that site. Selectors are timestamped since sites change their DOM frequently.

Use docs/sites/_template.md as a starting point for new guides.

Development

.venv/bin/pytest tests/ -v       # run tests
.venv/bin/mypy browsectl/        # type check (strict)
.venv/bin/ruff check browsectl/  # lint

License

MIT. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

browsectl-0.2.1.tar.gz (14.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

browsectl-0.2.1-py3-none-any.whl (16.0 kB view details)

Uploaded Python 3

File details

Details for the file browsectl-0.2.1.tar.gz.

File metadata

  • Download URL: browsectl-0.2.1.tar.gz
  • Upload date:
  • Size: 14.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.4.1 CPython/3.14.6 Linux/6.17.0-1020-azure

File hashes

Hashes for browsectl-0.2.1.tar.gz
Algorithm Hash digest
SHA256 ff5ad8d852fd1bf58ab759aa00aab8f22863e7169639f2a2967d778524897d91
MD5 7f5a45a90121eb77c06ff0cae7ee9889
BLAKE2b-256 59ac404b7729e9d1804fa6f6fedef2708c2223e3ec3319e385b9c9ea20f44d7a

See more details on using hashes here.

File details

Details for the file browsectl-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: browsectl-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 16.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.4.1 CPython/3.14.6 Linux/6.17.0-1020-azure

File hashes

Hashes for browsectl-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d1d537f5090eae6b4445924d22f06853656437e0fa2e4541ea20820aade9a102
MD5 3326b1bb29ca36d6da2f6891ad7e008a
BLAKE2b-256 f6df33c436e0d85ee3902018d86d5cd185b6d0aa5a37ecb6e74b56991f27ea36

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page