{"id":50909029,"url":"https://github.com/ivalsaraj/browserforce","last_synced_at":"2026-06-16T08:02:02.306Z","repository":{"id":340074317,"uuid":"1163512803","full_name":"ivalsaraj/browserforce","owner":"ivalsaraj","description":"Give AI agents your real Chrome browser — fully autonomous, no manual tab clicking. Works with OpenClaw, Claude, and any MCP agent.","archived":false,"fork":false,"pushed_at":"2026-03-17T08:27:03.000Z","size":1516,"stargazers_count":5,"open_issues_count":1,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-17T22:37:44.125Z","etag":null,"topics":["ai-agent","browser-automation","browserforce","cdp","chrome","chrome-devtools-protocol","chrome-extension","mcp","openclaw","playwright"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ivalsaraj.png","metadata":{"files":{"readme":"README.frontpage.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-02-21T18:41:00.000Z","updated_at":"2026-03-17T08:27:07.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ivalsaraj/browserforce","commit_stats":null,"previous_names":["ivalsaraj/browserforce"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ivalsaraj/browserforce","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivalsaraj%2Fbrowserforce","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivalsaraj%2Fbrowserforce/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivalsaraj%2Fbrowserforce/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivalsaraj%2Fbrowserforce/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ivalsaraj","download_url":"https://codeload.github.com/ivalsaraj/browserforce/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivalsaraj%2Fbrowserforce/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34396430,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-16T02:00:06.860Z","response_time":126,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agent","browser-automation","browserforce","cdp","chrome","chrome-devtools-protocol","chrome-extension","mcp","openclaw","playwright"],"created_at":"2026-06-16T08:02:01.249Z","updated_at":"2026-06-16T08:02:02.283Z","avatar_url":"https://github.com/ivalsaraj.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# BrowserForce // Parallel AI Agents in \"your\" Browser!\n\nGive AI agents controlled access to the browser you already use.\n\n\u003e \"a lion doesn't concern itself with token counting\" — [@steipete](https://x.com/steipete), creator of [OpenClaw](https://github.com/openclaw/openclaw)\n\u003e\n\u003e \"a 10x user doesn't concern itself with sandboxed browsers // sandboxes are for kids\" — BrowserForce, your friendly neighborhood power source.\n\n**You're giving an AI your real Chrome — your logins, cookies, and sessions. That takes conviction.**\nBrowserForce is built for people who use the best models and don't look back.\n\n**Autonomous when you want it, controlled when you need it.**\nRun hands-off in Auto mode, or switch to Manual mode and explicitly attach only the tabs you trust.\n\nWorks with [OpenClaw](https://github.com/openclaw/openclaw), Claude, Codex, Cursor, or any MCP-compatible agent.\n\n## Why BrowserForce\n\n|                | Playwright MCP       | OpenClaw Browser        | Playwriter              | Claude Extension     | BrowserForce                         |\n| -------------- | -------------------- | ----------------------- | ----------------------- | -------------------- | ------------------------------------ |\n| Browser        | Spawns new Chrome    | Separate profile        | Your Chrome             | Your Chrome          | **Your Chrome**                      |\n| Login state    | Fresh                | Fresh (isolated)        | Yours                   | Yours                | **Yours**                            |\n| Tab access     | N/A (new browser)    | Managed by agent        | Click each tab          | Click each tab       | **Auto mode + manual attached tabs** |\n| Autonomous     | Yes                  | Yes                     | No (manual click)       | No (manual click)    | **Yes (fully autonomous)**           |\n| Context method | Screenshots (100KB+) | Screenshots + snapshots | A11y snapshots (5-20KB) | Screenshots (100KB+) | **A11y snapshots (5-20KB)**          |\n| Tools          | Many dedicated       | 1 `browser` tool        | 1 `execute` tool        | Built-in             | **2 tools: `execute`, `reset`**      |\n| Agent support  | Any MCP client       | OpenClaw only           | Any MCP client          | Claude only          | **Any MCP client**                   |\n| Playwright API | Partial              | No                      | Full                    | No                   | **Full**                             |\n\n## 60-Second Start (MCP-First)\n\n1. Install:\n\n```bash\nnpm install -g browserforce\n```\n\n2. Install extension files:\n\n```bash\nbrowserforce install-extension\n```\n\n3. Load extension in `chrome://extensions` -\u003e Developer mode -\u003e Load unpacked -\u003e use path printed by command.\n\n4. Start relay:\n\n```bash\nbrowserforce serve\n```\n\n5. In your MCP client config, run BrowserForce via npm:\n\n```json\n{\n  \"command\": \"npx\",\n  \"args\": [\"-y\", \"browserforce@latest\", \"mcp\"]\n}\n```\n\n## Critical Reliability Notes (for MCP users)\n\n- MCP reads CDP URL from `~/.browserforce/cdp-url` unless `BF_CDP_URL` is set.\n- If multiple relay processes run on different ports, MCP may connect to the wrong relay.\n- Single-active mode is default (`BF_CLIENT_MODE=single-active`): a second client can get `409` while slot is busy.\n\nQuick checks:\n\n```bash\ncat ~/.browserforce/cdp-url\ncurl -s http://127.0.0.1:19222/ | jq\ncurl -s http://127.0.0.1:19222/client-slot | jq\necho \"${BF_CDP_URL:-\u003cunset\u003e}\"\n```\n\nIf you hit `Protocol error (Target.createTarget): Extension not connected`:\n\n```bash\nlsof -tiTCP:19222 -sTCP:LISTEN | xargs kill -9 2\u003e/dev/null || true\nlsof -tiTCP:19888 -sTCP:LISTEN | xargs kill -9 2\u003e/dev/null || true\nunset BF_CDP_URL\nRELAY_PORT=19222 npx -y browserforce@latest serve\n```\n\n## Security in Plain English\n\n- Relay binds to `127.0.0.1` only.\n- Extension origin is validated (`chrome-extension://...`).\n- CDP uses auth token in URL query.\n- Token file permissions are owner-only.\n- You can lock URLs, block navigation, and run read-only workflows.\n\n## What This Draft Changes\n\nThis file is a **front-page candidate** optimized for:\n- Primary audience: OpenClaw users actively running MCP browser workflows.\n- Secondary audience: developers doing deep debugging.\n\nTo avoid dropping anything, the complete current README is preserved below as a collapsed appendix.\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eFull Current README (Preserved, Unchanged Snapshot)\u003c/b\u003e\u003c/summary\u003e\n\n# BrowserForce // Parallel AI Agents in \"your\" Browser!\n\nGive AI agents controlled access to the browser you already use.\n\n\u003e \"a lion doesn't concern itself with token counting\" — [@steipete](https://x.com/steipete), creator of [OpenClaw](https://github.com/openclaw/openclaw)\n\u003e\n\u003e \"a 10x user doesn't concern itself with sandboxed browsers // sandboxes are for kids\" — BrowserForce, your friendly neighborhood power source.\n\n**You're giving an AI your real Chrome — your logins, cookies, and sessions. That takes conviction.** BrowserForce is built for people who use the best models and don't look back. Security is built in: lock URLs, block navigation, read-only mode, auto-cleanup — you stay in control.\n\n**Autonomous when you want it, controlled when you need it.** Your agent can run hands-off in Auto mode, or you can switch to Manual mode and explicitly attach only the tabs you trust. BrowserForce connects to **your running browser** with one Chrome extension and full Playwright API support.\n\nWorks with [OpenClaw](https://github.com/openclaw/openclaw), Claude, or any MCP-compatible agent.\n\n## Comparison\n\n\n|                | Playwright MCP       | OpenClaw Browser        | Playwriter              | Claude Extension     | BrowserForce                         |\n| -------------- | -------------------- | ----------------------- | ----------------------- | -------------------- | ------------------------------------ |\n| Browser        | Spawns new Chrome    | Separate profile        | Your Chrome             | Your Chrome          | **Your Chrome**                      |\n| Login state    | Fresh                | Fresh (isolated)        | Yours                   | Yours                | **Yours**                            |\n| Tab access     | N/A (new browser)    | Managed by agent        | Click each tab          | Click each tab       | **Auto mode + manual attached tabs** |\n| Autonomous     | Yes                  | Yes                     | No (manual click)       | No (manual click)    | **Yes (fully autonomous)**           |\n| Context method | Screenshots (100KB+) | Screenshots + snapshots | A11y snapshots (5-20KB) | Screenshots (100KB+) | **A11y snapshots (5-20KB)**          |\n| Tools          | Many dedicated       | 1 `browser` tool        | 1 `execute` tool        | Built-in             | **2 tools: `execute`, `reset`**      |\n| Agent support  | Any MCP client       | OpenClaw only           | Any MCP client          | Claude only          | **Any MCP client**                   |\n| Playwright API | Partial              | No                      | Full                    | No                   | **Full**                             |\n\n\n## Your Credentials Stay Yours\n\nEvery other approach asks you to hand over something: an API key, an OAuth token, stored passwords, session cookies in a config file. BrowserForce asks for none of it.\n\n**Why?** Because you're already logged in. BrowserForce talks to your running Chrome — it doesn't extract credentials, store cookies, or replay tokens. The browser handles auth exactly as it always has. Your agent inherits your sessions the same way a new Chrome tab does.\n\nWhat you never need to provide:\n\n- No passwords\n- No API keys\n- No OAuth tokens\n- No session cookies in env vars or config files\n\nIt's a security win *and* a setup win — there are no secrets to rotate, leak, or manage. Your logins live in Chrome. They stay in Chrome.\n\n## Setup\n\n### 1. Install\n\n```bash\nnpm install -g browserforce\n```\n\nOr from source:\n\n```bash\ngit clone https://github.com/ivalsaraj/browserforce.git\ncd browserforce\npnpm install\n```\n\n### 2. Load the Chrome extension\n\n**If you installed via npm:**\n\n1. Run: `browserforce install-extension` — note the path it prints (e.g. `/Users/you/.browserforce/extension`)\n2. Open `chrome://extensions/` in Chrome\n3. Enable **Developer mode** (top-right toggle)\n4. Click **Load unpacked** → a file picker opens\n  - **macOS**: press `Cmd+Shift+G`, paste the path from step 1, press Enter\n  - **Windows/Linux**: paste the path directly into the address bar of the dialog\n\n❗ After every BrowserForce update, re-run `browserforce install-extension`, then reload the extension in `chrome://extensions/` (click the ↺ icon next to BrowserForce).\n\n**If you cloned the repo:**\n\n1. Open `chrome://extensions/` in Chrome\n2. Enable **Developer mode** (top-right toggle)\n3. Click **Load unpacked** → select the `extension/` folder\n\nAfter loading, the extension icon appears in your toolbar (gray = disconnected).\n\n### 3. Done\n\nThe relay auto-starts when you run any command or connect via MCP — no manual step needed. Extension icon turns green once connected.\n\nTo run the relay manually (optional):\n\n```bash\nbrowserforce serve\n```\n\n## Connect Your Agent\n\n### OpenClaw\n\nMost OpenClaw users chat with their agent from Telegram or WhatsApp. BrowserForce lets your agent browse the web as you — no login flows, no captchas — even from a messaging app.\n\n#### OpenClaw One-Time Setup\n\n```bash\nnpm install -g browserforce\nbrowserforce install-extension\nbrowserforce setup openclaw\n```\n\nOptional: install the BrowserForce skill for your OpenClaw agent:\n\n```bash\nnpx -y skills add ivalsaraj/browserforce\n```\n\n#### Autostart Modes\n\n- `Default wrapper mode`: `setup openclaw` writes an OpenClaw MCP server entry that starts `browserforce serve` on-demand before `browserforce mcp`.\n- `Always-on daemon mode`: `setup openclaw` also installs OS autostart by default (launchd on macOS, systemd user service on Linux, scheduled task on Windows) so relay is already running after login.\n- `No daemon registration mode`: run `browserforce setup openclaw --no-autostart` to skip OS login service/daemon registration only; MCP wrapper autostart-on-demand still runs `browserforce serve` before `browserforce mcp`.\n\nSetup flags:\n- `--dry-run`: preview OpenClaw/autostart changes without writing files.\n- `--json`: print machine-readable setup output.\n- `--no-autostart`: skip OS login service/daemon registration only; wrapper autostart-on-demand stays enabled.\n\nOpt-in install automation environment variables:\n\n```bash\nBROWSERFORCE_SETUP_OPENCLAW=1\nBROWSERFORCE_SETUP_OPENCLAW_FORCE=1\nBROWSERFORCE_SETUP_OPENCLAW_APPLY=1\n```\n\nWhen enabled, package install runs `setup openclaw --dry-run --json`; adding `BROWSERFORCE_SETUP_OPENCLAW_APPLY=1` also runs `setup openclaw --json`. In CI, `BROWSERFORCE_SETUP_OPENCLAW_FORCE=1` is required for the setup hook to run.\n\nThen start the relay (only needed if you want to run it manually):\n\n```bash\nbrowserforce serve\n```\n\n**Verify it works** — send this to your agent:\n\n\u003e Go to [https://x.com](https://x.com) and give me top tweets\n\nIf your agent browses to the page and responds with the title, you're all set.\n\n**MCP setup (advanced):**\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eOpenClaw (MCP adapter)\u003c/b\u003e\u003c/summary\u003e\n\nAdd to `~/.openclaw/openclaw.json`:\n\n```json\n{\n  \"plugins\": {\n    \"entries\": {\n      \"mcp-adapter\": {\n        \"enabled\": true,\n        \"config\": {\n          \"servers\": [\n            {\n              \"name\": \"browserforce\",\n              \"transport\": \"stdio\",\n              \"command\": \"sh\",\n              \"args\": [\"-lc\", \"if ! lsof -tiTCP:19222 -sTCP:LISTEN \u003e/dev/null 2\u003e\u00261; then npx -y browserforce@latest serve \u003e/dev/null 2\u003e\u00261 \u0026 fi; exec npx -y browserforce@latest mcp\"]\n            }\n          ]\n        }\n      }\n    }\n  }\n}\n```\n\nThis wrapper-style entry auto-starts the relay on demand. Manual/non-wrapper alternative: use `npx -y browserforce@latest mcp` and keep `browserforce serve` running yourself.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eClaude Desktop\u003c/b\u003e\u003c/summary\u003e\n\nAdd to `~/Library/Application Support/Claude/claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"browserforce\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"browserforce@latest\", \"mcp\"]\n    }\n  }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eClaude Code\u003c/b\u003e\u003c/summary\u003e\n\nAdd to `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"browserforce\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"browserforce@latest\", \"mcp\"]\n    }\n  }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eCodex\u003c/b\u003e\u003c/summary\u003e\n\nAdd to `~/.codex/config.toml`:\n\n```toml\n[mcp_servers.browserforce]\ncommand = \"npx\"\nargs = [\"-y\", \"browserforce@latest\", \"mcp\"]\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eCursor\u003c/b\u003e\u003c/summary\u003e\n\nAdd to `~/.cursor/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"browserforce\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"browserforce@latest\", \"mcp\"]\n    }\n  }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eAntigravity\u003c/b\u003e\u003c/summary\u003e\n\nIn Antigravity: Agent panel -\u003e `...` -\u003e `Manage MCP Servers` -\u003e `View raw config`.\nAdd the same `mcpServers` entry:\n\n```json\n{\n  \"mcpServers\": {\n    \"browserforce\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"browserforce@latest\", \"mcp\"]\n    }\n  }\n}\n```\n\n\u003c/details\u003e\n\n\n\nIf MCP startup fails with `connection closed: initialize response`:\n\n1. Ensure args include `\"mcp\"` (without it, BrowserForce prints help and exits).\n2. If running from a local clone, install deps first: `pnpm install`.\n3. Validate the launch command manually: `npx -y browserforce@latest mcp`\n\n### CLI\n\n```bash\nnpm install -g browserforce   # or: pnpm add -g browserforce\n```\n\n```bash\nbrowserforce serve              # Start the relay server\nbrowserforce status             # Check relay and extension status\nbrowserforce tabs               # List open browser tabs\nbrowserforce snapshot [n]       # Accessibility tree of tab n\nbrowserforce screenshot [n]     # Screenshot tab n (PNG to stdout)\nbrowserforce navigate \u003curl\u003e     # Open URL in a new tab\nbrowserforce -e \"\u003ccode\u003e\"        # Run Playwright JavaScript (one-shot)\nbrowserforce plugin list        # List installed plugins\nbrowserforce plugin install \u003cn\u003e # Install a plugin from the registry\nbrowserforce plugin remove \u003cn\u003e  # Remove an installed plugin\nbrowserforce setup openclaw [--dry-run] [--json] [--no-autostart] # Configure OpenClaw + optional autostart\nbrowserforce update             # Update to the latest version\nbrowserforce install-extension  # Copy extension to ~/.browserforce/extension/\n```\n\nSetup flags: `--dry-run` (preview), `--no-autostart` (skip OS login daemon/service registration only), `--json` (machine-readable output).\n\nEach `-e` command is one-shot — state does not persist between calls. For persistent state, use the MCP server.\n\n## Plugins\n\nPlugins add custom helpers directly into the `execute` tool scope. Install once — your agent calls them like built-in functions.\n\n### Install a plugin\n\n```bash\nbrowserforce plugin install highlight\n```\n\nThat's it. Restart MCP (or Claude Desktop) after every plugin install or update, then `highlight()` is available in every `execute` call.\n\n### Prompt behavior (metadata-first)\n\nPlugin `SKILL.md` content is no longer fully inlined into the default `execute` prompt. BrowserForce now exposes plugin metadata first (name, description, helpers), then loads details on demand:\n\n- Call `pluginCatalog()` to discover installed plugins, helper names, and available sections.\n- Call `pluginHelp(name, section?)` only when you need plugin-specific instructions.\n\n### Official plugins\n\n\n| Plugin      | What it adds                                                                                   | Install                                 |\n| ----------- | ---------------------------------------------------------------------------------------------- | --------------------------------------- |\n| `highlight` | `highlight(selector, color?)` — outlines matching elements; `clearHighlights()` — removes them | `browserforce plugin install highlight` |\n\n\n### Use an installed plugin\n\nAfter installing `highlight`, your agent can call it directly:\n\n```javascript\n// Outline all buttons in blue\nawait highlight('button', 'blue');\n\n// Highlight the specific element you're about to click\nawait highlight('[data-testid=\"submit\"]', 'red');\nreturn await screenshotWithAccessibilityLabels();\n```\n\nThe helper receives the active page, context, and state automatically — no plumbing needed.\n\n### Manage plugins\n\n```bash\nbrowserforce plugin list        # See what's installed\nbrowserforce plugin remove highlight   # Uninstall\n```\n\nPlugins are stored at `~/.browserforce/plugins/\u003cname\u003e/`. Each plugin folder contains an `index.js` and can include a `SKILL.md`.\n\nRepo layout remains:\n- Official plugins: `plugins/official/\u003cname\u003e/SKILL.md`\n- Community plugins: `plugins/community/\u003cname\u003e/SKILL.md`\n\nNo migration to `plugin/skills/\u003cname\u003e/` is required.\n\n### Write your own\n\n```javascript\n// ~/.browserforce/plugins/my-plugin/index.js\nexport default {\n  name: 'my-plugin',\n  helpers: {\n    async scrollToBottom(page, ctx, state) {\n      await page.evaluate(() =\u003e window.scrollTo(0, document.body.scrollHeight));\n    },\n    async countLinks(page, ctx, state) {\n      return page.evaluate(() =\u003e document.querySelectorAll('a').length);\n    },\n  },\n};\n```\n\nDrop it in `~/.browserforce/plugins/my-plugin/`, restart MCP, and call `await scrollToBottom()` or `await countLinks()` from any `execute` call.\n\nAdd a `SKILL.md` file alongside `index.js` to publish plugin metadata and help text. The default prompt includes only metadata; fetch full or sectioned guidance on demand with `pluginHelp('my-plugin')` or `pluginHelp('my-plugin', 'examples')`.\n\n### Any Playwright Script\n\n```javascript\nconst { chromium } = require('playwright');\n\nconst browser = await chromium.connectOverCDP(\n  'ws://127.0.0.1:19222/cdp?token=\u003cTOKEN\u003e'\n);\n\nconst pages = browser.contexts()[0].pages();\nfor (const page of pages) {\n  console.log(page.url());  // your real tabs!\n}\n\n// Gmail is already logged in\nconst gmail = pages.find(p =\u003e p.url().includes('mail.google'));\nawait gmail.screenshot({ path: 'gmail.png' });\n```\n\nNo token config needed for MCP — the server reads it automatically from `~/.browserforce/cdp-url`.\n\n## What Your Agent Can Do\n\nOnce connected, your agent has full Playwright access to your real browser:\n\n```javascript\n// Navigate (uses your cookies — no login needed)\nawait page.goto('https://github.com');\nawait waitForPageLoad();\n\n// Read pages with accessibility snapshots (10-100x cheaper than screenshots)\nreturn await snapshot();\n\n// Click, type, fill forms\nawait page.locator('role=button[name=\"Sign in\"]').click();\nawait page.locator('role=textbox[name=\"Search\"]').fill('query');\n\n// Screenshots when you need them\nreturn await page.screenshot();\n\n// Work with multiple tabs\nconst pages = context.pages();\nconst gmail = pages.find(p =\u003e p.url().includes('mail.google'));\n\n// Persist data across calls\nstate.results = await page.evaluate(() =\u003e document.title);\n```\n\n### MCP Tools\n\n\n| Tool      | Description                                                                                                                                                                                                                    |\n| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| `execute` | Run Playwright JavaScript in your real Chrome. Access `page`, `context`, `state`, `snapshot()`, `waitForPageLoad()`, `getLogs()`, `screenshotWithAccessibilityLabels()`, `cleanHTML()`, `pageMarkdown()`, and Node.js globals. |\n| `reset`   | Reconnect to the relay and clear state. Use when the connection drops.                                                                                                                                                         |\n\n\n### Diff-Aware Helpers\n\nUse `showDiffSinceLastCall` to control diff output vs full output in execute helper calls:\n\n```javascript\nawait snapshot({ showDiffSinceLastCall: true });\nawait snapshot({ showDiffSinceLastCall: false });\nawait cleanHTML('body', { showDiffSinceLastCall: false });\nawait pageMarkdown({ showDiffSinceLastCall: true });\n```\n\n### BrowserForce Tab Swarms // Parallel Tabs Processing\n\nBrowserForce uses a parallel-first policy for independent extraction jobs, so agents finish list/count/scrape tasks faster with bounded risk.\n\n- Rule: For count/list/extraction across independent pages, dates, or items, run parallel tabs first using `Promise.all` with a concurrency cap (`3-8`, typically start at `5`).\n- Fallback: If the site starts rate-limiting (`429`), anti-bot challenges appear, or timeouts repeat, automatically retry with reduced concurrency and then sequential as a final fallback.\n- Safety: This swarm exception is for read-only bulk extraction only; no user-tab mutation (checkout/purchase/send/delete/settings changes) during swarm runs.\n- Required telemetry return: `peakConcurrentTasks`, `wallClockMs`, `sumTaskDurationsMs`, `failures`, `retries`.\n\nNeed role-based, real workflows? See [Actionable Use Cases](docs/USE_CASES.md).\n\n## Examples\n\nGet started with simple prompts. The AI generates code and does the work.\n\n**Example 1: Read page content (X.com search)**\n\n**Prompt to AI:**\n\n\u003e Go to x.com/search and search for \"browserforce\". Show me the top 5 tweets you find.\n\n**What the AI does:** Navigates to X, searches the term, extracts top tweets, returns them to you.\n\n**Use case:** Quick research, trend tracking, social listening.\n\n\n\n**Example 2: Interact with a form (GitHub search)**\n\n**Prompt to AI:**\n\n\u003e Go to GitHub and search for \"ai agents\". Show me the top 3 repositories and their star counts.\n\n**What the AI does:** Fills GitHub search, waits for results, extracts repo names + stars, returns them.\n\n**Use case:** Finding libraries, competitive research, project discovery.\n\n\n\n### Multi-Tab Workflows\n\n**Example 3: Search → Extract → Return**\n\n**Prompt to AI:**\n\n\u003e Search ProductHunt for \"AI tools\" and give me the top 5 products with their taglines and upvote counts.\n\n**What the AI does:** Navigates ProductHunt, searches, extracts product info, returns structured data.\n\n**Use case:** Market research, finding tools, competitive analysis.\n\n\n\n**Example 4: Open result in new tab, process there**\n\n**Prompt to AI:**\n\n\u003e Find the #1 product from your last ProductHunt search, click into it, and read the full description. Tell me what it does.\n\n**What the AI does:** Opens the product page from previous results, reads the description, summarizes it.\n\n**Use case:** Deep-dive research, understanding competitors, due diligence.\n\n\n\n**Example 5: Debugging workflow (inspect + verify)**\n\n**Prompt to AI:**\n\n\u003e Go to my staging site at staging.myapp.com/checkout and take a labeled screenshot. Tell me if the \"Complete Purchase\" button is visible and what's around it.\n\n**What the AI does:** Navigates, takes screenshot with interactive labels, analyzes button state and layout.\n\n**Use case:** Visual debugging, QA checks, spotting broken elements.\n\n\n\n**Example 6: Test form with data**\n\n**Prompt to AI:**\n\n\u003e Sign up for Substack using the email [test.user@example.com](mailto:test.user@example.com). Tell me if the signup completes successfully.\n\n**What the AI does:** Fills the form, submits, waits for confirmation, reports success/failure.\n\n**Use case:** Testing sign-up flows, QA automation, form validation.\n\n\n\n**Example 7: Content pipeline (search → extract → compare)**\n\n**Prompt to AI:**\n\n\u003e Search for \"AI regulation\" on both X.com and LinkedIn. Give me the top 5 trending posts from each and tell me which topics overlap.\n\n**What the AI does:** Searches both platforms, extracts posts, compares content, returns analysis.\n\n**Use case:** Multi-source research, trend analysis, market sentiment.\n\n\n\n**Example 8: Data extraction → CSV pipeline**\n\n**Prompt to AI:**\n\n\u003e Go to Hacker News and extract the top 10 stories with their titles and vote counts. Format as CSV so I can import into a spreadsheet.\n\n**What the AI does:** Navigates HN, extracts story data, formats as CSV, returns it ready to paste.\n\n**Use case:** Data workflows, trend tracking, content curation.\n\n\n\n**Example 9: A/B testing across variants**\n\n**Prompt to AI:**\n\n\u003e Visit myapp.com/?variant=red and myapp.com/?variant=blue. Compare the two designs and tell me which button color is more prominent and what other differences exist.\n\n**What the AI does:** Opens both variants, compares layouts/colors/text, reports visual differences.\n\n**Use case:** Design QA, A/B testing, variant comparison.\n\n\n\n**Example 10: Monitor + alert workflow**\n\n**Prompt to AI:**\n\n\u003e Check our status page at status.myapp.com every few minutes. Tell me the current status of the API and database. Alert me if anything changes from green to red.\n\n**What the AI does:** Monitors status page, reads indicators, alerts on degradation.\n\n**Use case:** Uptime monitoring, incident detection, SLA tracking.\n\n\n\n### Parallel Tab Swarms: Real-World Use Cases\n\n**Example 11: Retail price swarm (SKU × store matrix)**\n\n**Prompt to AI:**\n\n\u003e For these 25 SKUs, check Amazon, Walmart, Target, and Best Buy in parallel tabs. Return the best price, in-stock status, and fastest delivery ETA per SKU.\n\n**What the AI does:** Runs independent `(sku, store)` checks in capped parallel tab batches, retries with reduced concurrency on `429`/timeouts, then falls back sequentially if needed.\n\n**Use case:** Pricing intelligence, buy-box monitoring, merchandising ops.\n\n\n\n**Example 12: Travel fare grid (date × route sweep)**\n\n**Prompt to AI:**\n\n\u003e For SFO → JFK, scan the next 14 Fridays and Sundays across Google Flights, Kayak, and Expedia. Return the cheapest refundable option for each date.\n\n**What the AI does:** Opens independent `(date, site)` tasks in parallel, extracts fare + refundability, and returns a normalized comparison table.\n\n**Use case:** Travel operations, procurement, rapid itinerary optimization.\n\n\n\n**Example 13: Competitor launch radar (company × source)**\n\n**Prompt to AI:**\n\n\u003e Track the last 7 days of updates for these 30 competitors across release notes, changelogs, docs, and blog posts. Group findings by feature category.\n\n**What the AI does:** Parallelizes `(company, source)` extraction, deduplicates announcements, and returns a launch digest with links.\n\n**Use case:** Product strategy, PM intelligence, competitive monitoring.\n\n\n\n**Example 14: Lead qualification swarm (account × signal source)**\n\n**Prompt to AI:**\n\n\u003e For this account list, check careers pages, LinkedIn jobs, pricing pages, and press/news for expansion signals. Score each account and rank top opportunities.\n\n**What the AI does:** Executes independent account-source checks in parallel tabs, extracts signal evidence, and returns ranked lead scores with rationale.\n\n**Use case:** Sales research, outbound prioritization, RevOps signal mining.\n\n\n\n**Example 15: Security exposure triage (domain × surface)**\n\n**Prompt to AI:**\n\n\u003e For these domains, inspect login pages, robots.txt, status pages, public docs, and likely staging links. Flag suspicious exposures with evidence links.\n\n**What the AI does:** Runs read-only `(domain, surface)` checks in a swarm, retries degraded paths safely, and returns a risk-prioritized findings report.\n\n**Use case:** Security reviews, surface mapping, pre-audit triage.\n\n\n\n**More examples** and detailed walkthrough available in the [User Guide](GUIDE.md#examples).\n\n## How It Works\n\n```\n  Agent (OpenClaw, Claude, etc.)\n         │\n         ├─ MCP server (stdio)\n         ├─ CLI (browserforce -e)\n         │\n         │ CDP over WebSocket\n         ▼\n  Relay Server (localhost:19222)\n         │\n         │ WebSocket\n         ▼\n  Chrome Extension (MV3)\n         │\n         │ chrome.debugger API\n         ▼\n  Your Real Chrome Browser\n```\n\nThe **relay server** runs on your machine (localhost only). It translates between the agent's CDP commands and the extension's debugger bridge.\n\nThe **Chrome extension** lives in your browser. It attaches Chrome's built-in debugger to permitted tabs and forwards commands — exactly like DevTools does.\n\nIn **Auto mode**, the agent can create and control tabs it opens. In **Manual mode**, you decide access by clicking **+ Attach Current Tab**.\n\n## You Stay in Control\n\nClick the extension icon to configure restrictions. Your browser, your rules:\n\n\n| Setting                 | What it does                                                             |\n| ----------------------- | ------------------------------------------------------------------------ |\n| **Auto / Manual mode**  | Let the agent create tabs freely, or hand-pick which tabs it can access  |\n| **Lock URL**            | Prevent the agent from navigating away from the current page             |\n| **No new tabs**         | Block the agent from opening new tabs                                    |\n| **Read-only**           | Observe only — no clicks, no typing, no interactions                     |\n| **Auto-detach**         | Automatically detach inactive tabs after 5-60 minutes                    |\n| **Auto-close**          | Automatically close agent-created tabs after 5-60 minutes                |\n| **Custom instructions** | Pass text instructions to the agent (e.g. \"don't click any buy buttons\") |\n\n\n### Controlled Tab Workflows\n\n- **Manually attach a tab:** Open the tab you want, click the extension popup, then click **+ Attach Current Tab**.\n- **Open full log viewer:** In the popup, click **View Full Logs** to open the extension options page.\n- **Restrict to one controlled tab:** Use **Manual mode**, attach one tab, and enable **No new tabs**.\n- **Allow multiple controlled tabs:** Stay in **Manual mode** and attach each tab you want the agent to access.\n- **Restriction modes:** Use **Lock URL** (no navigation), **No new tabs**, and **Read-only** (observe only) together or separately.\n- **Auto-cleanup:** Use **Auto-detach** for inactive attached tabs and **Auto-close** for agent-created tabs.\n\nFor step-by-step setups, see the [Controlled Tabs Playbook](GUIDE.md#controlled-tabs-playbook).\n\n## Security\n\n\n| Layer            | Control                                                                 |\n| ---------------- | ----------------------------------------------------------------------- |\n| **Network**      | Relay binds to `127.0.0.1` only — never exposed to the internet         |\n| **Auth**         | Random token required for every CDP connection                          |\n| **Origin**       | Extension only accepts connections from its own Chrome origin           |\n| **Visibility**   | Chrome shows \"controlled by automated test software\" on active tabs     |\n| **Restrictions** | Lock URLs, block navigation, read-only mode — enforced at the CDP level |\n\n\nEverything runs on your machine. The auth token is stored at `~/.browserforce/auth-token` with owner-only permissions.\n\n## Configuration\n\n**Custom relay port:**\n\n```bash\nRELAY_PORT=19333 browserforce serve\n```\n\n**Extension relay URL:** Click the extension icon → change the URL → Save. Default: `ws://127.0.0.1:19222/extension`\n\n**Override CDP URL for MCP:**\n\n```json\n{\n  \"env\": {\n    \"BF_CDP_URL\": \"ws://127.0.0.1:19333/cdp?token=your-token\"\n  }\n}\n```\n\n**Client arbitration mode (`BF_CLIENT_MODE`):**\n\n```bash\n# default: one active /cdp client at a time\nBF_CLIENT_MODE=single-active browserforce serve\n\n# fallback: allow concurrent /cdp clients\nBF_CLIENT_MODE=multi-client browserforce serve\n```\n\nIn `single-active` mode, the relay enforces one active client slot. A second `/cdp` connection receives HTTP `409 Conflict` (busy). In `multi-client` mode, slot arbitration is disabled.\n\n**MCP standby polling (single-active mode):** if MCP sees a busy/`409` connect error, it enters standby and polls `GET /client-slot` until `busy: false` (about every 200-400ms, up to 30s), then retries connect.\n\n**Operational non-goals:** canonical list is maintained in [AGENTS.md](AGENTS.md#operational-non-goals).\n\n## API\n\n| Endpoint                 | Description                                   |\n| ------------------------ | --------------------------------------------- |\n| `GET /`                  | Health check (extension status, target count) |\n| `GET /client-slot`       | Client-slot state: `{ mode, busy, activeClientId, connectedAt }` |\n| `GET /json/version`      | CDP discovery                                 |\n| `GET /json/list`         | List attached targets                         |\n| `GET /logs/status` | Logs viewer status (extension-only origin) |\n| `GET /logs/cdp?after=\u0026limit=` | Incremental CDP log polling feed (extension-only origin) |\n| `ws://.../extension` | Chrome extension WebSocket |\n| `ws://.../cdp?token=...` | Agent CDP connection |\n\nTip: add `\u0026label=\u003cname\u003e` to the CDP URL to tag client connections in the logs viewer (MCP defaults to `browserforce-mcp`).\n\n## Troubleshooting\n\n\n| Problem                      | Fix                                                   |\n| ---------------------------- | ----------------------------------------------------- |\n| Extension stays gray         | Is the relay running? Check `http://127.0.0.1:19222/` |\n| \"Another debugger attached\"  | Close DevTools for that tab                           |\n| Agent sees 0 pages           | Open at least one regular webpage (not `chrome://`)   |\n| Extension keeps reconnecting | Normal — MV3 kills idle workers; it auto-recovers     |\n| Port in use                  | `lsof -ti:19222 | xargs kill -9`                      |\n\n\n### MCP Error: `Protocol error (Target.createTarget): Extension not connected`\n\nThis usually means MCP is talking to a relay process that is not the one your extension is connected to.\n\nQuick checks:\n\n```bash\ncurl -s http://127.0.0.1:19222/ | jq\ncat ~/.browserforce/cdp-url\necho \"${BF_CDP_URL:-\u003cunset\u003e}\"\n```\n\nIf MCP is reading a stale `~/.browserforce/cdp-url` (or `BF_CDP_URL` override), it may connect to the wrong port.\n\nRecovery steps (npm/npx workflow):\n\n```bash\n# 1) Stop stale relay listeners\nlsof -tiTCP:19222 -sTCP:LISTEN | xargs kill -9 2\u003e/dev/null || true\nlsof -tiTCP:19888 -sTCP:LISTEN | xargs kill -9 2\u003e/dev/null || true\n\n# 2) Clear stale override for this shell\nunset BF_CDP_URL\n\n# 3) Start one fresh relay on default port\nRELAY_PORT=19222 npx -y browserforce@latest serve\n```\n\nThen verify:\n\n```bash\ncat ~/.browserforce/cdp-url\ncurl -s http://127.0.0.1:19222/client-slot | jq\n```\n\nExpected: `cdp-url` points to `ws://127.0.0.1:19222/...` and `/client-slot` returns `{ mode, busy, activeClientId, connectedAt }`.\n\n### MCP Error: `Unexpected server response: 409`\n\nThis means single-active arbitration is working and another CDP client is currently holding the slot.\n\nCheck:\n\n```bash\ncurl -s http://127.0.0.1:19222/client-slot | jq\n```\n\nIf `busy: true`, close the other MCP/CDP session or set `BF_CLIENT_MODE=multi-client` for explicit concurrent-client fallback.\n\nCDP traffic is logged to `~/.browserforce/cdp.jsonl` (recreated on each relay start). Summarize traffic by direction + method:\n\n```bash\njq -r '.direction + \"\\t\" + (.message.method // \"response\")' ~/.browserforce/cdp.jsonl | uniq -c\n```\n\nFor practical debugging and operations flows, see [Actionable Use Cases](docs/USE_CASES.md#developer-high-impact).\n\n\u003e **Need advanced operator playbooks?** Read the [User Guide](https://github.com/ivalsaraj/browserforce/blob/main/GUIDE.md) for controlled-tab workflows, parallel swarm patterns, and production diagnostics.\n\n\u003c/details\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivalsaraj%2Fbrowserforce","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fivalsaraj%2Fbrowserforce","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivalsaraj%2Fbrowserforce/lists"}