Auto Browser MCP Server
Give your AI agent a real browser — with a human in the loop. Open-source MCP-native browser agent.
Auto Browser is an open-source mcp server by LvcidPsyche, written mainly in Python, with 914 GitHub stars and the MIT license. Its code was last updated Oct 30, 2026.
Auto Browser
<a href="https://glama.ai/mcp/servers/LvcidPsyche/auto-browser"> <img src="https://glama.ai/mcp/servers/LvcidPsyche/auto-browser/badge" alt="Auto-Browser on Glama: grade A for license, quality, and maintenance" width="420"> </a>
Give your AI agent a real browser, with a human in the loop.
Auto Browser is an MCP-native browser control plane for authorized workflows. It gives MCP clients, LLM agents, and operators a shared Playwright browser with human takeover, reusable auth profiles, approvals, audit trails, and local-first deployment.
Works with:
- Claude Code, Codex (CLI, IDE extension, and app), Google Antigravity, Cursor, and VS Code, connected directly over HTTP
- Claude Desktop, through the bundled stdio bridge
- any MCP client that can talk HTTP or stdio
- direct REST callers when you want curl-first control
Why Auto Browser
- MCP-native from day one. The browser surface is already packaged as an MCP server instead of bolted on after the fact.
- Human takeover when the web gets brittle. noVNC keeps the same live session available when a person needs to step in.
- Login once, reuse later. Save named auth profiles and reopen fresh sessions that are already signed in.
- Local-first by default. Run the full stack on your own box with Docker Compose, or use Codespaces for a quick hosted demo.
- Safety rails built in. Approvals, operator identity, PII scrubbing, Witness receipts, and policy presets are all part of the product surface.
- Evidence you can hand to someone else. Witness receipt chains are Ed25519-signed, and an exported bundle verifies with
scripts/verify_witness_bundle.py— which imports nothing from this project, so a recipient need not run or trust this controller to check it. The signing key sits beside the receipts, so for evidence that survives a compromised box, pin a head hash you recorded earlier or ship the receipts off the box (details). - We audit ourselves in public.
docs/audits/2026-08-execution-audit.mddocuments an adversarial audit of this repo that found safety controls which reported success while doing nothing, with reproductions, the fixes, and the gates that close the class. - Governed skill induction. Verified browser traces can become staged skill candidates with provenance that is signed when a mesh identity is configured — and checked on read, not just produced — plus verifier adapters and review-only graduation — agents that prove they can repeat themselves correctly, not just act once.
Good Fits
- internal dashboards and admin tools
- operator-assisted QA and browser debugging
- login-once, reuse-later account workflows
- brittle sites where a human may need to recover the flow
- MCP-powered agent workflows that need a real browser, not just HTML fetches
Not the Goal
- CAPTCHA solving
- unauthorized scraping or account automation
- deceptive identity shaping or bypass tooling
What You Get
| Browser Control | Operator Safety | Deployment and Integration |
|---|---|---|
| Playwright-backed sessions with screenshots, DOM summaries, OCR excerpts, tab controls, downloads, and network inspection | approval gates, operator identity headers, audit events, PII scrubbing, Witness receipts, and protection profiles | MCP over HTTP, bundled stdio bridge, REST API, Docker Compose, Codespaces, auth profiles, and optional per-session isolation |
Quickstart
git clone https://github.com/LvcidPsyche/auto-browser.git
cd auto-browser
docker compose up --build
That is enough for local development with the default settings. On first start the controller
generates an API token and saves it to data/api-token in this folder (git ignores it), and
every API and MCP request must send it as Authorization: Bearer <token>, apart from the health
checks, /version, the dashboard page, share links and /mesh/receive. The dashboard asks
for it once, the examples below read it with $(cat data/api-token), and the MCP clients take
it as shown under MCP Clients. API_ALLOW_TOKENLESS_LOOPBACK=true runs the
controller without a token, as it ran before, but then any container on the compose network
can drive the browser (a write a browser sends from another web origin is refused).
Optional:
cp .env.example .env
make doctor
Run make doctor from a normal terminal with local Docker access and permission to open localhost sockets.
Open:
- API docs:
http://127.0.0.1:8000/docs(Authorize with the token to try requests). The docs need no token on a loopback deployment (an exposed one answers 401), and Swagger UI loads its assets from cdn.jsdelivr.net. - Operator dashboard:
http://127.0.0.1:8000/dashboard, which includes the queue of actions waiting on your approval; paste the token when it asks, or openhttp://127.0.0.1:8000/dashboard#token=<token> - Visual takeover:
http://127.0.0.1:6080/vnc.html?autoconnect=true&resize=scale
All published ports bind to 127.0.0.1 by default.
Prebuilt images
Every release is also published to GHCR, so you can skip the build:
docker compose -f docker-compose.yml -f docker-compose.images.yml up -d
AUTO_BROWSER_IMAGE_TAG picks the version: latest (the default), a release such as 1.10.1, or
edge for the current main. The images are linux/amd64, and each carries an SBOM and a build
provenance attestation (gh attestation verify oci://ghcr.io/lvcidpsyche/auto-browser-controller:latest -R LvcidPsyche/auto-browser).
The controller image leaves out the agent CLIs; for *_AUTH_MODE=cli, build from source with
INSTALL_AGENT_CLIS=true.
With isolated sessions, name docker-compose.images.yml last, so they start from the published browser image too:
docker compose -f docker-compose.yml -f docker-compose.isolation.yml -f docker-compose.images.yml up -d
In the other order, the isolation overlay's default wins, and isolated sessions run a local
auto-browser-browser-node:latest: a stale build, or no image at all.
Try It in Codespaces
Codespaces provisions the stack automatically. The dashboard and noVNC tabs are ready once both images have built and started; the first start builds them from source.
First Useful Demo
The highest-signal flow in this repo is:
- create a session
- log in manually if the site needs a human
- save the session as a named auth profile
- open a new session from that auth profile
- continue work without reauthing
Start here:
Minimal session creation, from the auto-browser folder (AUTH carries the token; if you
set API_BEARER_TOKEN, use $API_BEARER_TOKEN in place of $(cat data/api-token)):
AUTH=(-H "Authorization: Bearer $(cat data/api-token)")
curl -s "${AUTH[@]}" http://127.0.0.1:8000/sessions \
-X POST \
-H 'content-type: application/json' \
-d '{"name":"demo","start_url":"https://example.com"}' | jq
Minimal observation:
curl -s "${AUTH[@]}" http://127.0.0.1:8000/sessions/<session-id>/observe | jq
Recent Changes
See CHANGELOG.md for the full release history.
MCP Clients
Auto Browser exposes:
- an HTTP MCP endpoint at
http://127.0.0.1:8000/mcp - convenience endpoints at
http://127.0.0.1:8000/mcp/toolsandhttp://127.0.0.1:8000/mcp/tools/call - a stdio bridge:
uvx auto-browser-mcpfrom PyPI, orscripts/mcp_stdio_bridge.pyin a repo checkout
Clients that speak MCP over HTTP connect directly, sending the controller's token. With Claude
Code or Codex, from the auto-browser folder (--scope user makes the server available in every
project, not only this folder):
claude mcp add --transport http --scope user auto-browser http://127.0.0.1:8000/mcp \
--header "Authorization: Bearer $(cat data/api-token)"
# Codex reads the token from the variable you name: export it wherever Codex runs.
export AUTO_BROWSER_TOKEN="$(cat data/api-token)"
codex mcp add auto-browser --url http://127.0.0.1:8000/mcp --bearer-token-env-var AUTO_BROWSER_TOKEN
Google Antigravity takes the server in its raw MCP config (MCP Servers, then Manage MCP
Servers, then View raw config), or in ~/.gemini/config/mcp_config.json. It reads
serverUrl, not url, and the token goes in headers:
{
"mcpServers": {
"auto-browser": {
"serverUrl": "http://127.0.0.1:8000/mcp",
"headers": { "Authorization": "Bearer <contents of data/api-token>" }
}
}
}
Cursor, VS Code, Claude Desktop through the stdio bridge (which reads the file named by
AUTO_BROWSER_TOKEN_FILE / --token-file; the repo wrapper, make stdio-bridge or
scripts/mcp_stdio_bridge.py, defaults that to its checkout's data/api-token for a loopback
URL), and pairing Auto Browser with a web-search MCP server are covered in
docs/mcp-clients.md.
The default MCP tool profile is curated: the 20 tools (21 with a vision model) a browsing agent needs (sessions, observe and screenshot, execute_action, page and download reading, tabs, auth profiles, wait_for_selector, eval_js, human takeover). Every listed tool costs the model context on every request, so the diagnostics, audit, harness, and admin tools are in the full profile. To expose everything, set:
MCP_TOOL_PROFILE=full
MCP_TOOL_PROFILE=lean serves just the 7-tool browsing loop (observe, screenshot, execute_action, get_html, find_elements, human takeover, close), and MCP_TOOL_PACKS adds or removes named packs on top of any profile, e.g. MCP_TOOL_PACKS=tabs,downloads or -scripting. The pack table is in docs/mcp-clients.md.
Raw tool-call example:
curl -s "${AUTH[@]}" http://127.0.0.1:8000/mcp/tools/call \
-X POST \
-H 'content-type: application/json' \
-d '{
"name":"browser.create_session",
"arguments":{
"name":"demo",
"start_url":"https://example.com"
}
}' | jq
Client setup guides:
docs/mcp-clients.mdexamples/claude-desktop-setup.mdexamples/cursor-mcp-setup.mdexamples/claude_desktop_config.json
For resource listing, resource reads, and subscription-style update examples,
see docs/mcp-clients.md#resources-and-subscriptions.
Convergence Harness
Auto Browser ships a Stage 0 convergence harness for Agent Skill Induction. It runs a structured task contract, records tamper-checked traces, verifies completion, and writes a staged skill candidate carrying provenance. With a mesh identity configured that provenance is signed, and the registry verifies the signature before serving a candidate — a candidate that fails the check, or that was dropped into the staging directory unsigned, is refused. Candidates induced from a mock run are marked simulated so they cannot pass as converged. Generated skills are staged only — promotion stays explicit and reviewed.
The harness tools — convergence runs, run status and traces, drift checks, candidate management, and graduation — are in the full MCP tool profile (MCP_TOOL_PROFILE=full); over REST, POST /mcp/tools/call calls them once the controller serves them.
Start with docs/convergence-harness.md. A deterministic local smoke is:
python -m controller.harness.run --contract evals/contracts/example_read.json --mock-final-url https://example.com --mock-final-text "Example Domain"
For MCP clients, set MCP_TOOL_PROFILE=full (or MCP_TOOL_PACKS=harness on top of curated) to expose the harness.* tools.
Security and Compliance
For a real private deployment, set at least:
APP_ENV=production
API_BIND_SCOPE=exposed
API_BEARER_TOKEN=<strong-random-secret>
REQUIRE_OPERATOR_ID=true
AUTH_STATE_ENCRYPTION_KEY=<44-char-fernet-key>
REQUIRE_AUTH_STATE_ENCRYPTION=true
SHARE_TOKEN_SECRET=<strong-random-secret>
CONTROLLER_ALLOWED_HOSTS=<controller hostname>
ALLOWED_HOSTS=<sites the browser may visit>
REQUEST_RATE_LIMIT_ENABLED=true
METRICS_ENABLED=true
STEALTH_ENABLED=false
With APP_ENV=production the controller refuses to start while the token, REQUIRE_OPERATOR_ID, either encryption setting, SHARE_TOKEN_SECRET or CONTROLLER_ALLOWED_HOSTS is missing, rate limiting is off, or ALLOWED_HOSTS is empty or *, and the startup log names each one; ALLOWED_HOSTS left out or at its example value, METRICS_ENABLED=false and STEALTH_ENABLED=true only warn.
By default every session shares one Chromium process and one noVNC desktop (SESSION_ISOLATION_MODE=shared_browser_node). Cookies and storage stay separate per session, but a human taking over one session can see the others' windows. When sessions belong to different people, accounts or trust domains, start with make up-isolation to give each session its own browser container, takeover surface and Docker network (docker_ephemeral), so one session's browser cannot reach another's Playwright server. docs/session-isolation-audit.md has the details.
ALLOWED_HOSTS is held before the request goes out (PRE_REQUEST_BLOCKING=true, the default):
- Stopped before it is sent: a top-level navigation's request to a host off
ALLOWED_HOSTS, including every redirect hop and a popup's first request. - Still caught after the fact by NAV-07 (the guard that sends a refused page back to
about:blankonce it commits):- speculation-rules prefetch in attach modes, and in a launched browser where it could not be turned off
(launched browsers turn it off when the controller acquires them;
/readinesswarns when that failed); - a navigation a service worker serves (one a same-site refused iframe registered) for a popup's first navigation, and for any the popup makes before its service-worker bypass is set (a background task once the controller sees the popup), in every mode;
blob:navigations a refused iframe makes;- bfcache restores in attach modes;
- requests held when the gate detaches, and any navigation a page starts itself before the replacement gate attaches. They go out. The controller attaches the replacement before it closes that browser's sessions, so the window is one attach, and it refuses their actions meanwhile.
- speculation-rules prefetch in attach modes, and in a launched browser where it could not be turned off
(launched browsers turn it off when the controller acquires them;
- Any tab, rarely: a navigation to a refused host fails closed in any tab of a gated browser, the operator's own included in attach modes, when the gate cannot classify its frame (its lookup failed).
- Not covered: iframes and subresources of other hosts.
In an attach mode (CDP_CONNECT_URL, browser.cdp_attach) the gate stops navigations of the controller's
sessions only (apart from a frame it cannot classify, above), but every navigation in that Chrome, the
operator's own tabs included, waits on its reply: about 13 ms each, the median measured on Chromium 151. Start
that Chrome with --disable-features=BlockOriginHeaderModificationOnRedirect,AvoidCorsURLLoaderRestartOnRedirect
and set CDP_BLOCK_ORIGIN_ON_REDIRECT_DISABLED=true. Without it, cross-origin 307/308 POST redirects can fail, and
on Chrome 155 and later credentialed cross-origin requests that need a CORS preflight fail after a redirect, in
the operator's own tabs too, while the controller is attached. Details:
docs/deployment.md.
COMPLIANCE_TEMPLATE can apply a preconfigured posture at startup:
| Preset | Auth Encryption | Operator ID | PII Scrub | Isolation | Max Auth-State Age |
|---|---|---|---|---|---|
strict | required | required | all layers | docker_ephemeral | 4h |
balanced | - | required | network + text | shared | 24h |
Both presets require upload approvals and enable Witness receipts. Startup writes the applied policy to /data/compliance-manifest.json. The legacy names (HIPAA, SOC2, GDPR, PCI-DSS) still work as deprecated aliases and emit a warning at startup.
Example:
COMPLIANCE_TEMPLATE=strict docker compose up
For deployment details, hosted Witness notes, CLI auth modes, and reverse-SSH guidance, see:
docs/deployment.mddocs/production-hardening.mddocs/session-isolation-audit.md: what each isolation mode does and does not separate
Architecture at a Glance
flowchart LR
User[Human operator] -->|watch / takeover| noVNC[noVNC]
LLM[Any model: OpenAI / Claude / Gemini / OpenRouter / Grok / DeepSeek / MiniMax / local] -->|shared tools| Controller[Controller API]
Controller -->|Playwright protocol| Browser[Browser node]
noVNC --> Browser
Browser --> Artifacts[(screenshots / traces / auth state)]
Controller --> Artifacts
Controller --> Policy[Allowlist + approval gates]
Model providers
First-class adapters for OpenAI, Claude, and Gemini (API or CLI). Beyond those,
a single generic OpenAI-compatible adapter drives any model reachable over an OpenAI
/chat/completions endpoint — set an API key to enable it:
| Provider | Reaches |
|---|---|
openrouter | one key → ~every frontier model (Claude, GPT, Gemini, Grok, DeepSeek, Llama, Mistral, Qwen, …) |
xai | Grok |
deepseek | DeepSeek (text-only; driven from the DOM/accessibility outline) |
minimax | MiniMax |
openai_compatible | any custom base URL — self-hosted Ollama / vLLM / LM Studio, Azure OpenAI, Together, Groq, Fireworks, … |
Vision (screenshots) is used for every provider except text-only ones. See .env.example for
the *_API_KEY / *_BASE_URL / *_MODEL settings.
Core components:
browser-node/runs Chromium, Xvfb, x11vnc, and noVNCcontroller/exposes the FastAPI controller, MCP transport, policy rails, and orchestration endpointsdata/holds runtime artifacts, auth state, approvals, audit logs, and optional CLI cachesscripts/contains local helpers for doctor, smoke tests, bridges, and release checks
Repo Guide
| Path | What It Contains |
|---|---|
controller/ | controller API, MCP transport, tests, and packaging |
browser-node/ | browser runtime and Playwright connection layer |
examples/ | copy-paste flows and MCP client setup |
integrations/langchain/ | LangChain, LangGraph, and CrewAI adapters |
docs/ | architecture, deployment, hardening, and launch docs |
scripts/ | doctor, smoke harnesses, stdio bridge, and auth helpers |
ops/ | supporting service templates and operational assets |
Common Commands
| Command | Purpose |
|---|---|
make help | list available repo commands |
make lint | run Ruff checks across the whole repo |
make test | run controller tests in Docker |
make test-local | run controller tests on host Python 3.11+ |
make eval | run deterministic provider/profile eval scoring |
make doctor | run the local readiness smoke |
make release-audit | run the fuller release-validation pass |
make smoke-isolation | verify per-session Docker isolation |
make smoke-reverse-ssh | verify reverse-SSH remote access |
Documentation Map
| If You Want To... | Start Here |
|---|---|
| understand the system shape | docs/architecture.md |
| connect Claude, Codex, Antigravity, Cursor, or VS Code | docs/mcp-clients.md |
| run the curl-first examples | examples/README.md |
| deploy on a trusted host | docs/deployment.md |
| review production constraints | docs/production-hardening.md |
| see what session isolation does and does not separate | docs/session-isolation-audit.md |
| run the convergence harness | docs/convergence-harness.md |
| run the agent evals | docs/agent-evals.md |
| drive the built-in agent loop and its model providers | docs/llm-adapters.md |
| let a peer node ask this controller to run a tool (mesh) | docs/mesh.md |
| inspect release history | CHANGELOG.md |
| see where the project is headed | ROADMAP.md |
Contributing
If you want to help, start with:
If Auto Browser is useful, a star helps other people find it. Sponsorship and tip options live in TIPS.md.
Auto Browser alternatives
View more →Similar mcp servers in Browser Automation, ranked by GitHub stars. Compare licence, recent activity and scan status before you choose.
| Name | Stars | Licence | Last updated | Scan |
|---|---|---|---|---|
| Auto Browser (this page) LvcidPsyche | 914 | MIT | Oct 30, 2026 | Scanned, no flagged issues |
| Chrome Devtools MCP ChromeDevTools | 55k | Apache-2.0 | Nov 1, 2026 | Scanned, no flagged issues |
| Playwright MCP microsoft | 39k | Apache-2.0 | Oct 31, 2026 | Scanned, no flagged issues |
| MCP Chrome hangwin | 13k | MIT | Jan 6, 2026 | Scanned, no flagged issues |
| Browser Tools MCP AgentDeskAI | 7.3k | MIT | Oct 28, 2026 | Scanned, no flagged issues |
| MCP BrowserMCP | 7.3k | Apache-2.0 | Oct 30, 2026 | Scanned, no flagged issues |