{
  "markdown": "# Pagerunner\n\n<p align=\"center\">\n  <a href=\"https://github.com/Enreign/pagerunner/actions/workflows/ci.yml\"><img src=\"https://github.com/Enreign/pagerunner/actions/workflows/ci.yml/badge.svg\" alt=\"CI\"></a>\n  <a href=\"https://github.com/Enreign/pagerunner/releases/latest\"><img src=\"https://img.shields.io/github/v/release/Enreign/pagerunner\" alt=\"Release\"></a>\n  <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/License-MIT-yellow.svg\" alt=\"License: MIT\"></a>\n  <img src=\"https://img.shields.io/badge/rust-1.91%2B-orange\" alt=\"Rust 1.91+\">\n</p>\n\nA 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.\n\n> [!WARNING]\n> Pagerunner is early-stage software (v0.x). APIs and configuration formats may change between releases.\n\n## Contents\n\n- [How it works](#how-it-works)\n- [Setup](#setup)\n- [Using with your project](#using-with-your-project)\n- [Tools](#tools)\n- [Site Intelligence](#site-intelligence)\n- [Session Checkpoints](#session-checkpoints)\n- [macOS Menu Bar App](#macos-menu-bar-app)\n- [Anonymization (PII protection)](#anonymization-pii-protection)\n- [Stealth mode](#stealth-mode)\n- [Daemon (multiple Claude Code sessions / persistent state)](#daemon-multiple-claude-code-sessions--persistent-state)\n- [Snapshots](#snapshots)\n- [Example session](#example-session)\n- [Legal & Responsible Use](#legal--responsible-use)\n\n## How it works\n\nPagerunner 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.\n\n## Setup\n\n**1. Install**\n\n```bash\n# Option A — Homebrew (easiest on macOS/Linux):\nbrew tap enreign/pagerunner\nbrew install pagerunner\n\n# Option B — Cargo (if you have Rust):\ncargo install pagerunner\n# Note: if you get \"requires rustc 1.91+\" despite having a newer Rust installed,\n# Homebrew's Rust may be shadowing rustup's. Fix: export PATH=\"$HOME/.cargo/bin:$PATH\"\n\n# Option C — Pre-built binary (no dependencies):\n\n# macOS arm64 (Apple Silicon):\ncurl -L https://github.com/Enreign/pagerunner/releases/latest/download/pagerunner-macos-arm64 \\\n  -o pagerunner && chmod +x pagerunner\n\n# macOS x86_64 (Intel):\ncurl -L https://github.com/Enreign/pagerunner/releases/latest/download/pagerunner-macos-x86_64 \\\n  -o pagerunner && chmod +x pagerunner\n\n# Linux x86_64:\ncurl -L https://github.com/Enreign/pagerunner/releases/latest/download/pagerunner-linux-x86_64 \\\n  -o pagerunner && chmod +x pagerunner\n\n# macOS: if Gatekeeper blocks the binary on first run:\nxattr -d com.apple.quarantine pagerunner\n\n# Option B — install via cargo (requires Rust):\ncargo install --git https://github.com/Enreign/pagerunner --locked\n\n# Option C — build locally:\ncargo build --release\n```\n\n**2. Auto-detect Chrome profiles**\n\n```bash\npagerunner init\n```\n\nThis reads Chrome's profile list and writes `~/.pagerunner/config.toml` automatically.\nRun `pagerunner status` to verify.\n\nAlternatively, write `~/.pagerunner/config.toml` by hand — see `pagerunner example-config` for the format.\n\n**3. Register as MCP server**\n\n```bash\n# If installed (Options A or B — binary is in PATH):\nclaude mcp add pagerunner \"$(which pagerunner)\" mcp\n\n# If built locally (Option C):\nclaude mcp add pagerunner \"$(pwd)/target/release/pagerunner\" mcp\n```\n\nFor Claude Desktop, add to `~/Library/Application Support/Claude/claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"pagerunner\": {\n      \"command\": \"/absolute/path/to/pagerunner\",\n      \"args\": [\"mcp\"]\n    }\n  }\n}\n```\n\n> **Note:** The `mcp` subcommand is required — registering just the binary path without `mcp` will not work.\n>\n> **Note:** Chrome locks profile directories. Close any Chrome window using a profile before opening a Pagerunner session on it.\n\n**4. Set up in your project (optional)**\n\nIn any project directory with a `CLAUDE.md` or `AGENTS.md`:\n\n```bash\npagerunner init\n```\n\nPagerunner prints a ready-to-use usage snippet and offers to append it to your project file automatically. For scripting: `pagerunner init --json`.\n\n**5. (Optional, `--features ner` builds only) Download the NER model**\n\n```bash\npagerunner download-model   # ~65MB, enables PERSON/ORG name detection\n```\n\n## Using with your project\n\nCopy the example agent instructions into your project root so Claude (or any agent) immediately knows how to use Pagerunner:\n\n```bash\n# Claude Code projects:\ncurl -sL https://raw.githubusercontent.com/Enreign/pagerunner/main/docs/examples/CLAUDE.md -o CLAUDE.md\n\n# Other agents (Gemini, Codex, etc.):\ncurl -sL https://raw.githubusercontent.com/Enreign/pagerunner/main/docs/examples/AGENTS.md -o AGENTS.md\n```\n\nOr paste the content manually and extend it with project-specific instructions.\n\n## Using Pagerunner with Claude Code\n\nFor comprehensive guidance, workflows, and examples tailored to 4 different use cases, install the **Pagerunner Skill**:\n\n```bash\n# Install the skill (once available in skills.sh registry)\nclaude skill install pagerunner-skill\n```\n\nOr explore the skill repository directly: [pagerunner-skill](https://github.com/Enreign/pagerunner-skill)\n\nThe skill includes:\n- **Quick starts for 4 ICPs:** Solo Developer, Power User, Security-Conscious, Server-Side\n- **11 workflow patterns:** form filling, authentication, scrolling, multi-step interactions\n- **Complete reference:** all 38 tools with parameters and examples\n- **Security guide:** PII anonymization, audit logging, encryption\n- **Real-world examples:** end-to-end workflows with error handling\n- **Troubleshooting:** common issues and solutions\n\nStart with the skill's [SKILL.md](https://github.com/Enreign/pagerunner-skill/blob/main/SKILL.md) to find your use case and quick start path.\n\n## Tools\n\n### Sessions & tabs\n\n| Tool | Description |\n|---|---|\n| `list_profiles` | List configured Chrome profiles |\n| `open_session` | Launch Chrome for a profile, returns `session_id` |\n| `attach_session` | Attach to an existing Chrome instance via `--remote-debugging-port` |\n| `close_session` | Kill a Chrome session |\n| `list_sessions` | List active sessions |\n| `list_tabs` | List open tabs in a session |\n| `new_tab` | Open a new tab, returns `target_id` |\n| `close_tab` | Close a specific tab |\n\n### Navigation & content\n\n| Tool | Description |\n|---|---|\n| `navigate` | Navigate a tab to a URL |\n| `wait_for` | Wait for a CSS selector, URL pattern, or fixed delay |\n| `get_content` | Get visible text content of a tab |\n| `screenshot` | Capture a tab as PNG (saved to temp file or inline base64) |\n| `evaluate` | Run JavaScript in a tab, returns the result |\n\n### Interactions\n\n| Tool | Description |\n|---|---|\n| `click` | Click an element by CSS selector |\n| `type_text` | Type text at the focused element or a given selector |\n| `fill` | Set input value with React/Vue/Angular synthetic events |\n| `select` | Choose a dropdown option by value |\n| `scroll` | Scroll the page by pixels or scroll an element into view |\n\n### Snapshots & tab state\n\n| Tool | Description |\n|---|---|\n| `save_snapshot` | Save current page cookies/localStorage to the encrypted DB |\n| `restore_snapshot` | Restore a saved snapshot into the current tab |\n| `list_snapshots` | List saved snapshots (optionally across all profiles) |\n| `delete_snapshot` | Delete a saved snapshot |\n| `save_tab_state` | Save all open tab URLs to the DB |\n| `restore_tab_state` | Reopen the previously saved tabs |\n\n### Key-value store\n\n| Tool | Description |\n|---|---|\n| `kv_set` | Store a value in a persistent namespace |\n| `kv_get` | Retrieve a value by key |\n| `kv_delete` | Delete a key |\n| `kv_list` | List keys in a namespace (with optional prefix filter) |\n| `kv_clear` | Delete all keys in a namespace |\n\n### Network & console\n\n| Tool | Description |\n|---|---|\n| `get_network_log` | Inspect HTTP requests captured in a session |\n| `get_console_log` | Capture JavaScript console output from a tab |\n\n### Site intelligence\n\n| Tool | Description |\n|---|---|\n| `get_site_knowledge` | Inspect what Pagerunner has learned about a site (adapters, auth tokens, selector health) |\n| `register_adapter` | Store a JS adapter for direct API calls against a site |\n| `call_site_api` | Execute a stored adapter in the browser tab |\n| `generate_adapter` | Auto-generate a JS adapter from network traffic using Claude (requires `ANTHROPIC_API_KEY`) |\n\n### Session checkpoints\n\n| Tool | Description |\n|---|---|\n| `save_session_checkpoint` | Save full tab state (URLs + scroll positions) for all tabs in a session |\n| `restore_session_checkpoint` | Reopen all saved tabs and navigate to stored URLs |\n| `list_session_checkpoints` | List saved checkpoints for a profile |\n| `delete_session_checkpoint` | Remove a checkpoint by ID |\n\n## Site Intelligence\n\nPagerunner learns about sites as you use them and can call site APIs directly using your session credentials — no separate auth setup required.\n\n**Adapters** are short JS functions stored in the encrypted DB and executed in the browser tab. Use them to call APIs that a site exposes (typically the same API the web UI uses):\n\n```\nregister_adapter(origin=\"https://github.com\", name=\"list-issues\",\n  description=\"List open issues for a repo\",\n  js_code=\"async ({owner, repo}) => { const r = await fetch(...); return r.json() }\")\n\ncall_site_api(session_id, target_id, origin=\"https://github.com\",\n  name=\"list-issues\", params={\"owner\": \"Enreign\", \"repo\": \"pagerunner\"})\n```\n\nSeed adapters for GitHub, Linear, Jira, Notion, and Gmail are built in.\n\n**Auth token detection** — Bearer tokens, API keys, and session cookies discovered in network traffic are stored in the encrypted site vault. Adapters automatically have access to them via the `credentials` argument.\n\n**Selector stability** — `click`, `fill`, and `select` track success/failure rates per selector. A fragility warning appears in the tool response when a selector fails >30% of the time over ≥5 uses.\n\n## Session Checkpoints\n\nSave complete browser state (all open tabs with URLs and scroll positions) and restore it in any future session:\n\n```\nsave_session_checkpoint(session_id, name=\"before-review\")\n  → checkpoint_id: cp_abc123\n\nrestore_session_checkpoint(session_id, checkpoint_id=\"cp_abc123\")\n  → reopens all saved tabs at their stored URLs\n```\n\nCheckpoints are stored in the encrypted DB and scoped to a profile.\n\n## macOS Menu Bar App\n\nA native Swift companion app lives at `apps/menubar/`. It shows all Chrome profiles, active sessions, open tabs, and daemon status from the menu bar — no terminal required.\n\n**Features:**\n- One-click open/close sessions and save checkpoints\n- Agent profiles shown with a distinct CPU icon in a separate section\n- Add Profile flow: discovers unconfigured Chrome profiles or creates new agent profiles\n- macOS native notifications: daemon stopped, session crashed, checkpoint saved\n- Global hotkey and auto-update via Sparkle 2.x\n\n**Build and run:**\n\n```bash\npagerunner daemon &\ncd apps/menubar\nbash scripts/package.sh   # builds + bundles into scripts/Pagerunner.app\nopen scripts/Pagerunner.app\n```\n\n## Anonymization (PII protection)\n\nPass `anonymize: true` to `open_session` to strip PII from all `get_content` and `evaluate`\nresults before they reach Claude. Screenshots are blocked in anonymization mode.\n\n```json\n{ \"tool\": \"open_session\", \"profile\": \"personal\", \"anonymize\": true }\n```\n\n**Detected by default:** EMAIL, PHONE, CREDIT_CARD, IBAN, SSN, IP\n**With `--features ner` build:** also detects PERSON and ORG names via a local ONNX model\n\n### Modes\n\n- **tokenize** (default): replaces PII with tokens like `[EMAIL:a3f9b2]`. Pass tokens back to\n  `fill`/`type_text` — Pagerunner de-tokenizes before writing to the DOM.\n- **redact**: one-way replacement with `[EMAIL]` — no vault, no de-tokenization.\n\n### NER setup (PERSON and ORG name detection)\n\n```bash\n# 1. Build with NER support:\ncargo build --release --features ner\n\n# 2. Download the model (one-time, ~65MB):\npagerunner download-model\n```\n\nDisable globally in `~/.pagerunner/config.toml`:\n\n```toml\n[ner]\nenabled = false\n```\n\n## Stealth mode\n\nPass `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.\n\n```json\n{ \"tool\": \"open_session\", \"profile\": \"personal\", \"stealth\": true }\n```\n\n## Example session\n\n```\nopen_session(profile=\"personal\")          → session_id: abc123\nnew_tab(session_id, url=\"https://...\")    → target_id: TAB456\nget_content(session_id, target_id)        → \"page text...\"\nclick(session_id, target_id, \"#button\")\ntype_text(session_id, target_id, \"hello\", selector=\"#input\")\nscreenshot(session_id, target_id)         → \"data:image/png;base64,...\"\nclose_session(session_id)\n```\n\n## Daemon (multiple Claude Code sessions / persistent state)\n\nBy 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.\n\nStart the daemon once to share state across any number of sessions:\n\n```bash\npagerunner daemon &\n```\n\nEach `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.\n\nTo stop:\n\n```bash\npkill -f \"pagerunner daemon\"\n```\n\n**Install as a background service** (starts at login, restarts on crash):\n\n```bash\n./scripts/install-launchd.sh\n```\n\nThe script detects your installed `pagerunner` binary automatically. Logs at `~/.pagerunner/daemon.log`.\n\n> **Note:** After installing the daemon service, restart Claude Code. On the next launch,\n> the daemon starts first (via launchd) and the MCP server connects to it in proxy mode.\n> If Claude Code is already running when you install the daemon, you need two restarts:\n> one to let launchd start the daemon, and one for the MCP server to reconnect to it.\n\n## Snapshots\n\nSave authenticated browser state to the encrypted local DB:\n\n```\nsave_snapshot(session_id, target_id, origin=\"https://github.com\")\n```\n\nRestore it in any future session:\n\n```\nrestore_snapshot(session_id, target_id, origin=\"https://github.com\")\n```\n\nSnapshots are encrypted with AES-256-GCM. The key is stored in macOS Keychain under `pagerunner / db_key` — never written to disk in plaintext.\n\n## Legal & Responsible Use\n\nPagerunner automates a browser you own, using your own credentials. You are responsible for\ncomplying with the Terms of Service of any website you automate, applicable data protection\nlaws (GDPR, CCPA), and authorized-access requirements (CFAA and equivalents).\n\nUsing `anonymize: true` is recommended for any workflow that involves processing personal\ndata belonging to other people.\n\nSee [DISCLAIMER.md](DISCLAIMER.md) for the full legal disclaimer, limitation of liability,\nand responsible use obligations.\n\n---\n\nIf this project helps you, [star the repo](https://github.com/Enreign/pagerunner) — it helps others find it.\n",
  "bytes": 15108,
  "sha": "da223dddc759f7281bf81c8234f588c82502065ec266e3b9ececc52c0817364b",
  "repo_slug": "enreign/pagerunner",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_enreign_pagerunner_34f196a2/readme"
}