GitHub - vernikr-personal/browser-agent: Real headful Chrome on Xvfb with a hardware-level X11 mouse (XTEST Bézier input), Cloudflare Turnstile auto-solve and zero-leak CDP. Localhost HTTP API + CLI + Python SDK. Companion MCP bridge: vernikr/browser-agent-mcp · GitHub
Skip to content

About

Real headful Chrome on Xvfb with a hardware-level X11 mouse (XTEST Bézier input), Cloudflare Turnstile auto-solve and zero-leak CDP. Localhost HTTP API + CLI + Python SDK. Companion MCP bridge: vernikr/browser-agent-mcp

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

43 Commits

Folders and files

Repository files navigation

browser-agent

PyPI CI Release Python 3.12+ License: MIT

🔗 Companion project: @vernikr/browser-agent-mcp — the MCP server that exposes this daemon to LLM agents (Claude Code, Cursor, Freebuff…). The two projects are developed together and speak the HTTP contract in docs/api.md.

Real headful Chrome on Xvfb with a hardware-level X11 mouse. One localhost daemon gives any project, script, or AI agent on a Linux box a genuine desktop browser: steered over real XTEST input events on randomized Bézier paths, with zero-leak CDP (no Runtime.enable), Cloudflare Turnstile auto-solve, and RAM discipline for tiny VPSes (auto-hibernates when idle — browser-agent doctor reports what it actually costs).

Why not Playwright/CDP directly: mainstream automation stacks call Runtime.enable / Debugger.enable on connect — the primary headless-detection vector. This daemon's CDP client refuses those methods by construction and reads the DOM via DOM.getOuterHTML; all mouse/keyboard input goes through the X server, so clicks are isTrusted: true hardware events.

Install & provision (server, Ubuntu 24.04)

curl -LsSf https://astral.sh/uv/install.sh | sh     # if uv is missing
uv tool install browser-agent-server
sudo browser-agent setup --with-chrome              # apt deps + google-chrome-stable + systemd unit
sudo browser-agent doctor                           # self-check

No systemd (container, WSL, a supervisor of your own)? The same install works — --no-unit skips the unit file and you run the daemon yourself:

uv tool install browser-agent-server
sudo browser-agent setup --no-apt --no-unit         # chrome only; deps already in the image
browser-agent doctor                                # self-check
browser-agent serve &                               # foreground/background under your supervisor

Use it three ways:

browser-agent fetch "https://example.com" --text        # CLI
curl -s 127.0.0.1:8765/status                           # HTTP API (any language)

Driving a live session over SSH needs no bridge — every action the daemon implements is a subcommand:

browser-agent goto "https://example.com"                # navigate the session
browser-agent screenshot /tmp/page.png                  # capture the X11 window
browser-agent html                                      # read the page back
browser-agent move 640 360 && browser-agent click 640 360
browser-agent type "hello" --submit                     # then press Return
browser-agent key Page_Down
browser-agent scroll --clicks 5 --direction down
from browser_agent import BrowserClient                 # Python SDK

client = BrowserClient()
page = client.fetch("https://example.com")
print(page["title"], len(page["text"]))

Connect from your workstation (agents)

Point the MCP bridge at this daemon — details and ready-made agent configs live in the companion repo:

pnpm dlx @vernikr/browser-agent-mcp init --client claude-code

What you get

Capability Detail
Real Chrome, never headless google-chrome-stable headed on on-demand Xvfb (1280×720x24) + openbox
Stealth CDP Hand-rolled RFC-6455 client; Runtime.enable/Console.enable/Debugger.enable refused by construction
Human-like input X11 XTEST mouse on randomized cubic Bézier curves with ease-in/out pacing and Gaussian micro-jitter; a human-scale pause between press and release
Cloudflare Turnstile Detects the interstitial, locates the checkbox via the DOM and clicks it with the real X11 mouse
RAM discipline one renderer, a bounded JS heap, the tab reset after each fetch, and auto-hibernation after an idle period — see the env table for the timeout and browser-agent doctor for what it costs
One at a time Global mutex: 1 tab across all callers
Interfaces CLI browser-agent, HTTP API 127.0.0.1:8765, Python SDK browser_agent.BrowserClient
Live view browser-agent vnc start + SSH-forwarded VNC
Optional WARP route Auto-retry blocked pages through a local SOCKS5 proxy (127.0.0.1:40000)

Docs

For AI agents

Install one-liner: uv tool install browser-agent-server && sudo browser-agent setup --with-chrome && browser-agent doctor No-systemd host (container/WSL): uv tool install browser-agent-server && sudo browser-agent setup --no-apt --no-unit && browser-agent serve & Self-check: browser-agent doctor --json (exit 0 = host ready; every failed check carries a fix command you can run). Companion MCP for agent hosts: vernikr/browser-agent-mcp. SSH-only agent, no bridge: the CLI drives the whole session — goto, move, click, type, key, scroll, screenshot, html, stop. Every one is a subcommand, so nothing needs the MCP layer to be installed.

Platform support

Linux/X11 only (Xvfb, XTEST). Works great on a 1 vCPU / 1 GB RAM VPS. macOS/Windows workstations should run the MCP bridge and talk to a Linux host running this daemon.

License

MIT — see LICENSE.

About

Real headful Chrome on Xvfb with a hardware-level X11 mouse (XTEST Bézier input), Cloudflare Turnstile auto-solve and zero-leak CDP. Localhost HTTP API + CLI + Python SDK. Companion MCP bridge: vernikr/browser-agent-mcp

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages