browser-agent
🔗 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 indocs/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 to ~12 MB idle).
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
Use it three ways:
browser-agent fetch "https://example.com" --text # CLI
curl -s 127.0.0.1:8765/status # HTTP API (any language)
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; human hold delays 55–125 ms |
| Cloudflare Turnstile | Detects the interstitial, locates the checkbox via the DOM and clicks it with the real X11 mouse |
| RAM discipline | --renderer-process-limit=1, JS heap capped at 256 MB, tab reset after each fetch, auto-hibernation after idle (default 60 s) ⇒ ~12 MB resting |
| 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
docs/deployment.md— provisioning, systemd, memory limits, WARP, VNC loginsdocs/api.md— HTTP contract (v1)docs/architecture.md— how and why it worksdocs/security.md— trust boundaries (loopback-only, no auth)docs/troubleshooting.md— symptom → cause → action
For AI agents
Install one-liner: uv tool install browser-agent-server && sudo browser-agent setup --with-chrome && browser-agent doctor
Self-check: browser-agent doctor --json (exit 0 = host ready).
Companion MCP for agent hosts: vernikr/browser-agent-mcp.
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.
Metadata
Release files for browser-agent-server 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| browser_agent_server-1.0.0.tar.gz | 76.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| browser_agent_server-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 105.0 kB
Release files / browser_agent_server-1.0.0.tar.gz
| Download URL | browser_agent_server-1.0.0.tar.gz |
|---|---|
| Size | 76.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f4167ab20bc688eb45bc5e715efaa87b26f2e0e021d58ef808098c66bea7e26b
|
|
BLAKE2b-256 checksum How to use checksums |
4aac0a4b87415f4f3d89a4a6e6bb77cb187691ac856d835e1796bb64d204d325
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / browser_agent_server-1.0.0-py3-none-any.whl
| Download URL | browser_agent_server-1.0.0-py3-none-any.whl |
|---|---|
| Size | 28.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5f463c0391d4362a1a5db7dbd8828f97b4bc81367bb0c15266934967c01c6097
|
|
BLAKE2b-256 checksum How to use checksums |
b7acef437671a8fb0cda6d50b2df1c130b0e297f9d64274c2d434b9f18541786
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|