Firefox DevTools MCP vs Selenium MCP

A side-by-side look at the Firefox DevTools MCP and Selenium MCP MCP servers: transport, auth, tools, quality signals, and the config to install either one in Claude, Cursor, Windsurf or VS Code.

Firefox DevTools MCP logoFirefox DevTools MCPBrowser Automation · Local subprocess (stdio)Control and debug Firefox: navigate, fill forms, inspect network and console, profile.69GreatAuth: not declaredSelenium MCP logoSelenium MCPBrowser Automation · Local subprocess (stdio)Selenium MCP server for AI agents — 38 browser automation tools with snapshots and sessions.59GoodAuth: not declared

Verdict: choose Firefox DevTools MCP for browser automation work as a local process; choose Selenium MCP for browser automation as a local process. You can also run both side by side in one mcpServers block.

Which MCP server should you choose?

Firefox DevTools MCP logoChoose Firefox DevTools MCP when

  • You need dedicated capabilities in the Browser Automation domain.
  • You prefer a local stdio subprocess transport.
  • You want tools like list_pages, new_page, navigate_page.
Explore Firefox DevTools MCP

Selenium MCP logoChoose Selenium MCP when

  • You need dedicated capabilities in the Browser Automation domain.
  • You prefer a local stdio subprocess transport.
  • You want tools like start_browser, navigate, history.
Explore Selenium MCP

Feature & specification comparison

Rows where the two servers differ are marked.

SpecFirefox DevTools MCP logoFirefox DevTools MCPSelenium MCP logoSelenium MCP
CategoryBrowser AutomationBrowser Automation
Quality signal69/100 · Great59/100 · Good
Install commandConfirmedConfirmed
TransportLocal subprocess (stdio)Local subprocess (stdio)
AuthNot declaredNot declared
PricingNot declaredNot declared
Required env varsNone listedNone listed
Verified ownerCommunity listingCommunity listing
GitHub stars5060
Directory activity 3 views 0 installs 0 upvotes 2 views 0 installs 0 upvotes
Tools3541

Tools & capabilities

Firefox DevTools MCP tools 35

  • list_pagesList open tabs (index, title, URL). Selected tab is marked.
  • new_pageOpen new tab at URL. Returns tab index.
  • navigate_pageNavigate selected tab to URL.
  • select_pageSelect active tab by index, URL, or title. Index takes precedence.
  • close_pageClose tab by index.
  • get_page_textGet the visible text of the page (document.body.innerText). Caps at maxLength (default 20000 chars); saveTo saves the full text to a file.
  • take_snapshotCapture 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.
  • resolve_uid_to_selectorResolve UID to CSS selector. Fails if the element is gone.
  • clear_snapshotClear snapshot UIDs. Usually not needed.
  • click_by_uidClick element by UID. Set dblClick for double-click.
  • hover_by_uidHover over element by UID.
  • fill_by_uidFill text input/textarea by UID.
  • +23 more on the listing page

Selenium MCP tools 41

  • start_browserStart a browser session (Chrome, Firefox, or Edge) that all other tools act on. Call this first. Only one session can be started this way: call stop_browser before starting another, or use session_create to run several browsers at once. The matching driver is downloaded automatically by Selenium Manager. Returns the session status.
  • navigateOpen a URL in the current tab and wait for the page to load (up to the pageLoadTimeoutMs set in start_browser). Returns the final URL after any redirects, and the page title. Use history to go back, forward, or refresh; use wait_for_page when a later redirect or client-side route change still has to happen.
  • historyBrowser history navigation: go back to the previous page (like the Back button), go forward to the next page, or refresh/reload the current page (like F5). Waits for the page to load and returns the new URL and title. To open a specific URL, use navigate instead. Element refs from an earlier capture_page may be stale afterwards, so capture the page again before using refs. Refresh can reset unsaved form input.
  • clickClick an element: waits until it is visible and enabled, then clicks it (scrolling it into view). Target it by selector or by a ref from capture_page. If clicks fail intermittently because of overlays, animations, or re-rendering, use retry_click; for double-click, right-click, or hover, use interact. Fails with the reason if the element does not become clickable within timeoutMs.
  • interactMouse actions beyond a plain click: double_click, right_click (opens a context menu), hover (reveals menus and tooltips), or click performed as a real mouse move-and-click. Waits for the element to be visible (hover) or visible and enabled (clicks). Target it by selector or by a ref from capture_page. For an ordinary click, prefer click.
  • typeType text into an input, textarea, or other editable element. Waits for it to be visible, clears the current value first (clearFirst: false appends instead), then sends the text as keystrokes so the page's input events fire; submit: true presses Enter afterwards. Target it by selector or by a ref from capture_page. For dropdowns use select_option; for single keys like Tab or Escape use press_key.
  • select_optionSelect an option in a native <select> dropdown by visible text, value, or zero-based index, and return the resulting selection. Waits for the dropdown to be visible, then clicks the option like a user so change events fire; on a multi-select it adds to the current selection. If nothing matches, the error lists the available options so you can retry. Only for real <select> elements; for custom dropdowns built from other elements, click the trigger and then the option.
  • scrollScroll the page: scroll down or up by pixels, jump to the top or bottom, or scroll an element into view (to the middle of the screen). Also scrolls inside a scrollable container (chat panels, tables, sidebars with their own scrollbar) when you pass that container as selector/ref together with to or deltaX/deltaY. Returns the scroll position with atTop/atBottom flags. For lazy-loaded or infinite-scroll pages ('load more' on scroll), scroll to the bottom, wait_for_element for the new items, and repeat until atBottom stays true and nothing new appears. click and type already scroll their target into view, so use this to reveal content or trigger lazy loading.
  • get_textRead the visible text of an element: what a user sees, not hidden text or an input's value. Waits for the element to be visible, then returns its text (trimmed by default). Target it by selector or by a ref from capture_page. To read an input's value or any attribute, use get_attribute; to check text as a pass/fail test step, use assert_text.
  • get_attributeRead an attribute or property of an element, e.g. an input's value, a link's href, or whether it is disabled, checked, or aria-expanded. Waits for the element to exist (it does not need to be visible). Returns the value, or null if it is not set; the live property wins when one exists, so 'value' gives the text currently in an input. Use get_text for visible text, and assert_attribute to check a value as a test step.
  • assert_textTest step: check that an element's visible text equals, contains (default), or matches a regular expression. Waits for the element to be visible, then checks once (it does not wait for the text to change). Passes with the actual text, or fails as a tool error showing expected vs actual, so it works as an acceptance check. Use get_text to just read text without a pass/fail.
  • assert_visibleTest step: check that an element becomes visible within timeoutMs, e.g. a success banner or a cart badge. Passes as soon as it is displayed; fails as a tool error if it is missing or stays hidden. Similar to wait_for_element with visible: true, but phrased as a pass/fail assertion.
  • +29 more on the listing page

Ready-to-paste client configs

Paste either block (or both) into your client config, e.g. claude_desktop_config.json or ~/.cursor/mcp.json. We only show a config when the install command is confirmed.

Firefox DevTools MCP

mcpServers (Claude Desktop / Cursor)
{
  "mcpServers": {
    "firefox-devtools-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@mozilla/firefox-devtools-mcp@latest"
      ]
    }
  }
}

Selenium MCP

mcpServers (Claude Desktop / Cursor)
{
  "mcpServers": {
    "selenium-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@gaforov/selenium-mcp@latest"
      ]
    }
  }
}

Frequently asked questions

Firefox DevTools MCP is categorized under Browser Automation and uses a local stdio subprocess. Selenium MCP belongs to Browser Automation and uses a local stdio subprocess. Pick Firefox DevTools MCP for browser automation work and Selenium MCP for browser automation.

Copy the mcpServers block from the config section on this page into your client's config (for example claude_desktop_config.json or ~/.cursor/mcp.json), then fully restart the client.

Firefox DevTools MCP has no declared pricing — check the project's own site. Selenium MCP has no declared pricing — check the project's own site. If a server needs environment variables such as API keys, define them under the env key in your client's MCP config.

Yes. MCP clients support multiple servers: add firefox-devtools-mcp and selenium-mcp as separate keys in the same mcpServers object, and your assistant will call tools from either one.

On AllMCPs, Firefox DevTools MCP has a quality signal of 69/100 (Great) with 3 views, 0 installs and 506 GitHub stars. Selenium MCP has 59/100 (Good) with 2 views, 0 installs and 0 GitHub stars.