AI browser automation. Write async Python to navigate, click, type, and extract data.
MCP Server: me.openbrowser/openbrowser-ai
The me.openbrowser/openbrowser-ai MCP server provides AI browser automation. It is designed to run code that can navigate web pages, click elements, type input, and extract data, using async Python workflows. Topics associated with this server include AI agents and browser automation skills.
🛠️ Key Features
AI browser automation
Async Python control for browser actions
Capabilities include navigate, click, type, and extract data
Related areas: AI agents and agent skills
🚀 Use Cases
Automating product scraping workflows (example referenced for Walmart)
Extracting structured information from web pages during automation runs
Managing browser state via saved cookies and scheduled tasks (hosted version)
⚡ Developer Benefits
Async Python scripting interface for browser automation
Reusable browser automation skills for agent-style workflows
Hosted dashboard availability for cookies and scheduled tasks (hosted version)
⚠️ Limitations
Cloud dashboard features are described as available only in the hosted version
Early access is indicated via a waitlist (hosted version)
AI-powered browser automation using CodeAgent and CDP (Chrome DevTools Protocol)
OpenBrowser is a framework for intelligent browser automation. It combines direct CDP communication with a CodeAgent architecture, where the LLM writes Python code executed in a persistent namespace, to navigate, interact with, and extract information from web pages autonomously.
CodeAgent Architecture - LLM writes Python code in a persistent Jupyter-like namespace for browser automation
Raw CDP Communication - Direct Chrome DevTools Protocol for maximum control and speed
Vision Support - Screenshot analysis for visual understanding of pages
15 LLM Providers - OpenAI, Anthropic, Google, Groq, AWS Bedrock, Azure, Ollama, DeepSeek, Cerebras, OpenRouter, OCI, and more
MCP Server - Model Context Protocol for Claude Desktop, Claude Code, Codex, OpenCode, and other AI assistants, with reusable saved login sessions
CLI Daemon - Persistent browser daemon with -c flag for direct code execution from Bash, saved login state, and 10-minute auto-shutdown
Workflow Recording - Record, replay, and export browser sessions to Jupyter notebooks or API crawler code
Video Recording - Record browser sessions as video files with ffmpeg
Cloud Platform - Full-stack web UI with real-time VNC streaming, saved logins (KMS-encrypted), scheduled workflows (EventBridge + SQS), and email notifications (SES)
Plugin System - Claude Code plugin with 7 guided skills (deep research, web scraping, form filling, e2e testing, page analysis, accessibility audit, file download)
Installation
Quick install (macOS / Linux)
bash
curl -fsSL https://raw.githubusercontent.com/billy-enrizky/openbrowser-ai/main/install.sh | sh
No separate browser install needed. OpenBrowser auto-detects any installed Chromium-based browser (Chrome, Edge, Brave, Chromium) and uses it directly. If none is found and uvx is available, Chromium is installed automatically on first run. To pre-install manually (requires uvx): openbrowser-ai install
Quick Start
Basic Usage
python
import asyncio
from openbrowser import CodeAgent, ChatGoogle
asyncdefmain():
agent = CodeAgent(
task="Go to google.com and search for 'Python tutorials'",
llm=ChatGoogle(model="gemini-3-flash"),
)
result = await agent.run()
print(f"Result: {result}")
asyncio.run(main())
# Add the marketplace (one-time)
claude plugin marketplace add billy-enrizky/openbrowser-ai
# Install the plugin
claude plugin install openbrowser@openbrowser-ai
This installs the MCP server and 7 built-in skills:
Skill
Description
deep-research
Conduct cited, multi-source web research and produce markdown and JSON reports
OpenBrowser includes an MCP (Model Context Protocol) server that exposes browser automation as tools for AI assistants like Claude. Listed on the MCP Registry as me.openbrowser/openbrowser-ai. No external LLM API keys required -- the MCP client provides the intelligence.
By default, each MCP server process uses an isolated profile under ~/.config/openbrowser/profiles/mcp-<instance-id>. Its storage_state.json is seeded once from ~/.config/openbrowser/profiles/default/storage_state.json, so existing logins are available without allowing concurrent MCP servers to kill or corrupt one another's browser. The per-process profile is retained on disk but is not automatically reused by a later MCP process. Configure OPENBROWSER_USER_DATA_DIR for a profile that survives restarts; OPENBROWSER_STORAGE_STATE is a one-time seed for managed profiles, and later changes are saved to the active per-process copy rather than copied back automatically. OpenBrowser also auto-cleans disposable Chromium caches in managed profiles, which keeps disk usage down without deleting cookies or login state. If you explicitly configure the same OPENBROWSER_USER_DATA_DIR for multiple servers, the profile lease rejects the second owner with a clear error.
The MCP server exposes a single execute_code tool that runs Python code in a persistent namespace with browser automation functions. The LLM writes Python code to navigate, interact, and extract data, returning only what was explicitly requested.
evaluate(code): run JS in page context, returns Python objects
Downloads
download_file(url, filename): download a file using browser cookies, list_downloads(): list downloaded files (sync, no await)
State
browser.get_browser_state_summary(): get page metadata and interactive elements
CSS
get_selector_from_index(index): get CSS selector for an element
Completion
done(text, success): signal task completion
Prefer indexed actions whenever an element index exists. Coordinate actions use CSS viewport pixels, not screenshot pixels. If a screenshot uses a devicePixelRatio other than 1, divide its coordinates by window.devicePixelRatio before calling an *_xy function.
Four CLI tools compared with a single Bash tool each. Claude Sonnet 4.6 on Bedrock. Randomized order. All achieve 100% accuracy.
CLI Tool
Duration (mean +/- std)
Tool Calls
Bedrock API Tokens
Response Chars
openbrowser-ai
84.8 +/- 10.9s
15.3 +/- 2.3
36,010 +/- 6,063
9,452 +/- 472
browser-use
106.0 +/- 9.5s
20.7 +/- 6.4
77,123 +/- 33,354
36,241 +/- 12,940
agent-browser
99.0 +/- 6.8s
25.0 +/- 4.0
90,107 +/- 3,698
56,009 +/- 39,733
playwright-cli
118.3 +/- 21.4s
25.7 +/- 8.1
94,130 +/- 35,982
84,065 +/- 49,713
openbrowser-ai uses 2.1-2.6x fewer tokens than all competitors via Python code batching and compact DOM representation.
Per-Task Token Usage
Task
openbrowser-ai
browser-use
playwright-cli
agent-browser
fact_lookup
2,504
4,710
16,857
9,676
form_fill
7,887
15,811
31,757
19,226
multi_page_extract
2,354
2,405
8,886
8,117
search_navigate
16,539
47,936
27,779
44,367
deep_navigation
2,178
3,747
4,705
5,534
content_analysis
4,548
2,515
4,147
3,189
openbrowser-ai wins 5 of 6 tasks. The advantage is largest on complex pages (search_navigate: 2.9x fewer tokens than browser-use) where code batching avoids repeated page state dumps.
# Run a browser automation task with an LLM agent
uvx openbrowser-ai -p "Search for Python tutorials on Google"# Execute code directly via persistent daemon
uvx openbrowser-ai -c "await navigate('https://example.com')"
uvx openbrowser-ai -c "print(await evaluate('document.title'))"# Daemon management
uvx openbrowser-ai daemon start # Start daemon (auto-starts on first -c call)
uvx openbrowser-ai daemon stop # Stop daemon and browser
uvx openbrowser-ai daemon status # Show daemon info
uvx openbrowser-ai daemon restart # Restart daemon# Install browser
uvx openbrowser-ai install
# Run MCP server
uvx openbrowser-ai --mcp
The -c flag connects to a persistent browser daemon over a Unix socket (localhost TCP on Windows). Variables persist across calls while the daemon is running. The daemon starts automatically on first use and shuts down after 10 minutes of inactivity.
The CLI daemon stores its browser profile in ~/.config/openbrowser/profiles/daemon and also writes storage_state.json there, so cookies and login sessions survive daemon restarts. One-shot -p runs use ~/.config/openbrowser/profiles/cli with the same storage-state behavior. Managed profiles automatically clear disposable browser caches on startup and shutdown while keeping auth state.
# Run unit tests
pytest tests/
# Run with verbose output
pytest tests/ -v
# E2E test the MCP server against the published PyPI package
uv run python benchmarks/e2e_published_test.py
Benchmarks
Run individual MCP server benchmarks (JSON-RPC stdio, 5-step Wikipedia workflow):
bash
uv run python benchmarks/openbrowser_benchmark.py # OpenBrowser MCP
uv run python benchmarks/playwright_benchmark.py # Playwright MCP
uv run python benchmarks/cdp_benchmark.py # Chrome DevTools MCP
The project includes a FastAPI backend and a Next.js frontend, both containerized with Docker.
Prerequisites
Docker and Docker Compose
A .env file in the project root with POSTGRES_PASSWORD and any LLM API keys (see backend/env.example)
Local Development (Docker Compose)
bash
# Start backend + PostgreSQL (frontend runs locally)
docker-compose -f docker-compose.dev.yml up --build
# In a separate terminal, start the frontendcd frontend && npm install && npm run dev
The dev compose mounts backend/app/ and src/ as volumes for hot-reload. API keys are loaded from backend/.env via env_file. The POSTGRES_PASSWORD is read from the root .env file.
Full Stack (Docker Compose)
bash
# Start all services (backend + frontend + PostgreSQL)
docker-compose up --build
This builds and runs both the backend and frontend containers together with PostgreSQL.
Backend
The backend is a FastAPI application in backend/ with a Dockerfile at backend/Dockerfile. It includes:
REST API on port 8000
WebSocket endpoint at /ws for real-time agent communication
VNC support (Xvfb + x11vnc + websockify) for live browser viewing on ports 6080-6090
The frontend is a Next.js application in frontend/ with a Dockerfile at frontend/Dockerfile.
bash
# Build the frontend imagecd frontend && docker build -t openbrowser-frontend .
# Run standalone
docker run -p 3000:3000 \
-e NEXT_PUBLIC_API_URL=http://localhost:8000 \
-e NEXT_PUBLIC_WS_URL=ws://localhost:8000/ws \
openbrowser-frontend
Environment Variables
Key environment variables for the backend (see backend/env.example for the full list):
Variable
Description
Default
GOOGLE_API_KEY
Google/Gemini API key
(required)
DEFAULT_LLM_MODEL
Default model for agents
gemini-3-flash-preview
AUTH_ENABLED
Enable Cognito JWT auth
false
VNC_ENABLED
Enable VNC browser viewing
true
DATABASE_URL
PostgreSQL connection string
(optional)
POSTGRES_PASSWORD
PostgreSQL password (root .env)
(required for compose)
Research: Reinforcement Fine-Tuning for Browser Agents
Beyond the framework, we conducted two independent research studies on improving browser agents through reinforcement learning, both using the FormFactory benchmark (1,250 form-filling tasks across 8 domains) and OpenBrowser's browser execution environment.
Study 1: Browser-in-the-Loop (Autoregressive RL)
We investigated whether reinforcement learning can improve a language model's ability to fill web forms beyond what supervised learning achieves.
Method: Two-phase pipeline -- SFT on Qwen3-8B with QLoRA (992 demonstrations), then online GRPO with live browser execution rewards (composite: 40% submission success + 40% field accuracy + 20% execution completeness)
Result: GRPO achieves 9.1% higher average reward than SFT alone on held-out validation (p=0.007, Wilcoxon signed-rank test). Improvement comes specifically from better form submission, not field filling.
Key finding: SFT is a prerequisite -- without it, the base model generates unstructured text and earns zero reward across all attempts.
Study 2: Diffusion Language Models for Web Action Planning
We investigated whether diffusion language models -- which generate text by iteratively denoising an entire sequence in parallel rather than left-to-right -- can learn web action planning.
Models tested: ReFusion 8B (masked diffusion with causal LM backbone) and FS-DFM 1.3B (pure discrete flow matching)
Result: After SFT, diffusion models solve 60-69% of tasks vs. 100% for the AR baseline. Token-level RL is universally fragile (2/16 comparisons improve, both insignificant). Sequence-level RL succeeds: MDPO pushes ReFusion to 91.9% (+31.4pp) and ESPO pushes FS-DFM to 87.1% (+18.6pp).
Key finding: The appropriate RL formulation is architecture-dependent. ELBO-based optimization (ESPO) produces concentrated distributions across architectures, while per-step trajectory methods produce multimodal distributions.
All training code is in infra/training/. Training runs on a single NVIDIA A10G GPU (24GB VRAM) via Anyscale.
bash
# Study 1: Autoregressive RL (Qwen3-8B)# SFT phase -- QLoRA fine-tuning on 992 FormFactory demonstrations (2-4 hours)
python infra/training/finetuning/sft_trainer.py
# Online GRPO phase -- browser-in-the-loop reward (4-8 hours per epoch)# Requires headless Chromium + FormFactory forms server
python infra/training/shared/formfactory_server.py & # Start form server
python infra/training/finetuning/online_grpo_trainer.py
# Evaluate SFT and GRPO checkpoints on val/test splits
python infra/training/finetuning/eval_sft.py
# Study 2: Diffusion LM RL (ReFusion 8B, FS-DFM 1.3B)# SFT phase
python infra/training/flow_matching/fsdfm_sft_trainer.py # FS-DFM SFT
python infra/training/flow_matching/flow_sft_trainer.py # ReFusion SFT# Sequence-level RL (best results)
python infra/training/flow_matching/espo_fsdfm_trainer.py # ESPO on FS-DFM
python infra/training/flow_matching/espo_refusion_trainer.py # ESPO on ReFusion
python infra/training/flow_matching/mdpo_fsdfm_trainer.py # MDPO on FS-DFM
python infra/training/flow_matching/mdpo_refusion_trainer.py # MDPO on ReFusion# Submit jobs to Anyscale cloud
python infra/training/anyscale/submit_job.py --config infra/training/anyscale/online_grpo_job.yaml
# Push trained checkpoints to HuggingFace
python infra/training/anyscale/push_checkpoints_to_hf.py
# Serve trained model locally via vLLM or Ollama
python infra/training/serving/serve_vllm.py
python infra/training/serving/export_gguf.py # Export to GGUF for Ollama
Reward function (in infra/training/shared/reward_functions.py): composite score = 0.4 * task completion + 0.4 * field accuracy + 0.2 * execution completeness. Online reward (online_reward.py) launches headless Chromium, executes the model's action plan, and computes the score from live browser state.
Contributing
Contributions are welcome! Please:
Fork the repository
Create a feature branch (git checkout -b feature/amazing-feature)
Commit your changes (git commit -m 'Add amazing feature')
Push to the branch (git push origin feature/amazing-feature)
Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Comma-separated list of allowed domains (empty for no restrictions)
OPENBROWSER_USER_DATA_DIR
Optional explicit Chrome profile directory. Omit for an isolated profile per MCP server instance; concurrent owners of one explicit profile are rejected
OPENBROWSER_STORAGE_STATE
Optional JSON file used as a one-time seed for cookies plus localStorage in managed MCP profiles; later updates are saved to the active profile copy
OPENBROWSER_COMPACT_DESCRIPTIONdefault false
Use minimal tool description (~500 tokens instead of ~1,430)
OPENBROWSER_MAX_OUTPUTdefault 10000
Maximum output characters per code execution (default: 10000)