Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Firefox DevTools MCP Connector

Control and inspect Firefox from Claude Code via the Model Context Protocol: capture screenshots, navigate and interact with pages, read console output, and evaluate scripts. Perfect for visual theme verification, UI regression testing, design review, and end-to-end browser automation — Claude sees and drives exactly what your users see.

┌──────────────┐  WebSocket   ┌──────────────┐  stdio/MCP   ┌──────────────┐
│   Firefox    │─────────────▶│  MCP Server  │◀────────────▶│  Claude Code │
│  Extension   │  localhost   │  (Node.js)   │              │              │
└──────────────┘   :8769      └──────────────┘              └──────────────┘

What's included

Component Path Purpose
Firefox WebExtension extension/ Captures screenshots on demand
MCP Server server/ Bridges extension → Claude Code
Screenshots screenshots/ Saved PNGs + diff images

Setup

1. Install the MCP server

cd server
npm install

2. Load the Firefox extension

  1. Open Firefox and go to about:debugging#/runtime/this-firefox
  2. Click Load Temporary Add-on…
  3. Select extension/manifest.json
  4. The 📸 icon appears in your toolbar

3. Register with Claude Code

Run this from the project root:

claude mcp add firefox-devtools \
  --scope user \
  -- node /ABSOLUTE/PATH/TO/firefox-devtools-mcp/server/index.js

Replace /ABSOLUTE/PATH/TO/ with the real path on your machine.

Or add it manually to ~/.claude.json:

{
  "mcpServers": {
    "firefox-devtools": {
      "command": "node",
      "args": ["/ABSOLUTE/PATH/TO/firefox-devtools-mcp/server/index.js"],
      "env": {
        "SCREENSHOT_WS_PORT": "8769"
      }
    }
  }
}

4. Verify

Open a new Claude Code session and run:

/mcp

You should see firefox-devtools listed with 26 tools.

Tools available in Claude Code

Tool Tier Description
capture_screenshot read Capture the visible viewport of the active tab
capture_full_page read Capture the full scrollable page
list_screenshots List all saved screenshots with timestamps
get_screenshot Retrieve a saved screenshot by filename
compare_screenshots Pixel-diff two screenshots, outputs a diff image
navigate write Load a URL in the active tab
go_back / go_forward write Move through tab history
reload_page write Reload the active tab, optionally bypassing cache
get_current_url read Return {url, title} of the active tab
get_element_text read Get an element's textContent
get_element_attribute read Get an element's attribute value
query_elements read Find elements matching a selector, with summary info — good for exploring a page
click_element write Click an element
fill_input write Fill an input/textarea; dispatches input/change so React/Vue notice
fill_form write Fill multiple inputs in one call, optionally clicking a submit element after
select_option write Select a <select> option by value or visible label
set_checkbox write Set a checkbox/radio's checked state
hover_element write Dispatch mouseover/mouseenter on an element
focus_element write Focus an element
press_key write Dispatch a keydown/keyup pair (e.g. Enter, Tab, Escape)
wait_for_selector write Poll until an element is visible/attached/hidden, or time out
read_console_logs read Read buffered console output from the active tab (since it last navigated)
clear_console_logs read Clear the active tab's console buffer
get_page_errors read Return uncaught errors and unhandled promise rejections since page load
evaluate_script execute Run JavaScript in the page's own context — full access to page globals

navigate/go_back/go_forward/reload_page/get_current_url/capture_* and all the interaction/inspection/console tools act on the active Firefox tab and are gated by the site permission allowlist (see Permissions below). list_screenshots, get_screenshot, and compare_screenshots work on locally saved files and aren't tab-scoped.

Console capture only ever runs on tabs the allowlist already grants read access to — the extension doesn't monkey-patch console on every site you browse, only ones you've explicitly allowed. If a page's Content-Security-Policy blocks the capture script, other tools on that page keep working; read_console_logs will just come back empty.

Element-targeting tools accept a selector_type of css (default), xpath, or text (case-insensitive substring match against leaf elements), plus an optional nth to pick among multiple matches.

evaluate_script is the most powerful — and most dangerous — tool here: it runs arbitrary JavaScript in the page's own context, with full access to page globals, not just the DOM. Code is wrapped in an async function body (return produces a value, await works directly). It requires the execute tier, which no site gets by default — see Permissions below. Every invocation logs a warning to the MCP server's stderr.

Usage examples

Once connected, just talk naturally in Claude Code:

> Take a screenshot of the page I have open and check if the dark
> mode theme matches our design tokens.

> Capture screenshots before and after my CSS change, then compare
> them to see what shifted.

> List all the screenshots we've taken and show me the latest one.

> Compare screenshot_1721900000.png with screenshot_1721901000.png
> using a threshold of 15 — I want to catch subtle color changes.

How it works

  1. Claude Code calls an MCP tool (e.g. capture_screenshot)
  2. The MCP server sends a WebSocket message to the Firefox extension
  3. The extension uses browser.tabs.captureVisibleTab() to grab a PNG
  4. The PNG (base64) is sent back through WebSocket → MCP server → Claude Code
  5. Claude Code sees the actual screenshot and can analyze it visually

For compare_screenshots, the server uses sharp to do a pixel-level diff and generates a highlighted diff image where changed pixels appear in red.

Configuration

Env var Default Description
SCREENSHOT_WS_PORT 8769 WebSocket port the extension connects to

Theme verification workflow

A typical visual QA loop looks like this:

  1. Open your app in Firefox with the light theme → ask Claude to capture
  2. Toggle to dark theme → capture again
  3. Ask Claude to compare the two and verify contrast ratios, color tokens, etc.
  4. Claude reports exactly which regions changed and whether the theme looks correct

Troubleshooting

Extension shows "Disconnected" → Make sure the MCP server is running. Claude Code starts it automatically when you use a tool, but you can also run cd server && node index.js manually.

NO_ACTIVE_TAB → Either no tab is focused, or the focused tab is a privileged browser page (about:*, moz-extension:*, chrome:*, resource:*) that the extension can never automate, regardless of the allowlist. Focus a regular webpage tab and retry.

TAB_CHANGED → The active tab switched to a different tab between the permission check and the action actually running (you alt-tabbed, or clicked a different tab, while a tool call was in flight). The extension re-verifies the active tab immediately before every action — this is a real permission check catching a real race, not a bug — and aborts rather than risk acting on a page it never checked. Just retry once you're back on the intended tab. (If the tab merely navigated to a different URL rather than losing focus, you'll see PERMISSION_DENIED instead if the new page isn't allowlisted.)

Screenshots are blank or black → Some pages block captureVisibleTab (e.g. DRM-protected video). Try a different tab.

ELEMENT_NOT_FOUND / ELEMENT_NOT_INTERACTABLE → The selector matched zero elements (or nth was out of range), or it matched an element that's disabled or has no visible layout box (display:none, zero size, etc.). Try query_elements first to see what's actually on the page.

"Site not allowlisted" / PERMISSION_DENIED → Every action is denied by default. If auto-prompt is on (the default), a native notification appears and the popup shows an inline "Allow this site?" panel — click the toolbar icon and hit Allow. Otherwise, click ⚙ Manage Permissions and add the site's URL pattern (e.g. http://localhost:*/*) with the tier the action needs.

RATE_LIMITED → More than rate_limit_per_second actions (default 20) hit the same tab within one second — usually a runaway loop. Wait a moment and retry, or raise the limit in ⚙ Manage Permissions → Settings.

SCRIPT_ERROR / INJECTION_BLOCKEDevaluate_script: SCRIPT_ERROR means your code threw — the message is the page's own error. INJECTION_BLOCKED means the page's Content-Security-Policy stopped the script-evaluation bridge from loading; nothing can be done short of the page relaxing its CSP.

Permissions

Deny by default: Claude Code can only act on a tab whose URL matches an entry in the extension's allowlist. Manage the allowlist, settings, and audit log from the popup's ⚙ Manage Permissions link, which opens the options page (Sites / Settings / Audit Log tabs).

  • readcapture_screenshot, capture_full_page, get_current_url, get_element_text, get_element_attribute, query_elements, read_console_logs, clear_console_logs, get_page_errors
  • write — everything in read, plus navigate, go_back, go_forward, reload_page, click_element, fill_input, fill_form, select_option, set_checkbox, hover_element, focus_element, press_key, wait_for_selector
  • execute — everything in write, plus evaluate_script — arbitrary JS in the page's context. The Sites tab shows a red warning before you can grant it; it's off by default and worth granting only to sites you fully trust and control.

Patterns follow Firefox match-pattern syntax (https://example.com/*, *://*.example.com/*, http://localhost:*/*). <all_urls> is rejected — it's too permissive for automation.

Settings tab: auto_prompt_new_sites (native notification + inline popup panel on first denied attempt), log_all_actions (audit log on/off), max_console_buffer (per-tab entry cap), rate_limit_per_second (per-tab action cap). Danger zone: clear the allowlist or reset all extension data — both irreversible.

Audit log tab: every action attempt (allowed or denied), filterable by site/action/result, with a clear button.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages