Skip to content

Merge changes from padenot/firefox-devtools-mcp#46

Merged
freema merged 20 commits intomozilla:mainfrom
juliandescottes:rebase-upstream
Mar 28, 2026
Merged

Merge changes from padenot/firefox-devtools-mcp#46
freema merged 20 commits intomozilla:mainfrom
juliandescottes:rebase-upstream

Conversation

@juliandescottes
Copy link
Copy Markdown
Collaborator

@freema

This PR merges all the changes from mozilla's initial fork of firefox-devtools-mcp. (
List of added features:

  • Add tool to evaluate JS against the content page
  • Add tool to install, uninstall and list webextensions
  • Add tool to restart Firefox
  • Add tool to read and write preferences
  • Improved support for reusing existing profile folder
  • Support for --pref cli argument
  • Support for MOZ_LOG
  • Support privileged context
  • Support for sending WebDriver BiDi commands

To avoid exposing new features to users, I added new cli flags.

  • --enable-script to enable all script evaluation tools. IMO should be safe to enable but was mentioned as a potential security issue in one .md file in the repo.
  • --enable-privileged-context to enable advanced features that typically require parent process / chrome privileges. This is mostly useful for internal Firefox development.

I cleaned up and removed the non-english .md files. We can add the back if needed after translation?

And this doesn't include my work on the 100% BiDi-based version at the moment.

@padenot

Some notable changes compared to the version we are currently using internally: as mentioned above, will need 2 cli flags to have script evaluation + chrome scope. Also renamed "chrome scope/context" to "privileged scope/context" in most places to avoid confusion. The --pref cli argument is no longer handled via chrome js, instead we use capabilities moz:firefoxOptions. This avoids restarting with chrome privs just for setting prefs.

padenot and others added 20 commits March 27, 2026 09:16
  - CLI: --env and --output-file flags
  - Capture stdout/stderr via fd redirection
  - Tools: get_firefox_output, get_firefox_info, restart_firefox
  - Change Firefox config at runtime without MCP server restart:
    different binary, env var, etc.
This implements:
- list_chrome_context
- select_chrome_context
- evaluate_chrome_script

They do what they say on the tin, but this requires
`MOZ_REMOTE_ALLOW_SYSTEM_ACCESS=1`, as expected.

This allows some functionnality for Firefox javascript developers.
Check connection status before restart to avoid errors when Firefox
was closed externally. Fall back to CLI firefoxPath if not provided.
Clean up stale instances and update error messages to guide recovery.
Selenium's setProfile() copies the profile to a temp directory which
can silently fail or not preserve all profile data. Using Firefox's
native --profile command-line argument directly ensures the configured
profile is actually used.

Adds test to verify profile path is passed via --profile argument.
Previously, restart_firefox would lose the configured profile path
when restarting Firefox. Now the tool preserves the current profile
path by default and adds a profilePath parameter to allow changing
it at runtime.

Documentation updated to reflect:
- New profilePath parameter in restart_firefox
- Firefox management tools in tool overview
- Corrected profile management behavior (uses native --profile arg)
Allow overriding Firefox's RecommendedPreferences via CLI and runtime
tools. When Firefox runs in WebDriver BiDi mode, it applies preferences
that change default behavior for test reliability. This feature enables
Firefox developers and testers to override these when needed.

Adds:
- CLI: --pref name=value (repeatable, requires MOZ_REMOTE_ALLOW_SYSTEM_ACCESS=1)
- Tools: set_firefox_prefs, get_firefox_prefs
- restart_firefox: new prefs parameter for setting on restart
- get_firefox_info: shows configured preferences

Preferences are preserved across restarts and re-applied automatically.
After Firefox launches, sendBiDiCommand() was failing with "WebSocket is
not open: readyState 0 (CONNECTING)" errors because it tried to send
commands before the BiDi WebSocket connection was fully established.

Add waitForWebSocketOpen() helper that:
- Returns immediately if WebSocket is already OPEN (readyState 1)
- Waits for 'open' event if CONNECTING (readyState 0) with 5s timeout
- Throws immediately if CLOSING or CLOSED (readyState 2 or 3)
The pref tools checked process.env.MOZ_REMOTE_ALLOW_SYSTEM_ACCESS
before calling getFirefox(), but the env var is only set in process.env
during getFirefox() -> FirefoxCore.connect(). This caused tools to fail
when launched with --env MOZ_REMOTE_ALLOW_SYSTEM_ACCESS=1.

Remove early env checks and rely on the existing "No chrome contexts
available" error which already provides helpful guidance.
Clean up test files by removing implementation-tracking
comments that referenced plan steps (e.g., "// Step 1.1").
These were added during development and are no longer needed.
Highlight the browser.ml.enable preference as a practical example
in both README and firefox-client.md. This pref is particularly
relevant because RecommendedPreferences disables ML/AI features
by default, making it essential for developing features like
Smart Window with this MCP server.
Implement BiDi-native tools for installing and uninstalling Firefox extensions:

- install_extension: Wraps webExtension.install BiDi command
  - Supports 3 types: archivePath (.xpi/.zip), base64, path (unpacked)
  - Firefox-specific moz:permanent parameter for signed extensions
- uninstall_extension: Wraps webExtension.uninstall BiDi command

Both tools provide straightforward access to Firefox's native WebDriver
BiDi webExtension module functionality.
Implements extension discovery using chrome-privileged AddonManager API
as a workaround for missing webExtension.getExtensions BiDi command.

Features:
- Lists all installed Firefox extensions with UUIDs and metadata
- Extracts mozExtensionHostname (UUID) for moz-extension:// URLs
- Shows background scripts, manifest version, active status
- Distinguishes system/built-in vs user-installed extensions
- Supports filtering by: ids (exact), name (partial), isActive, isSystem
- Filters applied in browser for efficiency

Requires MOZ_REMOTE_ALLOW_SYSTEM_ACCESS=1 environment variable.
Co-authored-by: Julian Descottes <jdescottes@mozilla.com>
Fixing some inconsistencies after rebasing the mozilla fork upstream as well as several cleanups:
- stop referring to chrome context and prefer privileged context
- remove md files which are not in english
- update some urls from freema to mozilla
@freema freema merged commit 4385c7b into mozilla:main Mar 28, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants