Skip to content

buildingopen/openbrowser

Repository files navigation

OpenBrowser

A persistent Chrome instance that AI agents control via Playwright MCP. Log in once, delegate all web tasks to AI. Stop using your browser.

License: MIT ShellCheck

What This Does

You run Chrome with a persistent profile. It stays logged into your accounts: Google, GitHub, LinkedIn, whatever you use. AI coding agents (Claude Code, Cursor, Windsurf, or anything that supports MCP) connect to it through Playwright and can navigate pages, click buttons, fill forms, read content.

You describe what you want in natural language. The agent does it.

"Check my open PRs for new comments"              -> done
"Find hotels in Lisbon, March 15-18, max 120 EUR" -> shortlist with prices
"Go to LinkedIn and summarize my notifications"    -> done

Two Modes

Local Remote
Where Chrome runs Your machine (headless) A Linux server
Setup 3 steps, 2 minutes 7 steps, 10 minutes
Needs a server? No Yes (any VPS with 2GB+ RAM)
Login method Use Chrome normally, then switch to headless VNC one-time login
Best for Trying it out, personal use Always-on, shared across devices

Both modes use the same persistent Chrome profile and CDP protocol. Your agent doesn't know or care which mode you're using.

Quick Start: Local Mode

No server needed. Chrome runs headless on your machine.

1. Clone and install

git clone https://github.com/buildingopen/openbrowser.git
cd openbrowser
./scripts/install-local.sh

This detects your OS, finds Chrome, and starts it as a background service with CDP on localhost:9222.

2. Configure MCP

Add to your Claude Code config (~/.claude.json):

{
  "mcpServers": {
    "openbrowser": {
      "type": "stdio",
      "command": "npx",
      "args": ["@playwright/mcp@latest", "--cdp-endpoint=http://localhost:9222"]
    }
  }
}

For Cursor, add to .cursor/mcp.json. For other MCP clients, consult their docs.

3. Test it

curl http://localhost:9222/json/version
# In Claude Code: "Navigate to github.com and tell me what you see"

Logging into accounts (local mode)

In headless mode there's no visible browser window. To log into your accounts:

./scripts/login-local.sh

This stops the headless service, opens Chrome visually so you can log in, then restarts the service when you close Chrome.

Quick Start: Remote Mode

Chrome runs on a Linux server. You connect through an SSH tunnel.

Your Machine (Claude Code / Cursor / any MCP client)
  |-- Playwright MCP server
      |-- SSH tunnel (autossh, auto-reconnects)
          |-- Remote Server
              |-- Xvfb (virtual display)
                  |-- Chrome (persistent profile, CDP on localhost:9222)
                      |-- Logged into your accounts

1. Server: One-command install

curl -sL https://raw.githubusercontent.com/buildingopen/openbrowser/main/scripts/install-server.sh | sudo bash

Or from a clone:

git clone https://github.com/buildingopen/openbrowser.git /opt/openbrowser
sudo /opt/openbrowser/scripts/install-server.sh

This installs Chrome, Xvfb, x11vnc, deploys the systemd service, and sets up health check and backup cron jobs. Requires an x86_64 server (Google does not publish Chrome for ARM64 Linux).

2. Server: Log into your accounts (one-time)

/opt/openbrowser/scripts/vnc-login.sh

From your local machine:

ssh -L 5900:localhost:5900 your-server
# Open vnc://localhost:5900 in any VNC client
# Log into Google (gives you SSO into GitHub, LinkedIn, etc.)
# Close VNC when done - the session auto-terminates

3. Local: Set up persistent tunnel

./scripts/setup-tunnel.sh your-server

This installs autossh as a system service (launchd on macOS, systemd on Linux) that auto-reconnects.

Or manually:

autossh -M 0 -N -L 9222:localhost:9222 your-server

4. Local: Configure MCP

Same as local mode:

{
  "mcpServers": {
    "openbrowser": {
      "type": "stdio",
      "command": "npx",
      "args": ["@playwright/mcp@latest", "--cdp-endpoint=http://localhost:9222"]
    }
  }
}

5. Test it

curl http://localhost:9222/json/version
# In Claude Code: "Navigate to github.com and tell me what you see"

Docker

Run Chrome headless in a container with a persistent profile volume.

git clone https://github.com/buildingopen/openbrowser.git
cd openbrowser
docker compose up -d

CDP is exposed on localhost:9222. Use the same MCP config as above.

# Verify
curl http://localhost:9222/json/version

The chrome-profile volume persists across container restarts, so your logins survive.

Security note: CDP has no authentication. The compose file binds to 127.0.0.1 only, but other containers on the same Docker network can reach CDP directly. Do not place OpenBrowser on a shared network with untrusted containers.

Verification

Run the verification script to check your setup:

./scripts/verify.sh

It checks: Chrome binary, profile directory, CDP connectivity, running services, and MCP configuration.

Uninstall

./scripts/uninstall.sh

Stops services, removes service files and cron entries. Asks before deleting the Chrome profile. Does not uninstall Chrome itself.

Health Checks and Backups

The server install script sets these up automatically. For manual setup:

# Health check every 5 minutes (restarts Chrome if unresponsive)
(crontab -l 2>/dev/null; echo "*/5 * * * * /opt/openbrowser/scripts/session-check.sh") | crontab -

# Daily profile backup at 3am (keeps 7 days)
(crontab -l 2>/dev/null; echo "0 3 * * * /opt/openbrowser/scripts/backup-profile.sh") | crontab -

Restore from backup

systemctl stop openbrowser
tar xzf /opt/openbrowser/backups/chrome-profile-YYYYMMDD.tar.gz -C ~/.config/
systemctl start openbrowser

2FA Automation

If your accounts use TOTP-based 2FA (datacenter IPs often trigger re-verification):

echo "YOUR_TOTP_SECRET" > ~/.config/openbrowser/.totp-secret
chmod 600 ~/.config/openbrowser/.totp-secret

# Generate a code
/opt/openbrowser/scripts/generate-totp.sh

Troubleshooting

CDP not responding (curl: (7) Failed to connect)

  • Local mode: check service is running (launchctl list | grep openbrowser on macOS, systemctl --user status openbrowser-local on Linux)
  • Remote mode: check the SSH tunnel (ps aux | grep autossh) and server service (systemctl status openbrowser)
  • Docker: docker compose logs openbrowser
  • Check if something else is on port 9222: lsof -i :9222

Session expired (Google/LinkedIn asks to log in again)

  • Google sessions expire after ~30 days on trusted devices, sooner from datacenter IPs
  • Remote mode: re-run scripts/vnc-login.sh and log in again via VNC
  • Local mode: ./scripts/login-local.sh
  • Set up TOTP automation (see 2FA Automation) to handle re-verification prompts

Chrome crashes or high memory

  • Check shared memory: Chrome needs adequate /dev/shm (Docker: shm_size: 2gb)
  • Check available RAM: Chrome with a few tabs uses 500MB-1GB
  • Remote mode: check journalctl -u openbrowser --no-pager -n 50

MCP not connecting

  • Run ./scripts/verify.sh to check all components
  • Verify your MCP config points to http://localhost:9222 (not https)
  • Restart your MCP client after config changes

Configuration

All scripts use environment variables with sensible defaults. See env.example for the full list.

Rate Limits

If you're automating interactions with services like LinkedIn, respect their rate limits. See rate-limits.example.json for recommended thresholds.

Security

  • No ports exposed to the internet. CDP only listens on 127.0.0.1. Access is exclusively through SSH (remote mode) or localhost (local/Docker mode).
  • VNC is ephemeral. The login script uses -once, which auto-terminates after the first disconnect.
  • TOTP secrets are outside the Chrome profile and excluded from git via .gitignore.
  • Profile backups stay on the server. They exclude cache directories to minimize size.
  • Chrome updates are pinned (server mode) to prevent auto-updates from breaking authenticated sessions.
  • Docker uses a non-root user and dedicated shared memory allocation.
  • Server mode runs as root by default. Acceptable for single-purpose VPS setups. On shared servers, create a dedicated user and set User= in the systemd service. See SECURITY.md for details.

File Structure

openbrowser/
  scripts/
    chrome-launcher.sh         # Chrome with Xvfb and CDP (remote/server mode)
    chrome-launcher-local.sh   # Chrome headless with CDP (local mode)
    install-server.sh          # One-command server setup
    install-local.sh           # One-command local setup
    login-local.sh             # Log into accounts in local mode
    setup-tunnel.sh            # Persistent SSH tunnel setup (remote mode)
    verify.sh                  # Health verification
    uninstall.sh               # Clean removal
    session-check.sh           # Health check, restarts on failure
    backup-profile.sh          # Daily profile backup
    vnc-login.sh               # One-time VNC for manual login (remote)
    generate-totp.sh           # TOTP code generation for 2FA
  systemd/
    openbrowser.service        # Chrome systemd service (server)
    openbrowser-local.service  # Chrome systemd service (local Linux, template)
    cdp-tunnel.service         # SSH tunnel systemd service (template)
  launchd/
    com.openbrowser.local.plist        # Chrome launchd service (local macOS, template)
    com.openbrowser.cdp-tunnel.plist   # SSH tunnel launchd (macOS, template)
  Dockerfile                   # Docker image
  docker-compose.yml           # Docker Compose config
  env.example                  # Configuration reference
  rate-limits.example.json     # Rate limit guidelines
  SECURITY.md                  # Security policy

Why Not Just Use APIs?

The browser is the universal API. Every web service already works with it.

  • Most apps don't expose everything via API (LinkedIn, Booking.com, airline sites)
  • APIs require individual auth setup, rate limit management, pagination handling
  • One Google login gives you OAuth SSO into dozens of services
  • If you can see it on screen, the agent can interact with it

Compatible Tools

Anything that supports MCP or CDP:

Contributing

See CONTRIBUTING.md.

License

MIT

About

A persistent Chrome instance on a remote server that AI agents control via Playwright MCP. Log in once, delegate all web tasks to AI. Stop using your browser.

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors