Skip to main content

Firefox Browser MCP — Server

An MCP server that lets an LLM client drive a real Firefox browser — every tab, its DOM, arbitrary CSS selectors, and its network/API traffic. It talks to the companion firefox-extension/ WebExtension over a local WebSocket bridge.

MCP client (Claude Desktop, etc.)
        │  stdio (MCP)
        ▼
firefox-browser-mcp  ──ws://127.0.0.1:9010──►  Firefox extension  ──►  All tabs

Run with uvx

uvx --from ./mcp-server firefox-browser-mcp

Once published to PyPI: uvx firefox-browser-mcp.

CLI options

Connection settings can be passed as arguments (they override the FBMCP_* env vars):

uvx firefox-browser-mcp --host 127.0.0.1 --port 9010 --log-level INFO
uvx firefox-browser-mcp --version
uvx firefox-browser-mcp --help
Flag Default Env fallback
--transport stdio FBMCP_TRANSPORT
--host 127.0.0.1 FBMCP_HOST
--port 9010 FBMCP_PORT
--http-host 127.0.0.1 FBMCP_HTTP_HOST
--http-port 8000 FBMCP_HTTP_PORT
--log-level INFO FBMCP_LOG_LEVEL

The Firefox extension connects to this bridge; use the extension popup's Enable/Disable toggle to turn the connection on or off.

Transports (--transport)

  • stdio (default) — the MCP client spawns one process per session, so the bridge lives only while a client session is open.

  • sse / streamable-http — run the server once as an always-on HTTP service the client connects to by URL. The WebSocket bridge is tied to the HTTP server's lifetime, so it stays up across client sessions and the extension can stay connected continuously:

    uvx firefox-browser-mcp --transport sse --http-port 8000 --port 9010
    # MCP endpoint:  http://127.0.0.1:8000/sse   (streamable-http -> /mcp)
    

    Configure the client with a URL instead of a command:

    { "mcpServers": { "firefox-browser": { "url": "http://127.0.0.1:8000/sse" } } }
    

Configure your MCP client

{
  "mcpServers": {
    "firefox-browser": {
      "command": "uvx",
      "args": ["--from", "/absolute/path/to/mcp-server", "firefox-browser-mcp"]
    }
  }
}

Targeting tabs

Every tab has a stable numeric id (plus title and url). Get them with browser_list_tabs. Most tools accept an optional tab argument:

tab value Meaning
omitted the currently active tab
123 / "123" the tab whose id is 123
"github.com" first tab whose url contains it
"Inbox" first tab whose title contains it

Environment variables

Variable Default Description
FBMCP_TRANSPORT stdio MCP transport (stdio/sse/streamable-http)
FBMCP_HOST 127.0.0.1 WebSocket bridge host
FBMCP_PORT 9010 WebSocket bridge port
FBMCP_HTTP_HOST 127.0.0.1 SSE/HTTP MCP endpoint host
FBMCP_HTTP_PORT 8000 SSE/HTTP MCP endpoint port
FBMCP_LOG_LEVEL INFO Python logging level

If you change the port, update the bridge URL in the extension popup.

Tools

Tabs — browser_list_tabs (id/title/url of every tab, all windows), browser_select_tab, browser_new_tab, browser_close_tab.

Navigation — browser_navigate, browser_go_back, browser_go_forward, browser_reload.

Inspection & extraction — browser_snapshot (accessibility tree with ref ids), browser_query (any CSS selector → refs, text, attributes, html), browser_get_text, browser_get_html, browser_get_attribute, browser_eval (run JS and return the result), browser_get_url, browser_screenshot, browser_get_console_logs.

Network / API — browser_get_network (captured requests with method, url, status, content-type, request & response bodies), browser_clear_network.

Interaction — browser_click, browser_type, browser_hover, browser_select_option, browser_press_key, browser_scroll, browser_wait. Interaction tools accept either a ref (from snapshot/query) or a CSS selector.

Status — browser_status.

Examples (what an agent can do)

  • "List my tabs, then read the article in the tab with 'wikipedia' in its url": browser_list_tabs → browser_get_text(tab="wikipedia").
  • "Grab all product prices": browser_query(selector=".price") or browser_eval(script="return Array.from(document.querySelectorAll('.price')).map(e=>e.textContent)").
  • "Show the API calls this page made": browser_get_network(filter="xmlhttprequest") (includes JSON response bodies).
  • "Log into the form": browser_type(selector="#email", text=...), browser_type(selector="#password", text=..., submit=True).

Development

cd mcp-server
uv venv && source .venv/bin/activate
uv pip install -e .
python -m firefox_browser_mcp.server

Metadata

Release files for firefox-browser-mcp 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for firefox-browser-mcp 0.2.1
File Size Uploaded Provenance
firefox_browser_mcp-0.2.1.tar.gz 9.5 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for firefox-browser-mcp 0.2.1
File Interpreter ABI Platform
firefox_browser_mcp-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 20.9 kB

Release files / firefox_browser_mcp-0.2.1.tar.gz

Download URL firefox_browser_mcp-0.2.1.tar.gz
Size 9.5 kB
Tags Source
SHA-256 checksum
How to use checksums
2bf0f2946115b7bf9af9bb400920da24b939a343a9a253ea577ab4d81074bc24
BLAKE2b-256 checksum
How to use checksums
79aa97d4ca8e0f88c3625b6e419188ded53290d3cd108a0a1db9c9d3353e8f7d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release files / firefox_browser_mcp-0.2.1-py3-none-any.whl

Download URL firefox_browser_mcp-0.2.1-py3-none-any.whl
Size 11.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f946b0a8b666a11bd00b69a53cd8514154ee8ab3507ebb3d714d6fe204ea79b3
BLAKE2b-256 checksum
How to use checksums
e969c357b2effd667207edb97c68e9336efde5ef0e2df53582821e31d98a2cd7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Security for firefox-browser-mcp 0.2.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page