Skip to content

Enne2/firefox-bidi-mcp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

firefox-bidi-mcp

firefox-bidi-mcp logo

Created by Matteo Benedetto

A standalone Model Context Protocol (MCP) server for controlling an already-open Firefox instance through WebDriver BiDi.

This project is designed for workflows where Firefox is started manually with remote debugging enabled and an MCP-compatible client, such as GitHub Copilot in VS Code, needs to inspect existing tabs instead of launching a new browser process.

Features

  • Connects to an existing Firefox instance via WebDriver BiDi
  • Lists currently open top-level tabs
  • Activates a specific tab by browsing context id
  • Navigates the active tab or a chosen tab to a URL
  • Evaluates JavaScript in the selected tab
  • Captures screenshots from the selected tab
  • Keeps a BiDi session open across multiple tool calls
  • Closes the session cleanly with an explicit tool

Why this project exists

Firefox remote debugging is not Chrome CDP.

When Firefox is started with:

firefox --remote-debugging-port=9222

it exposes a WebDriver BiDi endpoint, typically:

ws://127.0.0.1:9222/session

Standard reconnect flows used by Chrome-based DevTools clients are often not suitable here. This server provides a small MCP wrapper around BiDi so an MCP client can work with the already-open Firefox session directly.

Requirements

  • Node.js 18+
  • Firefox started manually with remote debugging enabled
  • An MCP-compatible client

Installation

Local development

npm install

Run directly

npm start

Starting Firefox

Start Firefox manually before using the MCP server:

firefox --remote-debugging-port=9222

If your Firefox instance is exposed on a different host or port, configure the MCP server with the FIREFOX_BIDI_WS_URL environment variable.

Example:

FIREFOX_BIDI_WS_URL=ws://127.0.0.1:9223/session npm start

Tools exposed

firefox_bidi_open_session

Open and keep a Firefox WebDriver BiDi session alive for subsequent tool calls.

firefox_bidi_close_session

Close the current Firefox WebDriver BiDi session.

firefox_bidi_list_tabs

Return the top-level tabs visible in the already-open Firefox window.

firefox_bidi_select_tab

Activate a tab using its browsing context id.

Input:

{ "context": "<context-id>" }

firefox_bidi_navigate

Navigate the selected tab or a provided context to a URL.

Input:

{ "url": "https://example.com", "context": "<optional-context-id>" }

firefox_bidi_evaluate

Run JavaScript inside the selected tab.

Input:

{ "expression": "document.title", "context": "<optional-context-id>" }

firefox_bidi_screenshot

Capture a screenshot from the selected tab.

Input:

{ "context": "<optional-context-id>" }

Recommended usage flow

For most MCP clients, use this sequence:

  1. firefox_bidi_open_session
  2. firefox_bidi_list_tabs
  3. firefox_bidi_select_tab
  4. One or more of:
    • firefox_bidi_navigate
    • firefox_bidi_evaluate
    • firefox_bidi_screenshot
  5. firefox_bidi_close_session

This is important because Firefox often allows only one active BiDi session at a time.

Example MCP configuration for VS Code / Copilot

Example mcp.json entry:

{
  "servers": {
    "firefox-bidi": {
      "command": "node",
      "args": [
        "/absolute/path/to/firefox-bidi-mcp/src/index.mjs"
      ],
      "type": "stdio",
      "env": {
        "FIREFOX_BIDI_WS_URL": "ws://127.0.0.1:9222/session"
      }
    }
  }
}

Project structure

firefox-bidi-mcp/
├── package.json
├── README.md
├── LICENSE
├── .gitignore
└── src/
    └── index.mjs

Development notes

Protocol details

This project implements a lightweight WebSocket client directly over Node's net module instead of adding a heavier dependency. It:

  • performs the HTTP upgrade handshake
  • encodes masked client frames
  • decodes server frames
  • sends BiDi commands such as:
    • session.new
    • session.end
    • browsingContext.getTree
    • browsingContext.activate
    • browsingContext.navigate
    • browsingContext.captureScreenshot
    • script.evaluate

Session model

The server keeps one BiDi session open across tool calls and expects the client to manage the lifecycle explicitly through:

  • firefox_bidi_open_session
  • firefox_bidi_close_session

This avoids browsing context instability that can happen if a brand-new session is created for every individual tool call.

Limitations

  • Firefox may reject connections if another BiDi client is already attached
  • Context ids are valid only within the active session
  • The server currently focuses on tab listing, tab activation, evaluation, navigation, and screenshots
  • More advanced actions like DOM click/fill helpers are intentionally left to higher-level automation layers or custom scripts executed with firefox_bidi_evaluate

Publishing to GitHub

Suggested steps:

  1. Create a new repository named firefox-bidi-mcp
  2. Copy this folder into that repository root
  3. Commit and push
  4. Optionally publish to npm

Example:

git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin git@github.com:<your-user>/firefox-bidi-mcp.git
git push -u origin main

Publishing to npm

If you decide to publish:

npm login
npm publish

If the package name is already taken, update the name field in package.json first.

License

MIT

About

MCP server for controlling an already-open Firefox instance through WebDriver BiDi

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors