Skip to content

About

Chromium extension to allow agents to interact with a specific browser tab

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Agent Tab Bridge

Agent Tab Bridge is a local-first Chromium extension for explicitly bridging an opted-in browser tab to local agent tooling.

It is designed for workflows where a user is already authenticated in their normal browser profile and wants to temporarily allow local tools to inspect or execute JavaScript in one tab. Access is opt-in per tab from the extension popup.

Safety Model

  • Disabled by default.
  • Enablement is per active tab.
  • An enabled tab stays bridged across reloads and navigation until the user disables it, closes it, or Chrome refuses extension access to the destination.
  • The extension requests access to all URLs so the explicit per-tab opt-in works on any page Chrome permits. The popup warns about this access before every enablement.
  • The bridge URL must be localhost: http://127.0.0.1:<port> or http://localhost:<port>.
  • The bridge serves CORS headers only to origins you list in allowedOrigins (empty by default), so arbitrary websites cannot queue commands.
  • Set a token in config.json to require Authorization: Bearer <token> on every bridge request except /health. With no token, the bridge runs unauthenticated and warns on startup.
  • Commands and results stay on the local machine unless you explicitly forward them elsewhere.

Configuration

config.json is the single source of truth, shared by the local bridge and the extension. It is gitignored (it may hold a token); config.example.json is the committed template.

npm run setup          # create config.json from config.example.json
# edit config.json as needed
Field Used by Purpose
host, port bridge Address the server binds to
bridgeUrl extension, CLI Localhost URL the extension and CLI dial
allowedOrigins bridge Origins allowed to make cross-origin (browser) requests
token bridge, extension, CLI Shared bearer token; empty disables auth
overrides extension, bridge Map production asset URLs to local files (see Script overrides)

manifest.json declares <all_urls> because Manifest V3 reads host permissions statically and the bridge must be able to re-inject its keepalive after cross-origin navigation. Chrome still blocks extension scripting on protected surfaces such as chrome:// pages.

Older config.json files may still contain an allowlist field. It is ignored and can be removed.

Install The Extension

  1. Run npm run setup to create config.json.
  2. Open chrome://extensions.
  3. Enable Developer mode.
  4. Click Load unpacked.
  5. Select this repository folder.
  6. Adjust config.json as needed, then reload the extension. The options page shows the active config read-only.

Install The Agent Skill

The bundled skill teaches Claude Code and Codex to discover and use the bridge. From the repository root, install it for both agents with:

for skills_root in "$HOME/.claude/skills" "$HOME/.agents/skills"; do
  mkdir -p "$skills_root"
  destination="$skills_root/agent-tab-bridge"
  if [ ! -e "$destination" ] && [ ! -L "$destination" ]; then
    ln -s "$PWD/.claude/skills/agent-tab-bridge" "$destination"
  fi
done

The command leaves an existing installation untouched. Restart the agent session after installing the skill.

Run The Local Bridge

npm run bridge

The bridge listens on http://127.0.0.1:3107 by default.

Menu bar app (macOS)

Instead of starting the bridge from a terminal, build the menu bar app once and run it:

npm run menubar            # builds menubar/AgentTabBridge.app
open menubar/AgentTabBridge.app

The menu bar item shows whether the bridge is running and how many tabs are bridged, lists those tabs, starts/stops the bridge, and has a Launch at login toggle. It manages bridge/server.js as a child process (logs to ~/Library/Logs/AgentTabBridge.log) and won't spawn a second server if one is already running. Rebuild with npm run menubar after pulling changes; the repo and node paths are baked in at build time. Enabling Launch at login the first time may need approval in System Settings → General → Login Items.

Use It

  1. Open a webpage in Chrome.
  2. Click the Agent Tab Bridge extension button.
  3. Click Enable for this tab.
  4. Send commands from the local CLI:
node bridge/client.js ping
node bridge/client.js snapshot
node bridge/client.js eval "document.title"

Screenshots return a PNG data URL:

node bridge/client.js screenshot

Multiple tabs

You can enable more than one tab; the toolbar badge shows how many are bridged and the popup lists them. Commands run in a single tab, so when several are enabled, name one with --tab <id>:

node bridge/client.js tabs                    # list enabled tabs and their ids
node bridge/client.js --tab 433920089 snapshot

With exactly one tab enabled the commands above work without --tab. With more than one and no --tab, the CLI stops and lists the tabs.

HTTP API

Queue a command:

curl -sS http://127.0.0.1:3107/api/command \
  -H 'content-type: application/json' \
  -d '{"type":"eval","code":"document.title"}'

Read bridge state:

curl -sS http://127.0.0.1:3107/api/clients
curl -sS http://127.0.0.1:3107/api/results

Command Types

  • ping: confirms the enabled tab is connected.
  • snapshot: returns URL, title, ready state, selected text, visible text, and active element summary.
  • screenshot: returns a visible-tab PNG data URL.
  • storage: dumps localStorage/sessionStorage keys with lengths and decodes any JWTs found in the values. Pass includeValues: true (CLI: --values) to include raw values (truncated to 4000 chars). Works on CSP-restricted pages because it injects a function, not an eval'd string.
  • eval: executes JavaScript in the enabled tab. The default execution world is MAIN; pass world: "ISOLATED" to run in the extension isolated world. On pages whose CSP forbids unsafe-eval (both worlds fail with an EvalError), the command automatically retries through the debugger API (CDP Runtime.evaluate), which is exempt from page CSP; pass backend: "cdp" (CLI: --cdp) to force that path. Chrome shows an "is debugging this browser" infobar for the duration of a CDP eval.

Eval results must be serializable. On the default path DOM elements are summarized instead of returned directly; on the CDP path results must be JSON-serializable (DOM nodes/functions are rejected by the protocol).

Script overrides (prototype in prod)

Swap a production script for a local file so you can prototype changes against a real, authenticated environment. The extension redirects the matching request (via declarativeNetRequest) to the bridge, which serves your file from overrides/.

  1. Put your file in overrides/ (e.g. overrides/flow-remoteEntry.js).

  2. Add a mapping to config.json and reload the extension:

    "overrides": [
      { "match": "remoteEntry.js", "file": "flow-remoteEntry.js" }
    ]
  3. Enable the target tab from the popup, then reload the page. The popup warns while overrides are active.

  • match is a declarativeNetRequest urlFilter (substring / *) tested against the request URL.
  • Overrides are scoped to enabled tabs and strip the page's content-security-policy on those tabs, because a strict script-src would otherwise block the localhost script. This is a real, temporary security relaxation — keep overrides empty when you're not prototyping.
  • Files are served with Cache-Control: no-store, so edits apply on the next reload. No page reload happens automatically.
  • No SRI on UiPath bundles today, so swapped scripts aren't rejected by integrity checks (verified against captured traffic).

About

Chromium extension to allow agents to interact with a specific browser tab

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages