Skip to main content
Glama
rschiefer
by rschiefer
README.md
# browser-auth-mcp

An MCP server that gives your AI agent a real Chromium browser for authentication workflows. Navigate, screenshot, fill forms, handle captchas with human-in-the-loop, and persist login sessions.

## Why this exists

Most sites block headless browsers. This server runs a **real Chromium** instance (using Xvfb on Linux for headed mode), with stealth patches to avoid fingerprinting, human-like mouse movement, and per-character typing delays. Your agent can log in to sites the same way a human would.

For captchas and 2FA — the agent calls `screenshot()` to see what's on screen, then you (the human) interact directly via the companion web UI while the agent waits.

## MCP Tools

| Tool | Description |
|------|-------------|
| `navigate(url)` | Navigate to a URL, wait for JS challenges |
| `screenshot()` | Capture current page as JPEG image |
| `get_page_text()` | Get visible text content |
| `get_fields()` | Detect all form fields (including Shadow DOM) |
| `fill_fields(fields, submit)` | Fill fields with human-like typing |
| `click(x, y)` | Click at coordinates with Bezier mouse movement |
| `press_key(key)` | Press a keyboard key |
| `scroll(delta_y)` | Scroll the page |
| `evaluate_js(script)` | Run JavaScript in page context |
| `save_session(site)` | Save cookies/localStorage for later |
| `load_session(site)` | Restore a saved login session |
| `list_sessions()` | List saved sessions |
| `delete_session(site)` | Delete a session |

## Quick Start

### Option 1: Docker (recommended)

```bash
docker compose up -d
```

Then configure your MCP client:
```json
{
  "mcpServers": {
    "browser-auth": {
      "type": "sse",
      "url": "http://localhost:8080/sse"
    }
  }
}
```

### Option 2: Local Python

```bash
pip install -r requirements.txt
playwright install chromium  # or use system Chromium

# stdio transport (Claude Desktop / Claude Code)
python server.py

# HTTP/SSE transport (remote access)
python server.py --http 8080
```

**Claude Desktop** (`~/.claude/claude_desktop_config.json`):
```json
{
  "mcpServers": {
    "browser-auth": {
      "command": "python",
      "args": ["/path/to/browser-auth-mcp/server.py"]
    }
  }
}
```

**Claude Code** (`.mcp.json` in project root):
```json
{
  "mcpServers": {
    "browser-auth": {
      "command": "python",
      "args": ["/path/to/browser-auth-mcp/server.py"],
      "type": "stdio"
    }
  }
}
```

## Example Agent Workflow

```
You: Log in to Reddit and save the session.

Agent:
1. navigate("https://www.reddit.com/login/")
2. screenshot()        → sees login form
3. get_fields()        → finds username + password selectors
4. fill_fields([
     {"selector": "[name='username']", "value": "myuser"},
     {"selector": "[name='password']", "value": "mypass"}
   ], submit=True)
5. screenshot()        → confirms logged in (or sees 2FA prompt)
6. save_session("reddit")
→ Future runs call load_session("reddit") to skip login entirely.
```

## Anti-Detection Features

- **Headed Chrome via Xvfb** — no headless flag, avoids most bot detection
- **playwright-stealth** — patches `navigator.webdriver`, fingerprinting APIs
- **Bezier curve mouse movement** — human-like cursor paths
- **Per-character typing delays** — random intervals between keystrokes
- **Shadow DOM field detection** — finds inputs inside web components (React, etc.)

## Session Persistence

Sessions are stored in `data/sessions/` (override with `SESSIONS_DIR` env var). Each file contains cookies and localStorage. Mount as a Docker volume to persist across restarts.

## Security Notes

- SSRF protection: private IPs, loopback, and dangerous URL schemes are blocked
- Sessions contain cookies — treat `data/sessions/` like a password store
- Intended for use with your own accounts and authorized testing only

## Requirements

- Python 3.11+
- Chromium (system package or via `playwright install chromium`)
- Xvfb (optional, Linux only — enables headed Chrome mode)

## License

MIT