Bridge a WebSocket-connected AI agent to a live Firefox profile via a WebExtension and native messaging host.
┌─────────────┐ WebSocket ┌──────────────────┐ Native Messaging ┌─────────────────┐
│ Agent │◄──────────────────►│ Rust Host │◄───────────────────────►│ Firefox Extension│
│ (CLI/SDK) │ ws://127.0.0.1 │ (830KB binary) │ stdin/stdout JSON │ (JS required) │
└─────────────┘ :8766 └──────────────────┘ └─────────────────┘
- Agent connects to the local WebSocket server
- Rust native host forwards commands to the Firefox extension
- Extension executes browser actions and returns results
The entire bridge is written in Rust except for the browser extension (browsers only support JavaScript extensions).
Download the signed extension from GitHub Releases:
- Download
browser-agent-bridge-X.X.X.xpi - In Firefox, go to
about:addons - Click gear icon → "Install Add-on From File..."
- Select the downloaded XPI
# Build the Rust binaries
cd rust-cli
cargo build --release
# Install native messaging manifest
cd ..
./scripts/install-native-host.shWindows is supported for the core Firefox bridge flow when both release binaries are installed:
browser-windows-x64.exe- CLI clienthost-windows-x64.exe- Firefox native messaging host
Firefox still requires a native messaging host manifest registered under
HKCU\Software\Mozilla\NativeMessagingHosts\firefox_agent_bridge. Downstream installers such as
jcode browser setup can stage the host binary, write the manifest, and create this registry entry.
Known limitation: persistent browser session ... mode currently uses Unix-domain sockets and is
disabled on Windows. Direct one-shot browser commands and the native messaging host are expected to
compile and run on Windows.
# Install globally via cargo
cargo install --path rust-cli
# For Claude Code users - install the skill
browser setup claudeAgents can connect directly to ws://127.0.0.1:8766 and send JSON:
{"action": "navigate", "params": {"url": "https://example.com"}}The CLI is a convenience wrapper - the WebSocket API is the core interface.
Benchmark results (v1.0.0 - January 2026):
| CLI | Per-Command | Improvement |
|---|---|---|
Rust (browser) |
12ms | baseline |
Node.js (client.js) |
105ms | 8.75x slower |
The Rust CLI provides 88% faster command execution.
Use --timing flag for detailed breakdown:
browser --timing navigate '{"url": "http://example.com"}'
# Returns: {"_timing": {"total_ms": 156, "connect_ms": 0, "roundtrip_ms": 155}, ...}| Action | Total (ms) | Connect (ms) | Roundtrip (ms) |
|---|---|---|---|
| ping | 3-8 | 0 | 3-8 |
| navigate | 150-170 | 0 | 150-165 |
| getContent | 2-33 | 0 | 2-33 |
| type | 2-11 | 0 | 2-11 |
| click | 2-5 | 0 | 2-5 |
| fillForm | 3-10 | 0 | 3-10 |
| Task | Status | Commands | Total Time | Cmd Execution | Description |
|---|---|---|---|---|---|
| table-scrape | PASS | 3 | ~15s | ~0.2s | Extract 8-row data table |
| oauth-flow | PASS | 8 | ~40s | ~1s | Complete mock Google OAuth |
| contact-form | PASS | 4 | ~20s | ~0.15s | Fill and submit form |
| login-flow | PASS | 12 | ~25s | ~1.5s | Login and extract secrets |
Tested with Claude Code (claude-opus-4-5-20251101)
Timing breakdown:
- Total Time = LLM thinking + command execution (dominated by LLM API latency)
- Cmd Execution = actual browser commands only (~120ms/command average)
Note: Parallel E2E tests require isolated sessions (tabId) to avoid conflicts.
See benchmarks/README.md for the full benchmark suite and setup instructions.
Use the --timing flag for latency breakdown:
browser --timing ping
# {"pong": true, "_timing": {"total_ms": 5, "connect_ms": 0, "roundtrip_ms": 5}}See docs/setup.md, docs/api.md, and docs/performance.md for full details.
| Binary | Size | Purpose |
|---|---|---|
browser |
1.2MB | CLI for sending commands |
firefox-agent-bridge-host |
830KB | Native messaging host |
No Node.js runtime required.