firefox-use
firefox-use
Browser control for Claude Code, on Firefox.
Claude Code can drive Chrome. This drives Firefox, with the same tools under the same names: screenshots and clicks, typing and keys, forms, tabs, page reading, console and network logs, file uploads, and GIF recordings of a whole flow. A browser task written for one browser runs on the other.
It talks to Firefox over WebDriver BiDi, which Firefox speaks natively - no extension, no
geckodriver, and no npm dependencies: the WebSocket client, the MCP server, the PNG
decoder and the GIF encoder are all in src/, on Node built-ins.
you: "log into the staging site and screenshot the dashboard"
-> read_page finds the form, form_input fills it, computer clicks and screenshotsInstall
As a Claude Code plugin - the tools and the skill in one step, with the server bundled, so nothing is downloaded at install time:
claude plugin marketplace add leetomo2528/firefox-use
claude plugin install firefox-use@firefox-useFrom npm, if you would rather register it yourself:
npx firefox-use install # registers the MCP server with Claude Code
npx firefox-use install-skill # adds the usage skill to ~/.claude/skills
npx firefox-use doctor # checks Firefox, the profile, the port, the handshakeFrom source:
git clone https://github.com/leetomo2528/firefox-use.git
cd firefox-use && node bin/firefox-use install && node bin/firefox-use install-skillStart a new Claude Code session afterwards. Firefox launches by itself on the first tool call.
Needs Firefox 129+ and Node 18+. Developed and tested on macOS; Linux runs in CI. Windows is not supported yet.
The tools
Tool | What it does |
| The tabs this session can act on. Call it first |
| Open and close tabs of your own |
| Go to a URL, back, or forward |
| Click, double/triple/right click, hover, drag, type, keys, scroll, screenshot, zoom, wait |
| Accessibility tree with a |
| "the search box", "the accept button" - refs by description |
| Set a field by ref: text, number, checkbox, select |
| Readable text, markup stripped |
| Console output, filtered by a regex you supply |
| Requests with status, type, timing and size |
| Evaluate an expression in the page |
| Several calls in one round trip, stopping at the first error |
| Resize the window a tab lives in |
| Fill a file input; drop a screenshot onto a page |
| Record a flow and export an annotated GIF |
Plus three that are ours alone: firefox_status, firefox_restart, and firefox_dialog -
Chrome's integration is finished by a modal dialog, here you can answer it.
Command line
firefox-use start [url] # launch Firefox with BiDi enabled
firefox-use status # what is running, which profile, which tabs
firefox-use open <url>
firefox-use shot page.png [url] [--full]
firefox-use stop | restart | doctor
firefox-use mcp # the MCP server on stdio (what Claude Code runs)Options: --headless, --port <n>, --profile <dir>.
Environment: FIREFOX_BIN, FIREFOX_USE_PORT, FIREFOX_USE_PROFILE, FIREFOX_USE_HEADLESS=1,
FIREFOX_USE_DOWNLOADS, FIREFOX_USE_UPLOAD_ROOTS, FIREFOX_USE_AUTO_RESTART=0.
How it works
Claude Code ──stdio JSON-RPC (MCP)──▶ bin/firefox-use mcp
│
src/tools.js registry, shared session, downloads
src/pages.js navigate, tabs, javascript_tool, form_input, resize
src/a11y.js read_page, find, get_page_text
src/computer.js mouse, keyboard, screenshots, zoom
src/observers.js console and network capture
src/uploads.js file_upload, upload_image
src/gif.js/gifenc.js recording, PNG decode, GIF89a encode
src/batch.js browser_batch
│
src/session.js tab group, element refs, screenshots, input
src/bidi.js WebDriver BiDi commands and events
src/ws.js RFC 6455 client
▼
firefox --remote-debugging-port 9222Worth knowing:
A profile of its own at
~/.firefox-use/profile. Log in there once and it sticks; your everyday Firefox is never touched.firefox-use stopis the off switch.macOS launches through
open -n -a. A Firefox started as a child of the shell inherits the shell's permissions and dies with "Could not find profile folder" under macOS app-data protection;openhands the launch to launchd instead.A fixed 1280x800 viewport per tab, at devicePixelRatio 1, so screenshot pixels and click coordinates share one coordinate space.
resize_windowchanges it deliberately, per tab.Refs are minted per document. After a navigation, a ref from the old page reports that it is gone rather than resolving to whatever now sits at that index.
One automation session per browser. The server closes its session on shutdown;
firefox_restartclears one left behind by a crash.
Development
npm test # unit tests, no browser
npm run test:integration # + a real headless Firefox, end to end
npm run spec # generate the parity fixture from your Claude Code install
npm run sync-plugin # copy the skill into the plugin and stamp versionsnpm run spec writes .spec/chrome-tool-spec.json - the Chrome integration's tool
definitions, read out of the Claude Code binary on your own machine. test/parity.test.js
compares our schemas against it and test/prose.test.js checks that our wording is not
borrowed from it. The file is never committed; those tests skip without it.
Limits
The Firefox window is the whole world: no OS-level input, no
about:privileged pages.The accessibility tree covers the top-level document; cross-origin iframes are not walked (click by coordinate, or use
javascript_tool).One browser instance per port.
Notices
MIT licensed. An independent project - not affiliated with Mozilla or Anthropic. Tool names and parameter shapes match Claude Code's Chrome integration on purpose, so tasks are portable; the descriptions, the skill and the documentation are written for this project. See NOTICE.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/leetomo2528/firefox-use'
If you have feedback or need assistance with the MCP directory API, please join our Discord server