Firefox DevToolsSAFE
Model Context Protocol server for Firefox DevTools - enables AI assistants to inspect and control Firefox browser through WebDriver BiDi
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
[](https://www.npmjs.com/package/@mozilla/firefox-devtools-mcp) [](https://github.com/mozilla/firefox-devtools-mcp/actions/workflows/ci.yml) [](https://codecov.io/gh/mozilla/firefox-devtools-mcp) [](LICENSE-MIT) [](LICENSE-APACHE)
Model Context Protocol server for automating Firefox via WebDriver BiDi (through Selenium WebDriver). Works with Claude Code, Claude Desktop, Cursor, Cline and other MCP clients.
Repository: https://github.com/mozilla/firefox-devtools-mcp
Note: This MCP server requires a local Firefox browser installation and cannot run on cloud hosting services like glama.ai. Use npx @mozilla/firefox-devtools-mcp@latest to run locally, or use Docker with the provided Dockerfile.Security
Browser MCP servers carry inherent risks. A few key practices:
- Use a dedicated Firefox profile. Never run the server against your regular profile — the agent has access to whatever the browser can reach, including cookies and saved sessions.
- Be cautious about which sites you visit. Pages can return content designed to manipulate the agent (prompt injection). Stick to sites you control or trust.
- Enable only the tool modules you need. The default
basicpreset already includesevaluate_script;--tool-preset slimdrops it. Higher presets such as--tool-preset developer(debugging, network, console, profiler) and--tool-preset mozilla(privileged cont
1f6edb191517OBSERVED · 2026-10-07Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add firefox-devtools-mcp -- npx -y @mozilla/[email protected]
Exposed tools (71)
40 read · 24 write · 7 destructive. Blast radius: 7 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
accept_dialog | read | Accept browser dialog. Provide promptText for prompts. |
clear_console_messages | destructive | Clear collected console messages. |
clear_downloads | destructive | Clear the tracked downloads buffer. |
clear_snapshot | destructive | Clear snapshot UIDs. Usually not needed. |
click_by_uid | write | Click element by UID. Set dblClick for double-click. |
close_firefox_session | read | Ends the browser session. If the server connected to your existing Firefox, |
close_page | read | Close tab by index. |
console | destructive | Read and clear console messages. |
debugging | write | Inspect scripts and set logpoints (Firefox 153+). |
dismiss_dialog | read | Dismiss browser dialog. |
downloads | read | Monitor and manage file downloads. |
drag_by_uid_to_uid | read | Drag element to another (HTML5 drag events). |
enable_debugger | write | Enable the JS debugger for the current page. Required before set_logpoint works. Requires Firefox 153+. |
evaluate_privileged_script | write | Execute JS function in a privileged (chrome) browsing context. Requires MOZ_REMOTE_ALLOW_SYSTEM_ACCESS=1 env var. Get context ids from list_privileged_contexts. |
evaluate_script | write | Run a JS function in the page and return its result. Prefer this for targeted reads (a value, text, computed style, whether an element exists) instead of a full take_snapshot. Use the UID interaction tools for clicking, typing, and filling. |
fill_by_uid | read | Fill text input/textarea by UID. |
fill_form_by_uid | read | Fill multiple form fields at once. |
get_firefox_info | read | Get information about the current Firefox instance configuration, including binary path, environment variables, and output file location. |
get_firefox_output | read | Retrieve Firefox output (stdout/stderr including MOZ_LOG, warnings, crashes, stack traces). Returns recent output from the capture file. Use filters to focus on specific content. |
get_firefox_prefs | read | Get Firefox preference values via a privileged API. Requires MOZ_REMOTE_ALLOW_SYSTEM_ACCESS=1 env var. |
get_logpoint_results | write | Get the results collected by a logpoint since it was set. |
get_network_request | read | Get request details by ID, including the response body (and request body when present). Large text bodies are truncated inline; binary bodies are summarized. URL lookup as fallback. |
get_page_text | read | Get the visible text of the page (document.body.innerText). Caps at maxLength (default 20000 chars); saveTo saves the full text to a file. |
get_script_source | read | Get the source code of a JavaScript file loaded in the page. Requires enable_debugger to have been called. |
hover_by_uid | read | Hover over element by UID. |
input | read | Interact with the page via UID-based clicks, typing, key presses, drag, and uploads. |
install_extension | write | Install a Firefox extension using WebDriver BiDi webExtension.install command. Supports installing from archive (.xpi/.zip), base64-encoded data, or unpacked directory. |
launch | write | Restart Firefox under a different launch configuration. |
list_console_messages | read | List console messages, filterable by level, time, text, source. Caps at limit (default 50); saveTo saves all matches to a file. |
list_downloads | read | List downloads tracked since startup, including status and saved file path. |
list_network_requests | read | List network requests, returning IDs for get_network_request. Filter by url/method/status; caps at limit (default 50); saveTo saves all matches to a file. |
list_pages | read | List open tabs (index, title, URL). Selected tab is marked. |
list_privileged_contexts | read | List privileged (privileged) browsing contexts. Requires MOZ_REMOTE_ALLOW_SYSTEM_ACCESS=1 env var. Use restart_firefox with env parameter to enable. |
list_scripts | read | List all JavaScript files currently loaded in the page. Requires enable_debugger to have been called. |
management | read | Inspect Firefox options and logs, and close the browser. |
navigate_history | read | Navigate history back/forward. UIDs become stale. |
navigate_page | read | Navigate selected tab to URL. |
network | read | List and inspect network requests, and control the HTTP cache. |
new_page | read | Open new tab at URL. Returns tab index. |
pages | read | Open, navigate, select, and close pages. |
prefs | write | Get and set Firefox preferences. |
press_key | write | Press a single key, optionally with modifiers, to submit, dismiss, navigate or trigger a shortcut. Not for entering text: use fill_by_uid instead. |
privileged | read | Access privileged ( |
profiler | write | Start, stop, and query the performance profiler. |
profiler_is_active | read | Check whether the Firefox profiler is currently recording. |
profiler_start | write | Start the Firefox profiler. Provide either a preset name or explicit recording options (entries, interval, features, threads). Cannot combine both. Valid presets: ${VALID_PRESETS.join( |
profiler_stop | write | Stop the Firefox profiler and save the recorded profile to a file in the downloads directory. Returns the path to the saved file, or null when nothing was saved. |
remove_logpoint | destructive | Remove a previously set logpoint. |
resolve_uid_to_selector | read | Resolve UID to CSS selector. Fails if the element is gone. |
restart_firefox | write | Restart Firefox with different configuration. Allows changing binary path, environment variables, and other options. All current tabs will be closed. |
screencast | read | Record screencasts of the page viewport (Firefox 154+). |
screencast_start | write | Start recording a screencast (video) of the current page viewport, saving the output to a file in the downloads directory. Returns a screencast id to pass to screencast_stop. Multiple recordings can run at once. |
screencast_stop | write | Stop an in-progress screencast recording started with screencast_start and finalize the video file. Returns the path to the saved file. |
screenshot | read | Capture screenshots of the page or specific elements. |
screenshot_by_uid | read | Capture element screenshot by UID as base64 PNG. |
screenshot_page | write | Capture viewport screenshot as base64 PNG. Set fullPage for the whole scrollable document. |
script | read | Evaluate arbitrary JavaScript in the page context. |
select_page | read | Select active tab by index, URL, or title. Index takes precedence. |
select_privileged_context | write | Select a privileged browsing context by ID and set WebDriver Classic context to |
set_download_behavior | write | Control how downloads are handled: allow (save to a destination folder), deny (cancel), or reset to default. Avoids the native save-file dialog. Requires a recent Firefox. |
set_firefox_prefs | write | Set Firefox preferences at runtime a privileged API. Requires MOZ_REMOTE_ALLOW_SYSTEM_ACCESS=1 env var. |
set_logpoint | write | Set a logpoint at a specific location. When execution reaches that line, the expression is evaluated and the result is stored without pausing. Use get_logpoint_results to retrieve collected values. Requires enable_debugger to have been called. |
set_network_cache | write | Control the HTTP cache. Use behavior= |
set_viewport_size | write | Set viewport dimensions in pixels. |
snapshot | read | Capture accessibility/DOM snapshots and resolve UIDs. |
take_snapshot | read | Capture DOM snapshot with stable UIDs. A UID stays valid across snapshots until its element is removed or the page navigates. Output caps at maxLines (default 100); scope with selector or dump the full tree with saveTo. |
type_text | read | Type text key by key into the focused element, optionally followed by a key such as Enter. Use fill_by_uid to set the value of a known input; use this for elements that only react to real typing, such as autocomplete fields and rich text editors. |
uninstall_extension | destructive | Uninstall a Firefox extension using WebDriver BiDi webExtension.uninstall command. Requires the extension ID returned by install_extension or obtained from list_extensions. |
upload_file_by_uid | write | Upload file to file input by UID. |
utilities | read | Handle dialogs, history navigation, and viewport sizing. |
webextension | destructive | Install and uninstall web extensions. |
Trust audit
SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | PASS |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (8 observation(s))
- Network
- declared (4 observation(s))
- Shell
- declared (5 observation(s))
- Dependencies
- not all pinned
- Secrets in source
- none-found
Findings (14)
clear_console_messages, clear_downloads, clear_snapshot, console, remove_logpoint, uninstall_extension, webextension
.codecov.yml
.prettierignore
.prettierrc.json
const hash = createHash('sha1').update(firefoxPath).digest('hex').slice(0, 8);const hash = createHash('sha1').update(binaryPath).digest('hex').slice(0, 8);import { logDebug } from '../../utils/logger.js';import { logDebug } from '../../utils/logger.js';import { logDebug } from '../../utils/logger.js';import { logDebug } from '../../utils/logger.js';import { nativeToLocalValue } from '../../utils/local-value.js';webdriver-bidi-protocol
Connects to an already-running Firefox instance instead of launching a fresh one. If that instance is your regular browser profile, the agent has access to your cookies, saved passwords, active sessio
Prompt injection is an attack where malicious content in the environment manipulates an AI agent into taking unintended actions. In browser automation, this means a page's visible text, hidden HTML el
Gates applied: no_behavioural_pass.
1f6edb191517full audit observations/trust-audit/mcp-server/freema__firefox-devtools.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-07 | 1f6edb191517 | SAFE | B | 89 | first audit |
Questions
What is the Firefox DevTools MCP server?
Model Context Protocol server for Firefox DevTools - enables AI assistants to inspect and control Firefox browser through WebDriver BiDi
What tools does Firefox DevTools expose?
71 in total: 40 read-only, 24 that write, and 7 that can delete or overwrite (clear_console_messages, clear_downloads, clear_snapshot, console, remove_logpoint). Every one is listed on this page with its risk.
Is Firefox DevTools safe to connect to an agent?
The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean server reads B. Separately from the audit: 7 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does Firefox DevTools need?
It reads FIREFOX_MCP_TEST_NEWKEY from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does Firefox DevTools run?
It speaks stdio, so it runs as a local process your client starts. It is published on npm as @mozilla/firefox-devtools-mcp at 0.10.4.
How current is this page?
The grade is for one exact copy of the source (1f6edb191517), read on 2026-10-07. The repository is watched and re-audited when it changes.