AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Browser Relay

skill-reliefeai-browser-relay-skill · by reliefeai

Control the user's local Chrome browser through Browser Relay. For agent browser interaction, use the `browser-relay` CLI by default; use HTTP API mainly when writing code, tests, or integrations. Use for dynamic/login-protected pages, clicking, typing, screenshots, or evaluating JS in tabs that carry the user's real session. Skip static pages and pure REST APIs.

No reviews yet
0 installs
25 views
0.0% view→install

Install

$ agentstack add skill-reliefeai-browser-relay-skill

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-reliefeai-browser-relay-skill)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Browser Relay? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Browser Relay Skill

Control a real Chrome browser via the Browser Relay CLI, HTTP API, or MCP. The browser runs on the user's machine, carrying their login state, cookies, and extensions.

When to Use

Use Browser Relay when you need to:

  • Scrape dynamic pages — JavaScript-rendered content, SPAs, dashboards
  • Interact with login-protected sites — pages that require the user's session (Twitter, Gmail, Notion, etc.)
  • Perform actions — click buttons, fill forms, scroll, take screenshots
  • Get structured page text — annotated DOM snapshot with [link], [button], [input] markers
  • Evaluate arbitrary JavaScript in the page context

When NOT to use:

  • Simple static pages without login — use WebFetch or Jina Reader (faster, cheaper)
  • Pure API calls — use the site's REST API directly

Prerequisites

  1. Relay Server running (Node.js, default port 18795)
  2. Browser Relay Chrome Extension installed and configured with the relay port
  3. At least one Chrome tab open and attached (extension auto-attaches all tabs)

Connection Info

Relay URL:  http://127.0.0.1:18795
WebSocket:  ws://127.0.0.1:18795/extension

No authentication needed — the relay only accepts connections from localhost.

Remote mode ("Remote Relay") lets an agent drive a browser on another machine. The user opens the extension Options, turns on Remote Relay, and copies the generated remote-device-id — a secret capability like br-xxx. Only then use remote flags (the hosted hub relay.linso.ai is the default host):

browser-relay tabs --remote-device-id br-xxx
browser-relay remote add mymac br-xxx    # or save an alias once…
browser-relay tabs --remote mymac        # …and use the short name (remote ls / rm to manage)

Never invent or guess a remote-device-id; it is a secret generated by the extension. The local relay stays bound to localhost — remote mode connects the browser out to the hub and does not need it.

Preferred CLI Workflow

When shell access is available, use the browser-relay CLI for browser interaction. Do not hand-write curl for normal agent browsing tasks. The CLI avoids JSON escaping, keeps commands short, and prints compact output by default.

Use the HTTP API directly only when you are writing code, tests, scripts, or an integration against Browser Relay, or when the CLI is unavailable. Use --json only when you need the full API response.

browser-relay tabs
browser-relay console --tab  --limit 50
browser-relay network --tab  --type response --status 500 --limit 20
browser-relay snapshot --tab  --max-length 20000
browser-relay wait 'button[type=submit]' --state visible --timeout 10000 --tab 
browser-relay click 'button[type=submit]' --tab 
browser-relay type 'hello world' --selector 'input[name=q]' --clear --submit --tab 
browser-relay key Control+L --tab 
browser-relay scroll down --amount 1000 --tab 
browser-relay download-start https://example.com/file.pdf --filename files/file.pdf
browser-relay downloads --limit 20
browser-relay screenshot /tmp/page.png --full-page --tab 
browser-relay eval 'document.title' --tab 

For maintenance, upgrade Browser Relay with:

browser-relay update

Then refresh this Skill for the active agent (for example, codex or claude-code) and let Browser Relay verify the installed copy:

browser-relay skill install --agent codex

For long text or JavaScript, avoid shell escaping with stdin:

printf '%s' "$TEXT" | browser-relay type --selector textarea --stdin --tab 
browser-relay eval --stdin --tab  &limit=100&level=error&clear=false
POST http://127.0.0.1:18795/api/console/clear
Body: { "tabId?": "...", "level?": "error" }

Use this after actions that may trigger frontend errors or warnings.

2c. browser_network

Read captured request/response/finished/failed network events. Sensitive headers such as Authorization, Cookie, Proxy-Authorization, and Set-Cookie are redacted; request bodies are not captured.

GET http://127.0.0.1:18795/api/network?tabId=&type=response&status=500&limit=100&clear=false
POST http://127.0.0.1:18795/api/network/clear
Body: { "tabId?": "...", "type?": "request|response|finished|failed", "method?": "GET", "status?": 500, "requestId?": "...", "url?": "substring" }

Use this after actions that fail silently, after form submits, or when console errors imply an API request failed.

3. browser_snapshot

Get a text representation of the current page (interactive elements annotated).

GET http://127.0.0.1:18795/api/snapshot?tabId=&format=text&maxLength=100000

Format can be "text" (annotated DOM) or "html" (raw HTML).

3b. browser_wait

Wait for a CSS selector to be attached to the DOM or become visible. Prefer this over fixed sleeps after navigation or actions.

POST http://127.0.0.1:18795/api/wait
Body: {
  "selector": "button.submit",
  "state?": "attached|visible",
  "timeoutMs?": 5000,
  "pollMs?": 100,
  "tabId?": "..."
}

state defaults to visible. timeoutMs accepts 1–20000 and pollMs accepts 50–1000. A timeout returns code: "wait_timeout" with retryable: true; a tab closing or the extension disconnecting fails immediately instead of waiting for the timeout.

4. browser_click

Click an element by CSS selector. Scrolls into view first, uses real mouse events.

POST http://127.0.0.1:18795/api/click
Body: { "selector": "button.submit", "tabId?": "...", "doubleClick?": false }

5. browser_type

Type text into an input field. Optionally clear and submit.

POST http://127.0.0.1:18795/api/type
Body: {
  "text": "hello world",
  "selector?": "input[name='q']",
  "clear?": true,
  "submit?": true,
  "tabId?": "..."
}

6. browser_scroll

Scroll the page.

POST http://127.0.0.1:18795/api/scroll
Body: { "direction": "down|up|top|bottom", "amount?": 800, "tabId?": "..." }

7. browser_key

Press a key or keyboard shortcut using real keyboard events.

POST http://127.0.0.1:18795/api/key
Body: { "key?": "Enter", "combo?": "Control+L", "tabId?": "..." }

Use combo for shortcuts (Control+L, Meta+K, Shift+Tab) and key for single keys (Enter, Escape, ArrowDown, a).

8. browser_screenshot

Capture a PNG screenshot (base64).

POST/GET http://127.0.0.1:18795/api/screenshot?tabId=&fullPage=true

Full-page captures use layout metrics plus a clipped screenshot when possible, then fall back to Chrome's captureBeyondViewport path. Returns: { ok: true, data: "base64...", format: "png", fullPage, strategy, width?, height?, bytes }

9. browser_eval

Evaluate arbitrary JavaScript in the page. The escape hatch.

POST http://127.0.0.1:18795/api/eval
Body: { "expression": "document.querySelector('h1').innerText", "tabId?": "..." }

10. browser_download

Get the URL of an image/media/link element.

POST http://127.0.0.1:18795/api/download
Body: { "selector": "img.profile-pic", "tabId?": "..." }

10. browserdownloadstart

Start a real Chrome download from a URL using the user's browser profile.

POST http://127.0.0.1:18795/api/download/start
Body: {
  "url": "https://example.com/file.pdf",
  "filename?": "files/file.pdf",
  "saveAs?": false,
  "conflictAction?": "uniquify|overwrite|prompt"
}

Returns: { ok: true, downloadId, id, options }

11. browser_downloads

List Chrome downloads plus recent Browser Relay download events.

GET http://127.0.0.1:18795/api/downloads?limit=20&state=complete
POST http://127.0.0.1:18795/api/downloads/clear

Use this after browser_download_start to verify completion or diagnose interruptions.

Real downloads require the extension's downloads permission. If Browser Relay was already loaded in Chrome before this capability was installed, reload the unpacked extension in chrome://extensions.

Agent Decision Workflow

When asked to do something with a web page:

  1. browser-relay tabs first — discover available tabs and their URLs
  2. browser-relay navigate if needed — go to the target page
  3. browser-relay snapshot — understand the page structure
  4. Plan actions based on snapshot (click what, type where)
  5. Execute (browser-relay click, browser-relay type, browser-relay key, browser-relay scroll) one at a time
  6. browser-relay wait for the next expected element after navigation or an action; do not guess with fixed sleeps
  7. browser-relay console if the page behaves unexpectedly or after risky actions
  8. browser-relay network if a request fails, hangs, or the UI changes without visible errors
  9. Re-snapshot after each action to verify state
  10. Use browser-relay download-start and browser-relay downloads for real file downloads
  11. Screenshot if visual confirmation is needed

Example Session

# 1. List tabs
browser-relay tabs
# ABC123    Google    https://google.com

# 2. Take snapshot to see the page
browser-relay snapshot --tab ABC123
# [input type=text name=q placeholder="Search Google"]
# [button "Google Search"]

# 3. Type into the search box
browser-relay type 'browser relay' --selector 'input[name=q]' --submit --tab ABC123

# 4. Wait for results instead of sleeping
browser-relay wait 'a[href*="github.com"]' --state visible --timeout 10000 --tab ABC123

# 5. New snapshot after navigation
browser-relay snapshot --tab ABC123

# 6. Click a result
browser-relay click 'a[href*="github.com"]' --tab ABC123

MCP Registration (Claude Desktop / Cursor / Windsurf)

Add to your MCP config (~/.claude/mcp.json or equivalent):

{
  "mcpServers": {
    "browser": {
      "command": "browser-relay-mcp",
      "env": {
        "BROWSER_RELAY_URL": "http://127.0.0.1:18795"
      }
    }
  }
}

Error Patterns

| Error | Meaning | Fix | |-------|---------|-----| | Extension not connected | Relay server is running but no browser extension connected | Check that Chrome is running with the Browser Relay extension installed | | No attached tabs | Extension connected but no tab is attached | The extension auto-attaches all regular tabs. Make sure at least one non-chrome:// tab is open | | Element not found: selector | The CSS selector did not match anything on the page | Try a different selector, or take a snapshot first to inspect the DOM | | wait_timeout | The selector did not reach the requested attached/visible state before timeout | Re-snapshot the page, check the selector, or retry when the page is expected to load more slowly | | Session with given id not found (-32001) | The relay holds stale session state (e.g. after an extension reload) | Run browser-relay fix — restarts the relay and clears stale sessions; the extension reconnects automatically |

Health Check

curl http://127.0.0.1:18795/
# → OK

curl http://127.0.0.1:18795/api/debug
# → { "version": "", "connected": true/false, "tabCount": N }

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.