Agent Browser Relay
Use this skill to attach to a chosen Chrome tab through the bundled Agent Browser Relay extension and extract tab metadata or DOM data for analysis.
Quick start
Fresh-machine rule:
skills addguarantees the installed skill at~/.agents/skills/agent-browser-relay- the guaranteed Chrome load path after
skills addis~/.agents/skills/agent-browser-relay/extension ~/agent-browser-relay/extensionis only an optional visible convenience copy created bynpm run extension:installnpm run extension:path,npm run relay:start, andnpm run relay:global:installprint the primary folder to load- opening the extension popup once after relay startup now wakes the extension and lets
npm run extension:statusconfirm that Chrome actually loaded it - on a new machine, the human must load the primary path in
chrome://extensionsbefore attach/read steps. Do not treat a missing visible convenience copy as a sandbox or socket-permission issue.
Defaults are set in code:
- Host:
127.0.0.1 - Port:
18793 - Attach timeout:
120000ms Override per command with--host,--port, and--attach-timeout-mswhen needed.
-
Install dependencies and start relay
This prints the primary Chrome extension path to load in Chrome and refreshes the optional visible convenience copy when possible.
npm run relay:start -- --status-timeout-ms 3000Or pin host/port explicitly:
npm run relay:start -- --host "127.0.0.1" --port "18793" --status-timeout-ms 3000relay:startkeeps running until you stop it or the process is restarted. If you want a bounded session, pass--auto-stop-msexplicitly:node scripts/relay-manager.js start --auto-stop-ms 10800000 -
Load extension in Chrome
chrome://extensions- Enable developer mode
- Load unpacked from
~/.agents/skills/agent-browser-relay/extensionafterskills add - If the command printed the extension path, treat that printed path as the source of truth
- Run
npm run extension:pathfrom the installed skill directory any time you want the exact path printed again ~/agent-browser-relay/extensionis optional; create it withnpm run extension:installif you want a visible shortcut
-
Confirm the extension is loaded in Chrome
Open the toolbar popup once after relay is running. The popup should show
Relay connected on <port>.Agent requirement: before any attach step on a fresh machine, ask the human to open the popup once, then confirm:
npm run extension:status -- --wait-for-connected --connected-timeout-ms 120000 -
Attach the extension to the target tab (open toolbar popup and click attach)
Optional per-tab relay: in the popup, set Tab port before clicking attach if this tab should use a non-default relay port. If you want the agent to create its own first background tab instead, enable Allow agent to create new background tabs in the popup.
Agent requirement: after
extension:statusconfirms Chrome loaded the extension, pause and ask the human to do this attach step, then wait for confirmation before continuing.If your
.agentsskill folder dropsextension/after agit fetchor pull, repair it from the repo:cd ~/.agents/skills/agent-browser-relay 2>/dev/null || cd ~/.agents/skills/private/agent-browser-relay git sparse-checkout disable git config --unset-all core.sparseCheckout || true git config --unset-all core.sparseCheckoutCone || true git checkout -- . -
Check readiness and attach state
node scripts/read-active-tab.js --host "127.0.0.1" --port "18793" --tab-id "<TAB_ID>" --check --wait-for-attach --attach-timeout-ms "120000"Resolve
<TAB_ID>from status first (npm run relay:status -- --all --status-timeout-ms 3000). For all agent runs, use the assigned tab id:node scripts/read-active-tab.js --host "127.0.0.1" --port "18793" --tab-id "<TAB_ID>" --check --wait-for-attach --attach-timeout-ms "120000"Continue only if this command returns success.
Per-tab relay port behavior
- If you run one relay process with multiple ports, the extension can manage different relay ports per attached tab.
- A tab with no saved relay-port mapping uses the global default relay port (
18793). - After a successful attach, the extension saves that tab’s mapped relay port and reuses it automatically.
- Closed tabs have their mapping removed automatically.
Mandatory behavior for agents
- Use fixed commands from this repo. Do not try to "discover" alternate script names.
- Gateway-only rule: always communicate through the local relay gateway (
/statusandnode scripts/read-active-tab.js). - Never use direct browser-control tooling for this workflow (for example Playwright, Puppeteer, Selenium,
agent-browser, or ad-hoc Chrome control scripts). - Never take control of a random Chrome window/profile. Only operate on the explicitly attached target tab leased via
--tab-id. - On a fresh machine, explicitly tell the human to load the primary extension path from
npm run extension:pathbefore any attach/read attempt. Afterskills add, that is normally~/.agents/skills/agent-browser-relay/extension. - Canonical commands:
npm run extension:pathnpm run extension:statusnpm run relay:startnpm run relay:statusnpm run relay:stopnode scripts/read-active-tab.js
- For relay health checks, always use explicit timeouts to avoid hangs:
npm run relay:status -- --status-timeout-ms 3000curl --max-time 3 -sS "http://127.0.0.1:18793/status"npm run relay:status -- --all --status-timeout-ms 3000
- After
relay:start, pause and ask the human to open the popup once sonpm run extension:status -- --wait-for-connected --connected-timeout-ms 120000can confirm Chrome actually loaded the extension. - Only after
extension:statussucceeds, either ask the human to attach the target tab before reads, or confirm that Allow agent to create new background tabs is enabled before first-tab creation workflows. - Run
node scripts/read-active-tab.js --host "127.0.0.1" --port "18793" --tab-id "<TAB_ID>" --check --wait-for-attach --attach-timeout-ms "120000"before reads and proceed only when it succeeds. - If the workflow will open tabs via
Target.createTarget, runnode scripts/read-active-tab.js --check --require-target-createand proceed only when it succeeds. - For all agent runs (single-agent and concurrent), always pass
--tab-id <tabId>on check/read commands so every operation is lease-scoped. - When
Target.createTargetis enabled, the extension may create and auto-attach the first agent-controlled tab for the session without a human seed attach step. - Do not stop/restart relay during the task unless the human requests it or recovery is explicitly required.
- Do not restart relay only because code was updated locally; updates are applied on next explicit human-approved restart.
- If the requested
tabIdis missing from relay statusattachedTabs, stop and ask the human to re-attach the target tab in the popup before continuing. - If
relay:starttimes out, report the actual relay log/error. Do not guess about sandbox restrictions unless the command output shows a concrete permission error. - If the page shows human-verification gates (for example "Are you human?" or CAPTCHA), stop immediately, alert the human with $attention-please, and wait for explicit human confirmation before continuing.
-
Read structured tab payload
node scripts/read-active-tab.js --host "127.0.0.1" --port "18793" --tab-id "<TAB_ID>" -
Optional one-command smoke test
./scripts/preflight.sh
Capabilities
read-active-tab.js returns capability metadata in every successful payload under:
source.capabilities
Version compatibility checks are also included under source.extension:
installedVersionsourceVersionrelayVersionobservedExtensionVersionversionMismatch
If a mismatch is detected, the command also prints a human-friendly update hint to stderr on every run.
scripts/read-active-tab.jsdefault extraction:url,title,text,links,metaDescription.- Relay session leases (
--tab-id) for concurrent agent isolation per tab on one relay port. Runtime.evaluateexpression mode with--expression.- Screenshot capture mode via
--screenshot(optional--screenshot-full-page,--screenshot-path). - Preset extraction for WhatsApp and generic chat-auditing with regex filters.
- Attach-state polling with
--check --wait-for-attach.
Presets and filters
--presetvalues:default,whatsapp,wa,whatsapp-messages,chat-audit,chat.- Regex filters:
--text-regex,--exclude-text-regex,--link-text-regex,--link-href-regex. - WhatsApp/chat filters:
--message-regex,--exclude-message-regex,--sender-regex,--exclude-sender-regex.
Common command examples
In agent workflows, use the --tab-id variants. Unscoped commands are for manual/local debugging only.
node scripts/read-active-tab.js --host "127.0.0.1" --port "18793" --pretty false
node scripts/read-active-tab.js --host "127.0.0.1" --port "18793" --tab-id 123 --pretty false
node scripts/read-active-tab.js --host "127.0.0.1" --port "18793" --tab-id 123 --check --wait-for-attach --require-target-create --attach-timeout-ms 120000
node scripts/read-active-tab.js --host "127.0.0.1" --port "18793" --expression "document.documentElement.outerHTML"
node scripts/read-active-tab.js --host "127.0.0.1" --port "18793" --screenshot --screenshot-full-page --screenshot-path "./tmp/page.png"
node scripts/read-active-tab.js --host "127.0.0.1" --port "18793" --preset whatsapp-messages --max-messages 200 --selector "#main"
node scripts/read-active-tab.js --preset chat-audit --selector "body" --message-regex ".*"
All successful commands return a source object with relayHost, relayPort, relayStatusUrl, and relayWebSocketUrl.
Recommended flow with agents
Before fetching data in an automation flow, run a lightweight preflight once to ensure relay + attached tab state are ready.
For multiple agents on one relay:
- Resolve tab ids from relay status (
npm run relay:status -- --all --status-timeout-ms 3000). - Assign one tab id per agent.
- Use
--tab-idin everyread-active-tab.jscall for that agent.