Pagerunner
A Chrome browser automation MCP server. Connect Claude (or any MCP client) to a real Chrome session — using your existing profiles with their cookies, saved passwords, and history.
[!WARNING] Pagerunner is early-stage software (v0.x). APIs and configuration formats may change between releases.
Contents
- How it works
- Setup
- Using with your project
- Tools
- Anonymization (PII protection)
- Stealth mode
- Daemon (multiple Claude Code sessions / persistent state)
- Snapshots
- Example session
- Legal & Responsible Use
How it works
Pagerunner launches Chrome with your existing user profile via CDP (Chrome DevTools Protocol) and exposes it as an MCP server over stdin/stdout. Claude can then navigate, click, type, screenshot, and run JavaScript in the live browser.
Setup
1. Install
# Option A — Homebrew (easiest on macOS/Linux):
brew tap enreign/pagerunner
brew install pagerunner
# Option B — Cargo (if you have Rust):
cargo install pagerunner
# Option C — Pre-built binary (no dependencies):
# macOS arm64 (Apple Silicon):
curl -L https://github.com/Enreign/pagerunner/releases/latest/download/pagerunner-macos-arm64 \
-o pagerunner && chmod +x pagerunner
# macOS x86_64 (Intel):
curl -L https://github.com/Enreign/pagerunner/releases/latest/download/pagerunner-macos-x86_64 \
-o pagerunner && chmod +x pagerunner
# Linux x86_64:
curl -L https://github.com/Enreign/pagerunner/releases/latest/download/pagerunner-linux-x86_64 \
-o pagerunner && chmod +x pagerunner
# macOS: if Gatekeeper blocks the binary on first run:
xattr -d com.apple.quarantine pagerunner
# Option B — install via cargo (requires Rust):
cargo install --git https://github.com/Enreign/pagerunner --locked
# Option C — build locally:
cargo build --release
2. Auto-detect Chrome profiles
pagerunner init
This reads Chrome's profile list and writes ~/.pagerunner/config.toml automatically.
Run pagerunner status to verify.
Alternatively, write ~/.pagerunner/config.toml by hand — see pagerunner example-config for the format.
3. Register as MCP server
# If installed (Options A or B — binary is in PATH):
claude mcp add pagerunner "$(which pagerunner)" mcp
# If built locally (Option C):
claude mcp add pagerunner "$(pwd)/target/release/pagerunner" mcp
For Claude Desktop, add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"pagerunner": {
"command": "/absolute/path/to/pagerunner",
"args": ["mcp"]
}
}
}
Note: The
mcpsubcommand is required — registering just the binary path withoutmcpwill not work.Note: Chrome locks profile directories. Close any Chrome window using a profile before opening a Pagerunner session on it.
4. (Optional, --features ner builds only) Download the NER model
pagerunner download-model # ~65MB, enables PERSON/ORG name detection
Using with your project
Copy the example agent instructions into your project root so Claude (or any agent) immediately knows how to use Pagerunner:
# Claude Code projects:
curl -sL https://raw.githubusercontent.com/Enreign/pagerunner/main/docs/examples/CLAUDE.md -o CLAUDE.md
# Other agents (Gemini, Codex, etc.):
curl -sL https://raw.githubusercontent.com/Enreign/pagerunner/main/docs/examples/AGENTS.md -o AGENTS.md
Or paste the content manually and extend it with project-specific instructions.
Using Pagerunner with Claude Code
For comprehensive guidance, workflows, and examples tailored to 4 different use cases, install the Pagerunner Skill:
# Install the skill (once available in skills.sh registry)
claude skill install pagerunner-skill
Or explore the skill repository directly: pagerunner-skill
The skill includes:
- Quick starts for 4 ICPs: Solo Developer, Power User, Security-Conscious, Server-Side
- 11 workflow patterns: form filling, authentication, scrolling, multi-step interactions
- Complete reference: all 27 tools with parameters and examples
- Security guide: PII anonymization, audit logging, encryption
- Real-world examples: end-to-end workflows with error handling
- Troubleshooting: common issues and solutions
Start with the skill's SKILL.md to find your use case and quick start path.
Tools
Sessions & tabs
| Tool | Description |
|---|---|
list_profiles | List configured Chrome profiles |
open_session | Launch Chrome for a profile, returns session_id |
close_session | Kill a Chrome session |
list_sessions | List active sessions |
list_tabs | List open tabs in a session |
new_tab | Open a new tab, returns target_id |
Navigation & content
| Tool | Description |
|---|---|
navigate | Navigate a tab to a URL |
wait_for | Wait for a CSS selector, URL pattern, or fixed delay |
get_content | Get visible text content of a tab |
screenshot | Capture a tab as PNG (saved to temp file or inline base64) |
evaluate | Run JavaScript in a tab, returns the result |
Interactions
| Tool | Description |
|---|---|
click | Click an element by CSS selector |
type_text | Type text at the focused element or a given selector |
fill | Set input value with React/Vue/Angular synthetic events |
select | Choose a dropdown option by value |
scroll | Scroll the page by pixels or scroll an element into view |
Snapshots & tab state
| Tool | Description |
|---|---|
save_snapshot | Save current page cookies/localStorage to the encrypted DB |
restore_snapshot | Restore a saved snapshot into the current tab |
list_snapshots | List saved snapshots (optionally across all profiles) |
delete_snapshot | Delete a saved snapshot |
save_tab_state | Save all open tab URLs to the DB |
restore_tab_state | Reopen the previously saved tabs |
Key-value store
| Tool | Description |
|---|---|
kv_set | Store a value in a persistent namespace |
kv_get | Retrieve a value by key |
kv_delete | Delete a key |
kv_list | List keys in a namespace (with optional prefix filter) |
kv_clear | Delete all keys in a namespace |
Anonymization (PII protection)
Pass anonymize: true to open_session to strip PII from all get_content and evaluate
results before they reach Claude. Screenshots are blocked in anonymization mode.
{ "tool": "open_session", "profile": "personal", "anonymize": true }
Detected by default: EMAIL, PHONE, CREDIT_CARD, IBAN, SSN, IP
With --features ner build: also detects PERSON and ORG names via a local ONNX model
Modes
- tokenize (default): replaces PII with tokens like
[EMAIL:a3f9b2]. Pass tokens back tofill/type_text— Pagerunner de-tokenizes before writing to the DOM. - redact: one-way replacement with
[EMAIL]— no vault, no de-tokenization.
NER setup (PERSON and ORG name detection)
# 1. Build with NER support:
cargo build --release --features ner
# 2. Download the model (one-time, ~65MB):
pagerunner download-model
Disable globally in ~/.pagerunner/config.toml:
[ner]
enabled = false
Stealth mode
Pass stealth: true to open_session to enable anti-detection: hides automation signals, injects scripts to mask navigator.webdriver, and adds human-like delays between inputs.
{ "tool": "open_session", "profile": "personal", "stealth": true }
Example session
open_session(profile="personal") → session_id: abc123
new_tab(session_id, url="https://...") → target_id: TAB456
get_content(session_id, target_id) → "page text..."
click(session_id, target_id, "#button")
type_text(session_id, target_id, "hello", selector="#input")
screenshot(session_id, target_id) → "data:image/png;base64,..."
close_session(session_id)
Daemon (multiple Claude Code sessions / persistent state)
By default each pagerunner mcp process opens the database directly — only one can run at a time. If you open Pagerunner in a second Claude Code window you'll hit a DB lock error.
Start the daemon once to share state across any number of sessions:
pagerunner daemon &
Each pagerunner mcp instance automatically detects the daemon, connects to it over a Unix socket (~/.pagerunner/daemon.sock), and proxies all tool calls through it. All Claude Code windows share the same open browsers, KV store, and snapshots.
To stop:
pkill -f "pagerunner daemon"
Install as a background service (starts at login, restarts on crash):
cargo build --release
./scripts/install-launchd.sh
Logs at ~/.pagerunner/daemon.log.
Snapshots
Save authenticated browser state to the encrypted local DB:
save_snapshot(session_id, target_id, origin="https://github.com")
Restore it in any future session:
restore_snapshot(session_id, target_id, origin="https://github.com")
Snapshots are encrypted with AES-256-GCM. The key is stored in macOS Keychain under pagerunner / db_key — never written to disk in plaintext.
Legal & Responsible Use
Pagerunner automates a browser you own, using your own credentials. You are responsible for complying with the Terms of Service of any website you automate, applicable data protection laws (GDPR, CCPA), and authorized-access requirements (CFAA and equivalents).
Using anonymize: true is recommended for any workflow that involves processing personal
data belonging to other people.
See DISCLAIMER.md for the full legal disclaimer, limitation of liability, and responsible use obligations.