Control Firefox browsers (Floorp, LibreWolf, Zen, Firefox) from any MCP client.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
We haven't yet run this listing's install command through our automated sandbox check. This isn't a red flag β we're steadily working through the catalog.
π‘ Paste into ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows)
Inspect callable tools, capabilities, and parameters exposed to AI agents by Gecko Mcp.
list_tabsList all open tabs (title, URL, browserId, active, pinned).
open_tabOpen a new tab at a URL; **returns the new tab's `browserId`** so you can target it.
get_active_tabReturn the active tab's title, URL and browserId.
navigate_tabNavigate an existing tab to a URL.
close_tabClose a tab.
read_pageRead a tab's content as clean Markdown (or HTML / accessibility tree). Output is capped (default 25 KB) to protect the context.
An MCP (Model Context Protocol) server that lets AI assistants β Claude Code, Claude Desktop, Cursor, and any MCP client β read pages, take screenshots and manage tabs in Floorp and other Firefox-based browsers (LibreWolf, Waterfox, Zen, Mullvad, Firefoxβ¦), using your real, logged-in session.
Think "Claude in Chrome", but for the whole Firefox/Gecko family.

Get started in ~30 seconds:
Registers gecko-mcp with Claude Code, Claude Desktop, Cursor, VS Code (Copilot), Windsurf, Zed, Codex and more β per-project or global. See Setup for manual config and Requirements for the one-time browser step.
Cautious about installing this? Good β you should be. It's small (2 deps, all in
src/), the OS keyboard/mouse is locked by default (browser-only until you opt in), releases ship with npm provenance (verifiable against this source), and the full threat model is in SECURITY.md. Read it before you runnpx gecko-mcp.
gecko-mcp talks to the browser through one of two backends, picked automatically:
floorp.mcp.enabled = true
in about:config and gecko-mcp uses the fast http://127.0.0.1:58261 API β
no extension, richest feature set.floorp.mcp.enabled to true in about:config, restart Floorp.-marionette (see Browser support).An interactive wizard registers gecko-mcp with the AI coding tool(s) of your choice β Claude Code, Cursor, Windsurf, VS Code (Copilot), Gemini CLI, Codex, Zed, Cline (and a copy-paste snippet for Kimi Code, Antigravity, or any other MCP client) β and lets you install it for the current project or globally (all repos). It merges into existing config (and backs it up first).
Non-interactive / scriptable:
Any MCP client works with this server block (no clone/build needed β npx
fetches it):
Or with Claude Code's CLI: claude mcp add gecko -s user -- npx -y gecko-mcp.
One-time Floorp step: set
floorp.mcp.enabled = trueinabout:configand restart Floorp so its automation API is available.
gecko-mcp picks its backend automatically: if Floorp's :58261 API is reachable
it uses that; otherwise it connects to Marionette, the automation engine built
into every Gecko browser. To use a non-Floorp browser, launch it once with
Marionette enabled:
| Browser | Launch with Marionette |
|---|---|
| Floorp | (no flag β just set floorp.mcp.enabled=true; uses the native API) |
| Firefox | firefox -marionette |
| LibreWolf | librewolf -marionette |
| Waterfox | waterfox -marionette |
| Zen | zen -marionette |
| Mullvad | mullvad-browser -marionette |
Marionette listens on TCP 2828 by default. To use another port, set the
marionette.port pref in the profile (e.g. via user.js) and start gecko-mcp
with a matching MARIONETTE_PORT. Force a backend with GECKO_MCP_BACKEND=marionette.
Note: Marionette must be enabled at launch to attach to your live session. On the Marionette backend, Floorp-only extras (
snapshotfingerprints,list_workspaces/switch_workspace, accessibility tree) return a clear "not supported" message β usefind/read_pageinstead. Everything else (tabs, navigation, click, type, forms, screenshots, cookies, real OS inputβ¦) works.
Tabs & reading
| Tool | What it does |
|---|---|
list_tabs | List all open tabs (title, URL, browserId, active, pinned). |
open_tab | Open a new tab at a URL; returns the new tab's browserId so you can target it. |
get_active_tab | Return the active tab's title, URL and browserId. |
navigate_tab | Navigate an existing tab to a URL. |
close_tab | Close a tab. |
read_page | Read a tab's content as clean Markdown (or HTML / accessibility tree). Output is capped (default 25 KB) to protect the context. |
find | Fast element locator β search a page server-side by visible text and/or tag; returns a compact list of ready-to-use CSS selectors (~1 KB) instead of the whole HTML. Use it to find a button/link/field, then act on the selector. |
snapshot | Structured page map: Markdown with inline fp: refs + an element selector map β locate elements without grepping HTML, then act via a ref. |
screenshot | Capture a screenshot of a tab (viewport or full page). |
launch_floorp | Ensure Floorp is running β launches it if the API isn't reachable (Windows). |
launch | Start any Firefox-based browser (Firefox, LibreWolf, Zenβ¦) with Marionette enabled so gecko-mcp can drive it. |
Interaction
| Tool | What it does |
|---|---|
click | Click an element by CSS selector or a ref from snapshot; auto-scrolls it into view first. |
type_text | Type into an input/textarea β or a rich/contenteditable editor (Slate, ProseMirrorβ¦) β by CSS selector. |
fill_form | Fill multiple fields at once. |
press_key | Press a keyboard key (Enter, Tab, β¦). |
wait_for_element | Wait for an element to attach / become visible / etc. |
get_value | Sensitive. Read the current value of an input/textarea/select (can read password fields). |
Most tools target the active tab by default; pass a browserId (from
list_tabs) to target a specific tab.
The tools below can affect things outside the browser, so they are disabled
until you turn them on. With nothing set, gecko-mcp does browser automation only.
Unlock them per-session by just asking ("enable OS input", which calls the
enable_os_input tool), or persistently with GECKO_MCP_ENABLE_OS_INPUT=1. Lock
again with disable_os_input. While locked, these tools refuse with a clear message.
The evaluate tool (run arbitrary page JavaScript) is locked the same way β
unlock with enable_evaluate or GECKO_MCP_ENABLE_EVALUATE=1.
| Tool | What it does |
|---|---|
enable_os_input / disable_os_input | Unlock / re-lock the OS keyboard & mouse tools for this session. |
enable_evaluate / disable_evaluate | Unlock / re-lock the evaluate (run page JS) tool for this session. |
evaluate | Locked. Run JavaScript in the page and return its value (return β¦). |
Real OS keyboard (Windows) β for React/rich editors and bot-guarded submits that ignore synthetic input:
| Tool | What it does |
|---|---|
real_type | Type into the focused element via genuine OS key events (isTrusted). |
real_key | Press a real key/combo, e.g. "Enter", "ctrl+a". |
real_clear | Real Ctrl+A + Delete β reliably clears a rich/contenteditable field. |
These produce input a page can't distinguish from a human's, so they drive
React/Slate editors and submit composers that synthetic clicks/typing can't.
Workflow: click the field to focus it β real_clear / real_type / real_key "Enter".
Safety guard: OS keystrokes go to the foreground window, so before sending anything these tools bring Floorp to the foreground and verify it β if Floorp isn't running or can't be focused, they abort without typing a single key, so input can never leak into another app.
Real OS mouse (Windows) β genuine isTrusted clicks at screen coordinates:
| Tool | What it does |
|---|---|
window_bounds | Floorp's window rectangle in screen pixels (to compute targets). |
move_cursor | Move the real OS cursor to a screen pixel inside Floorp. |
real_click | Real OS click (left/right, single/double) at a screen pixel inside Floorp. |
Double guard: the click is sent only when Floorp is verified foreground and the point lies inside Floorp's window rect β a stray coordinate is refused, so a click can never land in another app/window. Coordinates are screen pixels (note display scaling/DPI when mapping from a screenshot).
More interaction & queries
| Tool | What it does |
|---|---|
hover / double_click / right_click | Mouse gestures on an element (selector or ref). |
select_option | Choose an option in a <select>. |
set_checked | Check/uncheck a checkbox or radio. |
submit_form | Submit a form. |
upload_file | Sensitive. Set a file <input> by absolute path β restrict with GECKO_MCP_ALLOW_UPLOAD_DIRS. |
get_attribute | Read an element attribute (href, value, β¦). |
get_article | Readability-extracted main article as Markdown. |
get_cookies | Sensitive. Cookies visible to the page β values redacted unless includeValues: true. |
wait_for_network_idle | Wait for network activity to settle. |
list_workspaces / switch_workspace | Floorp workspaces (where supported). |
Understand the threat model before enabling this. Two risks dominate:
floorp.mcp.enabled is on, any local process can drive your logged-in
browser via 127.0.0.1:58261 β not just this server. There is also no
Origin check, so hostile web pages may attempt CSRF/DNS-rebinding tricks
against it. Mitigations:
floorp.mcp.enabled off when you're not using automation.GECKO_MCP_TOKEN environment variable β this server then sends it
as a Bearer token on every request (effective on Floorp builds that
enforce a token; harmless otherwise).Hardening built into this server:
enable_os_input tool, or GECKO_MCP_ENABLE_OS_INPUT=1). By default gecko-mcp
can only automate the browser, never your wider machine.open_tab/navigate_tab accept only http(s)
(and about:blank) by default, and refuse loopback/private hosts
(127.0.0.1, localhost, 10/8, 172.16/12, 192.168/16, 169.254/16,
IPv6 ULA/link-local). This stops a prompt-injected agent from pivoting the
browser onto Floorp's own API or your LAN and reading the response back. Lift
with GECKO_MCP_ALLOW_PRIVILEGED_URLS=1. Optionally pin navigation to a
domain allowlist with GECKO_MCP_ALLOW_DOMAINS.get_cookies; raw values require
an explicit includeValues: true.get_value can read secrets: browsers let same-origin JS read password
fields, so this tool can return a typed password. It's flagged SENSITIVE β
use it only on fields the user asked about, never to harvest credentials.GECKO_MCP_ALLOW_UPLOAD_DIRS (;-separated
directories) to confine upload_file. Paths are canonicalised with realpath
(symlinks resolved) and checked so .., a symlink, a same-prefix sibling
directory, or a UNC path can't escape the allowed folders.find skips hidden elements (inline display:none/visibility:hidden,
hidden, type=hidden, aria-hidden) so a page can't lure the agent into
clicking an invisible button via text search.maxChars, find limit, typed text, form fields) to
prevent resource-exhaustion / crash inputs.GECKO_MCP_PORT is validated as 1β65535.readOnlyHint/destructiveHint/β¦) so your client can auto-run read-only
tools and confirm destructive ones (close_tab, navigate_tab, submit_form,
upload_file). A server can't show prompts itself β approval is the client's
job β so this is how gecko-mcp tells the client what's safe vs consequential.evaluate tool: arbitrary page-JS execution is deliberately not exposed.What is not defended (inherent / Floorp-side): a malicious local process can
still read or impersonate the unauthenticated loopback API (plaintext, no TLS), and
prompt injection from a page you choose to automate can still drive legitimate
actions on that page. Disable floorp.mcp.enabled when idle and don't automate
untrusted sites unattended.
| Environment variable | Effect |
|---|---|
GECKO_MCP_TOKEN | Sent as Authorization: Bearer β¦ to the Floorp API. |
GECKO_MCP_PORT | API port (default 58261, validated 1β65535). |
GECKO_MCP_ALLOW_PRIVILEGED_URLS | 1 allows non-http(s) URLs and loopback/private hosts in open/navigate. |
GECKO_MCP_ALLOW_DOMAINS | Comma-separated domain allowlist for navigation (subdomains included). Unset = any public host. |
GECKO_MCP_ALLOW_UPLOAD_DIRS | Restrict upload_file to these directories (;-separated). |
FLOORP_PATH | Full path to floorp.exe for launch_floorp. |
GECKO_MCP_BACKEND | Force the backend: floorp or marionette. Default: auto-detect. |
MARIONETTE_PORT | Marionette TCP port for non-Floorp browsers (default 2828). |
GECKO_MCP_ENABLE_OS_INPUT | 1 unlocks the OS keyboard/mouse tools at startup (otherwise locked until the enable_os_input tool is called). |
GECKO_MCP_ENABLE_EVALUATE | 1 unlocks the evaluate (run page JS) tool at startup (otherwise locked until enable_evaluate). |
GECKO_MCP_BROWSER_PROCESS | Process-name regex the real OS keyboard/mouse may target (default covers the common Gecko forks). |
The legacy
FLOORP_MCP_*variable names still work as fallbacks (from before the rename), so existing configs keep working β preferGECKO_MCP_*going forward.
find searches the page server-side and returns
~1 KB of ready-to-use selectors instead of dumping the whole HTML, and
read_page is capped (default 25 KB) so a page read can't flood the context.powershell.exe
(~700 ms) and compiling the P/Invoke helper (~600 ms) used to happen on every
real_*/move_cursor/window_bounds call (~1.9 s each). Now one host is
started lazily, compiles once, and runs a read-eval loop β so the first call
pays ~1.6 s but every call after is ~350 ms for a guarded key/click (~5Γ
faster) and a few ms for a window-bounds query. The foreground/bounds safety
guards still run on every command; the host is recycled if it hangs or dies.Learned from driving real apps (incl. Google Flow):
type_text handles plain inputs and contenteditable editors
(Slate, ProseMirror, Lexical) β it falls back to dispatching a real text-input
event when an element has no .value. Reliably clearing such editors isn't
solved yet (no select-all/evaluate).press_key "Enter" over click for those.isTrusted=true from page JavaScript β it
is a browser security invariant. Floorp injects input at a privileged layer, so
ordinary clicks/keys behave like real ones; but flows guarded by reCAPTCHA or
strict bot-detection may still refuse automated submission.evaluate: the page-JS eval endpoint returns HTTP 404 on some Floorp builds,
so it is not exposed as a tool here.browserId returned
by open_tab, or one from list_tabs, and pass it explicitly to every tool.real_type / real_key / real_clear, with a
foreground safety guard β drives React/Slate editors & bot-guarded submitssnapshot (fingerprint refs + selector map) + click by ref + auto-scroll-into-viewlaunch_floorp β start Floorp if not running (Windows)window_bounds / move_cursor / real_click, with a
foreground + in-window-bounds double guardevaluate (available in newer Floorp builds; older ones return HTTP 404)launch helper for non-Floorp browsers (start them with -marionette)Built against the automation API exposed by Floorp. The official
Floorp-Projects/floorp-mcp-server
was a useful reference for mapping the endpoint surface. This is an independent,
clean-room MIT-licensed implementation.
MIT Β© Frumane
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/gecko-mcp)<a href="https://allmcps.com/mcp/gecko-mcp"><img src="https://allmcps.com/api/badge/gecko-mcp?style=directory" alt="Gecko Mcp on AllMCPs" /></a>