Claude in Chrome only works in Chrome, and I use Firefox. So I built Firefox Agent Bridge, which gives Claude Code the same browser tools in Firefox. Then I spent two days and about 1,200 eval runs benchmarking it against Claude in Chrome and fixing whatever the traces showed, until it was faster and cheaper on all 16 tasks.

Same prompt, same model (Sonnet 5.5, high effort): find the cheapest nonstop SFO to JFK round trip on Google Flights. Both found the same $414 flight. One take each, the median of three, played at 3x.
1.7xfaster per task
14.9s vs 25.5s
2.1xfewer input tokens
56k vs 119k
28%cheaper per task
$0.058 vs $0.080
16/16tasks faster
and cheaper

What it does

  • Same tools as Claude in Chrome (navigate, computer, find, read_page and the rest), for Claude Code, Codex or the Claude desktop app.
  • The agent gets its own tab group and works in the background. It never takes focus or moves your cursor.
  • A sidebar chat that runs Claude Code on your existing plan, plus a few things Chrome doesn’t have: ⌥-click an element to ask about it, teach a task by doing it once, start a task from the address bar or your phone.
  • Password and card fields are masked before a screenshot or page read leaves the browser.
Claude in the Firefox sidebar, drawing a timeline in Excalidraw with the mouse. It works in its own tab group in the background.
All 14 tools and what each does

The first eleven have the same names and arguments as Claude in Chrome. batch and replay_steps are the bridge’s own, and devtools is off unless you turn it on.

ToolWhat it does
tabs_context_mcpLists the tabs in the session’s tab group
tabs_create_mcpOpens a background tab in the group
tabs_close_mcpCloses one of the session’s tabs
navigateGoes to a URL, back or forward, and returns once the page is parsed
computerScreenshot, zoom, click, hover, drag, type, key and scroll, by coordinate or element ref
read_pageA compact text tree of the page’s roles and names, across every frame
findKeyword search over element names, roles and labels. Returns the best 8 matches
get_page_textThe page’s readable text
form_inputSets one field, or several in one call
javascript_toolRuns a script in the page. The page’s CSP doesn’t block it
file_uploadFills a file input without opening the native picker
batchRuns up to 20 actions in one call and stops at the first that fails
replay_stepsReplays a task you taught it, without the model, until a step doesn’t match
devtoolsReads the console and network requests

Agent Bridge vs the alternatives

Firefox already has a few ways to let software drive it, and Chrome has Claude in Chrome. None of them gave me an agent that works in my own logged-in Firefox while I keep using it.

  • Smart Window, Mozilla’s AI mode, reads the tabs you share but can’t click or fill a form. It runs on Mozilla’s models, not the Claude plan I already pay for.
  • Mozilla’s DevTools MCP is a debugging tool. It warns against pointing it at your regular profile, and it has nothing to show what the agent is doing or to stop it.
  • Playwright MCP and WebDriver BiDi start a separate automation browser, so none of my logins come along.
  • Claude in Chrome comes closest, but it only runs in Chrome and only with Claude. It is also slower and reads about twice the tokens, which the benchmark below measures.

That gap is why the bridge exists. Row by row:

Firefox Agent BridgeClaude in ChromeFirefox Smart WindowMozilla DevTools MCPPlaywright MCPWebDriver BiDi
Reach
Works in Firefox✓yes✕no✓yes✓yespartlyits own Firefox build✓yes
Uses your real profile and logins✓yes✓yes✓yespartlywarns against it✕noseparate browser✕noseparate session
Clicks, types and fills forms✓yes✓yes✕noplanned✓yes✓yes✓yes
Works in background tabs, never takes focus✓yespartlywindow must be visible–doesn't applypartlyheadlesspartlyheadlesspartlyhidden tabs stop rendering
Sees and acts inside cross-origin iframes✓yespartlyneeded workarounds✕nopartly✓yespartlyclient picks the frame
Start a task from anywhere✓yesterminal, sidebar, address bar, phonepartlyside panelpartlyin the window✕noterminal✕noterminal–doesn't apply
The agent
Bring your own subscription✓yesClaude or ChatGPTpartlyClaude only✕nofree, Mozilla's models✓yes✓yes–doesn't apply
Choice of agent✓yesClaude Code, Codex, Claude desktop✕noClaude onlypartlyMozilla's list✓yes✓yes–doesn't apply
Runs locally, with your files and shell✓yespartlythrough Claude Code✕no✓yes✓yes–doesn't apply
Memory and skills carry across sessions✓yespartlypartly✓yes✓yes–doesn't apply
Same tools as Claude in Chrome✓yes✓yes✕no✕no✕no✕no
Measured time and input tokens per task14.9s, 56k25.5s, 119k–doesn't applynot measurednot measurednot measured
Safety and traceability
Passwords and cards masked before they leave the browser✓yes✕no✕no✕no✕no✕no
Shows which agent is driving which tabs✓yes✓yes–doesn't apply✕no✕nopartlyone robot icon
Stop all, or disconnect one client✓yespartlystop only–doesn't apply✕no✕no✕no
Activity log of every call✓yes✕no–doesn't apply✕no✕no✕no
Open source✓yes✕no✓yes✓yes✓yes✓yes
Past parity
Teach a task by doing it, replay without the model✓yespartlyshortcuts✕no✕no✕no✕no
Point at an element to ask about it✓yes✕no✕no✕no✕no✕no
Live agent cam, save as GIF✓yespartlyGIF tool✕no✕no✕no✕no
What it costs
Installs in a regular browser, signed✕noDeveloper Edition only✓yes✓yes✓yes✓yes✓yes
Built on stable, supported APIs✕no✓yes✓yes✓yes✓yes✓yes
Asks before acting on each sitepartlyper action, opt-in✓yes–doesn't apply✕no✕no✕no

✓ yes partly ✕ no – doesn't apply

The last three rows are what the rest cost me.

Getting real clicks out of Firefox

Chrome extensions can send real input through chrome.debugger. Firefox extensions can’t, and a lot of sites ignore the untrusted events a normal extension can fire. So the bridge ships a WebExtension Experiment, privileged code that Developer Edition will load. It puts an actor in every frame and sends input from privileged code, so pages see real, trusted clicks and keystrokes.

One click, from the model to the page. Click a box to see what it does.

The catch is that it depends on internal APIs. I wrote up what WebDriver BiDi would need to do the same thing on stable ground.

The benchmark

16 tasks, 3 runs each per browser, same model (Sonnet 5.5) and prompt. Articles, lists, five-page comparisons, Wikipedia link chains, search, infinite scroll, forms, a date picker, a virtualized table and a dropdown inside an embedded frame.

Median per taskFirefox, first runFirefox, nowClaude in Chrome
Passed48/4848/4847/48
Time19.1s14.9s25.5s
Input tokens60k56k119k
Cost$0.062$0.058$0.080
Per click697ms122ms161ms

Median time per task, log scale. The frame dropdown went from Firefox's slowest task to the middle of the pack. Hover or tap a task for what it asks and its numbers.

Why it’s faster and cheaper

Three reasons, and the traces can separate them.

Tool calls return sooner. The model waits on every call, and Firefox’s come back faster:

Mean per callFirefoxClaude in Chrome
List the session’s tabs45ms1.9s
A computer action (click, type, scroll)84ms1.4s
Run JavaScript in the page1.6s3.7s

Every turn starts smaller. Claude in Chrome offers the model 22 tools and the bridge offers 13, and every tool’s definition is sent again on every turn. On the three article tasks both browsers made the same 4 calls over the same 5 turns and got the same text back, yet Chrome read about 5,500 more tokens on each turn. Across all 16 tasks a turn costs 8k input tokens in Firefox and 14.5k in Chrome. I think the longer tool list is most of that gap, though I can’t see Chrome’s definitions to count them. It’s also why devtools is opt-in here.

Fewer steps. This one wasn’t true at first. Where Firefox was behind in the first run, the traces showed why:

Where Firefox was behindFixResult
Five package pages or a long form took twice the callsA batch tool and multi-field form_inputPyPI compare: 13 calls → 5
Couldn’t see into MDN’s example, a cross-origin frame in a shadow rootfind and read_page walk every child frame71 calls → 9
Every click waited 500ms in case it opened a tabWait 100ms unless it targets a new tab, and skip the cursor animation in background tabs697ms → 122ms
navigate waited for the load eventReturn once the page is parsed1.9s → 0.6s

Cost follows the tokens, but by less: 28% against 2.1x, because most of those extra tokens are cached reads, which are cheap.

Chrome’s find asks a model to match elements. It failed on 5 of its 15 calls here, and its tokens aren’t in Chrome’s counts, so Chrome’s real cost is a little higher than shown.

Ideas I tested and dropped

Each idea ran against the same tasks without it, before it got built or kept.

IdeaWhat happenedKept?
One sub-agent per page18–41% faster on five-page comparisons, at 2.75x the costFor 4+ pages
Reader view before readingLost paragraphs on 6 of 22 sites (BBC kept a third)No
Read the site’s JSONConfidently answered 62. The answer was 41.No
Hint Sonnet to batch its stepsShown on 68 results; Sonnet didn’t batch any moreNo
A screenshot alias toolFake screenshot calls went to 0, other made-up tools went from 3 to 17No
Cap page text lengthSlower, since long articles need the whole pageNo
Return from navigate once parsed0.6s instead of 1.9s per page, no passes lostYes

The tool-wording changes did the least. How Sonnet behaves barely moved with anything I put in a description.

Which Claude model should drive it

Round 1 used six long tasks. Sonnet 5.5, Opus 5.5 and Fable 5.1 passed all 162 runs at every effort level, so it only told me about cost. Haiku 4.5 passed 10 of 18, and every failure ended with it saying it had succeeded.

Round 2 needed harder tasks. The first two drafts were still too easy because Sonnet just wrote JavaScript around them, so five of the six ban it. The tasks: count 582 table rows, read 167 star ratings shown as icons, solve an Evil sudoku, draw a 13-shape tldraw grid, work through UI Testing Playground’s tricky widgets, and apply the 2026 World Cup tie-break rules.

Mean score, hard tasksLowMediumHigh
Sonnet 5.50.9350.9300.994
Opus 5.50.9810.9890.991
Fable 5.10.9911.0001.000
  • Sonnet high matched Opus at every effort level for about 0.7x the cost, so it’s now the sidebar default.
  • Fable was the most reliable, 53 of 54, at 3–4x Sonnet’s cost.
  • Effort mostly helps with rules. Over 216 more Sonnet runs, high passed 90% against low’s 80%, and nearly all of that gap is the World Cup task.

Sonnet 5.5 passes out of 18 per task: 6 runs on the plain tools, 12 with one small tool tweak on, at both effort levels. Hover or tap a task for what it asks.

Still open

  • The Space fix has tests but I haven’t tried it by hand yet.
  • Sonnet still makes up a left_click call now and then.

To try it you need Firefox Developer Edition or Nightly, and a separate profile, because the install turns signature checks off for it. scripts/install.sh does the rest. It depends on internal APIs, so a Firefox update can break it.

Code, eval harness and every result file are in the repo, with the full tables in the eval README.