ff-mcp
Provides controlled access to a Firefox browser profile, enabling capabilities such as listing tabs, reading page content, interacting with pages, executing scripts, and capturing screenshots with granular, revocable permissions.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ff-mcplist my open tabs"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ff-mcp
ff-mcp gives local MCP clients controlled access to the Firefox profile you already use. It is
made of a Firefox Manifest V3 WebExtension and a Python Native Messaging host that serves MCP over
Streamable HTTP on 127.0.0.1.
The extension—not the localhost process—is the final authorization boundary. Listing tab metadata does not grant access to page content. Reading, interaction, and screenshots require independent, revocable capabilities.
Current capabilities
List tab metadata without page access.
Request
READ,INTERACT,SCRIPT, andSCREENSHOTon a specific tab.Grant access once, for a document, for a tab session, or persistently for a host.
Read bounded serialized snapshots and CSS-query results. Live DOM objects never cross the bridge.
Click, type, scroll, and navigate through structured operations.
Capture a tab only with a separate screenshot grant.
Execute arbitrary JavaScript in the isolated user-script world or the page's main world only with a separate
SCRIPTgrant and Firefox's optionaluserScriptspermission.Match persistent policies with
host,glob,regex, andschemepredicates composed withAND,OR, andNOT.Audit authorization decisions and sensitive operations inside Firefox.
Bind MCP to loopback only, require a generated bearer token, and reject HTTP origins by default.
Requirements
Firefox 150 or newer.
Python 3.14 (the package is pinned to the 3.14 minor line).
uvis recommended for installation.
One-off SCRIPT execution requires Firefox 153 or newer because that release introduced
userScripts.execute(). The remaining capabilities support Firefox 150 onward.
Install from a checkout
Install the native companion as a persistent tool, then register it with Firefox:
uv tool install .
ff-mcp install-nativeFor development, load extension/manifest.json from
about:debugging → This Firefox → Load Temporary Add-on.
Open the ff-mcp toolbar popup and press Start. The first start creates a private configuration file containing a random token:
Linux:
$XDG_CONFIG_HOME/ff-mcp/config.jsonor~/.config/ff-mcp/config.jsonmacOS:
~/.config/ff-mcp/config.jsonWindows:
%APPDATA%\ff-mcp\config.json
The popup shows and can copy a generic connection object:
{
"url": "http://127.0.0.1:8765/mcp",
"headers": {
"Authorization": "Bearer YOUR_GENERATED_TOKEN"
}
}Configure those values in an MCP client that supports Streamable HTTP and custom headers. The endpoint exists only while the extension holds its Native Messaging connection open.
Permission flow
Call
browser_tabsand choose a tab ID.Call
browser_request_accesswith one or more capabilities.Approve the toolbar request in Firefox.
Call the read, interaction, or screenshot tool.
Revoke the grant from the toolbar or with
browser_revoke.
READ is allowed by default only for localhost, subdomains of .localhost, 127.0.0.0/8, and
::1. This default does not include interaction, scripting, or screenshots.
Policy rules
The options page has a visual policy editor. Each new rule starts with a main AND container that
contains an OR allow group and a NAND exclusion group. Add host, URL-pattern, regex, or scheme
conditions; nest more AND, OR, NAND, or NOR containers when needed; then choose the
capabilities the matching rule grants.
Empty non-negated containers match nothing. Empty negated containers match everything, so a new rule remains inactive until its allow group has at least one condition. The always-enabled localhost READ rule is shown separately and cannot be edited or removed.
Existing expression-based rules are migrated into the visual tree when the settings page opens. The expression format remains the stored representation for backward compatibility.
Regex patterns are length-limited and reject backreferences, lookarounds, and obvious nested quantifiers. This is a safety subset, not a complete RE2 implementation.
Development
UV_CACHE_DIR=/tmp/ff-mcp-uv-cache uv sync --group dev
UV_CACHE_DIR=/tmp/ff-mcp-uv-cache uv run pytest -q
# Opt-in: launches the installed Firefox headlessly with a fresh temporary profile.
FF_MCP_RUN_FIREFOX_TESTS=1 UV_CACHE_DIR=/tmp/ff-mcp-uv-cache uv run pytest -q tests/test_firefox_integration.py
UV_CACHE_DIR=/tmp/ff-mcp-uv-cache uv run ruff check .
UV_CACHE_DIR=/tmp/ff-mcp-uv-cache uv run ruff format --check .
node tests/policy.test.js
node tests/rule-model.test.js
node tests/background.test.js
node tests/content.test.js
node --check extension/background.js
node --check extension/content.js
node --check extension/options.js
node --check scripts/check-web-ext-lint.jsSet FIREFOX_BINARY for installations Selenium cannot discover automatically. The integration test
recognizes the standard Linux Snap location without extra configuration.
The Firefox extension has no runtime third-party dependencies or build step.
Releases
Tags named vX.Y.Z run the release workflow. The tag version must match both
project.version in pyproject.toml and version in extension/manifest.json. The workflow asks
Mozilla Add-ons to sign the extension on the unlisted channel, verifies the returned XPI, and
attaches the signed XPI plus its SHA-256 checksum to a GitHub release. The generated artifacts stay
untracked.
Configure these secrets in the repository's release environment before pushing a tag:
AMO_JWT_ISSUER: the issuer from an AMO API credential.AMO_JWT_SECRET: the corresponding AMO API secret.
Create the credentials from the AMO API keys page. Unlisted signing does not publish the extension in AMO search or listings.
Security limits
The extension necessarily requests broad site access so it can mediate arbitrary tabs and use Firefox's background-tab screenshot API. Its internal capability checks are therefore critical.
Approved browser metadata, website content, and website activity are transmitted to the local native host and MCP client. AMO declares these required data categories during installation.
Firefox-restricted pages such as
about:and the add-ons store cannot be read by content scripts.A tab-session grant intentionally survives navigation in that tab; document grants do not.
MCP client identity is descriptive within the one bearer-token trust domain. Use a separate config and token if mutually untrusted local clients need isolation.
Structured clicks and input can still trigger page behavior. Grant
INTERACTsparingly.SCRIPTis effectively full page control. Firefox asks for its optionaluserScriptspermission during approval, and ff-mcp still requires a separate tab capability.MAIN-world scripts can access and alter page-owned JavaScript state; grant this only to clients and sites you trust.
See firefox_mcp_extension_findings.html for the design
research that preceded this implementation.
License
MIT. See LICENSE and THIRD_PARTY.md.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Browser MCP for logged-in tasks. Uses your Chrome — credentials stay local. Zero-token replay.
Remote MCP server for full read/write access to a Zotero library
A MCP server built for developers enabling Git based project management with project and personal…
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/complynx/ff-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server