diff --git a/.agents/skills/bug-filing/SKILL.md b/.agents/skills/bug-filing/SKILL.md index dc18c83c..1e951495 100644 --- a/.agents/skills/bug-filing/SKILL.md +++ b/.agents/skills/bug-filing/SKILL.md @@ -1,6 +1,6 @@ --- name: bug-filing -description: File a Bugzilla bug for firefox-devtools-mcp, or draft a bug summary and description. Use when the user asks to file a bug, wants a bug summary/description for a change, or needs to report a defect/enhancement/task in this repo. Drafts the summary and description, and opens a prefilled enter_bug.cgi form in the browser for the user to submit. +description: File a Bugzilla bug for firefox-mcp, or draft a bug summary and description. Use when the user asks to file a bug, wants a bug summary/description for a change, or needs to report a defect/enhancement/task in this repo. Drafts the summary and description, and opens a prefilled enter_bug.cgi form in the browser for the user to submit. allowed-tools: - Bash(python3 .agents/skills/bug-filing/file-bug.py:*) - Bash(python3 .claude/skills/bug-filing/file-bug.py:*) diff --git a/.claude-plugin/COWORK.md b/.claude-plugin/COWORK.md index bb0517a5..29ad01a6 100644 --- a/.claude-plugin/COWORK.md +++ b/.claude-plugin/COWORK.md @@ -31,7 +31,7 @@ At any point, make sure the **Cowork** tab is selected and not the **Chat** tab. ![screenshot of Claude Desktop with the Add marketplace option highlighted](cowork-customize-add-marketplace.png) -6. Paste the URL of this repository (`https://github.com/mozilla/firefox-devtools-mcp`) in the popup, validate. +6. Paste the URL of this repository (`https://github.com/mozilla/firefox-mcp`) in the popup, validate. ![screenshot of Claude Desktop with the repository URL pasted in the popup](cowork-customize-add-marketplace-url.png) diff --git a/.claude-plugin/README.md b/.claude-plugin/README.md index fc12ef97..fe1702c4 100644 --- a/.claude-plugin/README.md +++ b/.claude-plugin/README.md @@ -1,4 +1,4 @@ -# Firefox DevTools Plugin for Claude Code +# Firefox MCP Plugin for Claude Code Control Firefox for automated browsing, web testing, and debugging. Navigate pages, fill forms, click elements, take screenshots, and monitor console/network activity. @@ -12,7 +12,7 @@ Control Firefox for automated browsing, web testing, and debugging. Navigate pag ## Installation ```bash -/plugin marketplace add mozilla/firefox-devtools-mcp +/plugin marketplace add mozilla/firefox-mcp /plugin install firefox-devtools-mcp@firefox-devtools-plugins ``` @@ -84,5 +84,5 @@ The plugin enables the following by default: ## Links -- [Repository](https://github.com/mozilla/firefox-devtools-mcp) -- [npm](https://www.npmjs.com/package/@mozilla/firefox-devtools-mcp) +- [Repository](https://github.com/mozilla/firefox-mcp) +- [npm](https://www.npmjs.com/package/@mozilla/firefox-mcp) diff --git a/.claude/skills/bug-filing/SKILL.md b/.claude/skills/bug-filing/SKILL.md index dc18c83c..1e951495 100644 --- a/.claude/skills/bug-filing/SKILL.md +++ b/.claude/skills/bug-filing/SKILL.md @@ -1,6 +1,6 @@ --- name: bug-filing -description: File a Bugzilla bug for firefox-devtools-mcp, or draft a bug summary and description. Use when the user asks to file a bug, wants a bug summary/description for a change, or needs to report a defect/enhancement/task in this repo. Drafts the summary and description, and opens a prefilled enter_bug.cgi form in the browser for the user to submit. +description: File a Bugzilla bug for firefox-mcp, or draft a bug summary and description. Use when the user asks to file a bug, wants a bug summary/description for a change, or needs to report a defect/enhancement/task in this repo. Drafts the summary and description, and opens a prefilled enter_bug.cgi form in the browser for the user to submit. allowed-tools: - Bash(python3 .agents/skills/bug-filing/file-bug.py:*) - Bash(python3 .claude/skills/bug-filing/file-bug.py:*) diff --git a/.codecov.yml b/.codecov.yml index 4d999e7d..1f5411d0 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,4 +1,4 @@ -# Codecov configuration for firefox-devtools-mcp +# Codecov configuration for firefox-mcp # https://docs.codecov.com/docs/codecov-yaml # Coverage targets diff --git a/.env.example b/.env.example index 5fadf7bf..d9fb40e7 100644 --- a/.env.example +++ b/.env.example @@ -23,5 +23,5 @@ FIREFOX_PROFILE_PATH= # Tool preset selecting which tool modules to enable (slim, basic, developer, mozilla, all) TOOL_PRESET=basic -# Debug logging (set to * or firefox-devtools for verbose logs) +# Debug logging (set to * or firefox-mcp for verbose logs) DEBUG= diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index bd6fab79..7d6e2e8c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -43,8 +43,18 @@ jobs: npm run format:check npm run build + # Each step skips a version already on npm, so a rerun can finish a partial publish. - name: Publish main package - run: npm publish --access public --provenance + run: | + PKG=$(node -p "require('./package.json').name + '@' + require('./package.json').version") + if [ "$(npm view "$PKG" version --prefer-online 2>/dev/null)" = "${PKG##*@}" ]; then + echo "$PKG is already published, skipping." + else + npm publish --access public --provenance + fi + + - name: Publish compat package + run: npm run publish:compat -- --access public --provenance - name: Publish moz package run: npm run publish:moz -- --access public --provenance diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1e030198..63dd78cc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,7 +32,7 @@ jobs: run: npm run test:run - name: Create archive - run: tar -czf firefox-devtools-mcp-${{ github.ref_name }}.tar.gz dist package.json README.md LICENSE-APACHE LICENSE-MIT + run: tar -czf firefox-mcp-${{ github.ref_name }}.tar.gz dist package.json README.md LICENSE-APACHE LICENSE-MIT - name: Build MCPB bundle run: npm run build:mcpb @@ -42,7 +42,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | gh release create ${{ github.ref_name }} \ - firefox-devtools-mcp-${{ github.ref_name }}.tar.gz \ + firefox-mcp-${{ github.ref_name }}.tar.gz \ dist-mcpb/*.mcpb \ --generate-notes diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f67a291f..6308ed26 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,11 +1,11 @@ -# Contributing to Firefox DevTools MCP +# Contributing to Firefox MCP ## Issues Issues are tracked on [Bugzilla](https://bugzilla.mozilla.org) under **product: Developer Infrastructure**, **component: Firefox MCP**. - [File a new issue](https://bugzilla.mozilla.org/enter_bug.cgi?format=__default__&blocked=2026717&product=Developer%20Infrastructure&component=Firefox%20MCP) -- [Meta bug (tracks all firefox-devtools-mcp issues)](https://bugzilla.mozilla.org/show_bug.cgi?id=2026717) +- [Meta bug (tracks all firefox-mcp issues)](https://bugzilla.mozilla.org/show_bug.cgi?id=2026717) For questions and discussion, join the [#firefox-devtools-mcp Matrix room](https://chat.mozilla.org/#/room/#firefox-devtools-mcp:mozilla.org). diff --git a/README.md b/README.md index 6a8c344a..f468d628 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# Firefox DevTools MCP +# Firefox MCP -[![npm version](https://badge.fury.io/js/@mozilla%2Ffirefox-devtools-mcp.svg)](https://www.npmjs.com/package/@mozilla/firefox-devtools-mcp) -[![CI](https://github.com/mozilla/firefox-devtools-mcp/workflows/CI/badge.svg)](https://github.com/mozilla/firefox-devtools-mcp/actions/workflows/ci.yml) -[![codecov](https://codecov.io/gh/mozilla/firefox-devtools-mcp/branch/main/graph/badge.svg)](https://codecov.io/gh/mozilla/firefox-devtools-mcp) +[![npm version](https://badge.fury.io/js/@mozilla%2Ffirefox-mcp.svg)](https://www.npmjs.com/package/@mozilla/firefox-mcp) +[![CI](https://github.com/mozilla/firefox-mcp/workflows/CI/badge.svg)](https://github.com/mozilla/firefox-mcp/actions/workflows/ci.yml) +[![codecov](https://codecov.io/gh/mozilla/firefox-mcp/branch/main/graph/badge.svg)](https://codecov.io/gh/mozilla/firefox-mcp) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE-MIT) [![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE-APACHE) Glama @@ -14,9 +14,11 @@ Model Context Protocol server that lets AI agents use Firefox. It has two main u It controls Firefox through WebDriver BiDi (via Selenium WebDriver) and works with Claude Code, Claude Desktop, Cursor, Cline and other MCP clients. -Repository: https://github.com/mozilla/firefox-devtools-mcp +Repository: https://github.com/mozilla/firefox-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. +Also published as `@mozilla/firefox-devtools-mcp` for existing setups. + +> **Note**: This MCP server requires a local Firefox browser installation and cannot run on cloud hosting services like glama.ai. Use `npx @mozilla/firefox-mcp@latest` to run locally, or use Docker with the provided Dockerfile. ## Security @@ -42,13 +44,13 @@ Recommended: use `npx` so you run the latest published version from npm. #### Claude Code ```bash -claude mcp add firefox-devtools npx @mozilla/firefox-devtools-mcp@latest +claude mcp add firefox npx @mozilla/firefox-mcp@latest # Headless + viewport via args -claude mcp add firefox-devtools npx @mozilla/firefox-devtools-mcp@latest -- --headless --viewport 1280x720 +claude mcp add firefox npx @mozilla/firefox-mcp@latest -- --headless --viewport 1280x720 # Or via environment variables -claude mcp add firefox-devtools npx @mozilla/firefox-devtools-mcp@latest \ +claude mcp add firefox npx @mozilla/firefox-mcp@latest \ --env START_URL=https://example.com \ --env FIREFOX_HEADLESS=true ``` @@ -56,17 +58,17 @@ claude mcp add firefox-devtools npx @mozilla/firefox-devtools-mcp@latest \ #### Codex ```bash -codex mcp add firefox-devtools -- npx @mozilla/firefox-devtools-mcp@latest +codex mcp add firefox -- npx @mozilla/firefox-mcp@latest # Headless + viewport via args -codex mcp add firefox-devtools -- \ - npx @mozilla/firefox-devtools-mcp@latest -- --headless --viewport 1280x720 +codex mcp add firefox -- \ + npx @mozilla/firefox-mcp@latest -- --headless --viewport 1280x720 # Or via environment variables -codex mcp add firefox-devtools \ +codex mcp add firefox \ --env START_URL=https://example.com \ --env FIREFOX_HEADLESS=true \ - -- npx @mozilla/firefox-devtools-mcp@latest + -- npx @mozilla/firefox-mcp@latest ``` ### Option B β€” Edit the configuration file @@ -78,9 +80,9 @@ Add to Claude Code’s mcp_settings.json: ```json { "mcpServers": { - "firefox-devtools": { + "firefox": { "command": "npx", - "args": ["-y", "@mozilla/firefox-devtools-mcp@latest", "--headless", "--viewport", "1280x720"], + "args": ["-y", "@mozilla/firefox-mcp@latest", "--headless", "--viewport", "1280x720"], "env": { "START_URL": "about:blank" } @@ -94,11 +96,11 @@ Add to Claude Code’s mcp_settings.json: Add to ~/.codex/config.toml: ```toml -[mcp_servers.firefox-devtools] +[mcp_servers.firefox] command = "npx" -args = ["-y", "@mozilla/firefox-devtools-mcp@latest", "--headless", "--viewport", "1280x720"] +args = ["-y", "@mozilla/firefox-mcp@latest", "--headless", "--viewport", "1280x720"] -[mcp_servers.firefox-devtools.env] +[mcp_servers.firefox.env] START_URL = "about:blank" ``` @@ -112,7 +114,7 @@ npm run setup ## Try it with MCP Inspector ```bash -npx @modelcontextprotocol/inspector npx @mozilla/firefox-devtools-mcp@latest --start-url https://example.com --headless +npx @modelcontextprotocol/inspector npx @mozilla/firefox-mcp@latest --start-url https://example.com --headless ``` Then call tools like: @@ -172,10 +174,10 @@ surface, and use `--tool-preset slim` or an explicit `--tools` list to drop it. ```bash # Use the developer preset (adds network, console, debugging and profiler tools) -npx @mozilla/firefox-devtools-mcp --tool-preset developer +npx @mozilla/firefox-mcp --tool-preset developer # Enable only the modules you need -npx @mozilla/firefox-devtools-mcp --tools pages network console +npx @mozilla/firefox-mcp --tools pages network console ``` The `prefs` and `privileged` modules require `MOZ_REMOTE_ALLOW_SYSTEM_ACCESS=1` and are only @@ -211,13 +213,13 @@ Use `--android-device` to automate Firefox running on an Android device. Require adb devices # Launch Firefox for Android on the single connected device -npx @mozilla/firefox-devtools-mcp --android-device auto --android-wipe-app-data +npx @mozilla/firefox-mcp --android-device auto --android-wipe-app-data # Target a specific device -npx @mozilla/firefox-devtools-mcp --android-device --android-wipe-app-data +npx @mozilla/firefox-mcp --android-device --android-wipe-app-data # Use Firefox Nightly instead -npx @mozilla/firefox-devtools-mcp --android-device --android-package org.mozilla.fenix --android-wipe-app-data +npx @mozilla/firefox-mcp --android-device --android-package org.mozilla.fenix --android-wipe-app-data ``` Port forwarding between the host and device is handled automatically by geckodriver. @@ -231,7 +233,7 @@ Use `--connect-existing` to automate your real browsing session, with cookies, l firefox --marionette --remote-debugging-port # Run the MCP server -npx @mozilla/firefox-devtools-mcp --connect-existing --marionette-port 2828 +npx @mozilla/firefox-mcp --connect-existing --marionette-port 2828 ``` Both flags are required because the MCP uses both WebDriver Classic (`--marionette`) and WebDriver BiDi (`--remote-debugging-port`). If Firefox is only started with `--marionette`, the MCP server fails to connect and asks you to restart Firefox with both flags. @@ -311,14 +313,14 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for more details on local development, te - Firefox not found: pass `--firefox-path "/Applications/Firefox.app/Contents/MacOS/firefox"` (macOS) or the correct path on your OS. - First run is slow: Selenium sets up the BiDi session; subsequent runs are faster. - Stale UIDs: a UID stays valid until its element is removed or the page navigates; take a fresh snapshot (`take_snapshot`) when a UID tool reports one is gone. -- Windows 10: Error during discovery for MCP server 'firefox-devtools': MCP error -32000: Connection closed +- Windows 10: Error during discovery for MCP server 'firefox': MCP error -32000: Connection closed - **Solution 1** Wrap with `cmd /c` ([details](https://github.com/modelcontextprotocol/servers/issues/1082#issuecomment-2791786310)): ```json "mcpServers": { - "firefox-devtools": { + "firefox": { "command": "cmd", - "args": ["/c", "npx", "-y", "@mozilla/firefox-devtools-mcp@latest"] + "args": ["/c", "npx", "-y", "@mozilla/firefox-mcp@latest"] } } ``` @@ -327,9 +329,9 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for more details on local development, te ```json "mcpServers": { - "firefox-devtools": { + "firefox": { "command": "C:\\nvm4w\\nodejs\\npx.ps1", - "args": ["-y", "@mozilla/firefox-devtools-mcp@latest"] + "args": ["-y", "@mozilla/firefox-mcp@latest"] } } ``` diff --git a/docker-compose.yml b/docker-compose.yml index e3136078..e901008f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,12 +1,12 @@ version: '3.8' services: - firefox-devtools-mcp: + firefox-mcp: build: context: . dockerfile: Dockerfile - image: firefox-devtools-mcp:latest - container_name: firefox-devtools-mcp + image: firefox-mcp:latest + container_name: firefox-mcp stdin_open: true tty: true environment: diff --git a/docs/ci-and-release.md b/docs/ci-and-release.md index 97482e0f..ff08078b 100644 --- a/docs/ci-and-release.md +++ b/docs/ci-and-release.md @@ -24,11 +24,17 @@ Workflows - Publish (.github/workflows/publish.yml) - On GitHub Release published, or via manual dispatch: builds and publishes to npm with provenance. - - Two jobs: `publish` pushes both npm packages, then `publish-mcp-registry` syncs `server.json` + - Two jobs: `publish` pushes the npm packages, then `publish-mcp-registry` syncs `server.json` to the `package.json` version and publishes to the official MCP Registry. + - `publish` pushes three packages from the same build: `@mozilla/firefox-mcp`, the compat + package `@mozilla/firefox-devtools-mcp` (the name used before the rename, still published so + that existing setups keep updating) and the moz package. - Manual dispatch takes `npm-publish` (default false) and `mcp-publish` (default true), so a failed registry publish can be re-run on its own without npm rejecting an already published version. `release.yml` passes both explicitly when it triggers the workflow. + - Each npm step skips a package whose version is already on npm. If a publish stops + halfway, rerun it with `npm-publish` checked and the release tag as the ref: it + publishes the missing packages with provenance, then registers the version. - The registry verifies the package on npm, so `publish-mcp-registry` first polls `npm view` for the version it is about to register, up to five minutes, and fails if it never appears. - To re-run the registry publish on its own, use the Actions UI, whose checkboxes send real @@ -57,14 +63,15 @@ MCP Registry `packages[].version` in step with `package.json`, and the publish job syncs them again in its own checkout so a release cannot register a mismatched version. - The registry proves package ownership through the `mcpName` field in `package.json`, which must - keep matching the `name` in `server.json` (`io.github.mozilla/firefox-devtools-mcp`). + keep matching the `name` in `server.json` (`io.github.mozilla/firefox-mcp`). - The `io.github.mozilla/*` namespace comes from owning the `mozilla` GitHub organization, so no DNS verification is involved. - `mcp-publisher` is pinned to a release and its sigstore bundle is checked with `cosign verify-blob` before it runs, since it executes in a job holding `id-token: write`. Bumping the pinned `VERSION` in the workflow is a deliberate step. -- `scripts/generate-moz-package.mjs` and `scripts/build-mcpb.mjs` both strip `mcpName` from the - `package.json` they ship, since neither artifact is the package registered under that name. +- `scripts/generate-moz-package.mjs`, `scripts/publish-compat-package.mjs` and + `scripts/build-mcpb.mjs` all strip `mcpName` from the `package.json` they ship, since none of + these artifacts is the package registered under that name. Client plugin manifests - `plugins/*/.claude-plugin/` (Claude), `gemini-extension.json` (Gemini CLI) and the root diff --git a/docs/firefox-client.md b/docs/firefox-client.md index d4497173..5a7e7743 100644 --- a/docs/firefox-client.md +++ b/docs/firefox-client.md @@ -42,7 +42,7 @@ In WebDriver BiDi mode, Firefox applies [RecommendedPreferences](https://searchf **Example:** `browser.ml.enable` is disabled by RecommendedPreferences, which prevents testing ML/AI features like Smart Window. Override it: ```bash -npx firefox-devtools-mcp --pref "browser.ml.enable=true" +npx @mozilla/firefox-mcp --pref "browser.ml.enable=true" ``` Runtime (requires `MOZ_REMOTE_ALLOW_SYSTEM_ACCESS=1`): diff --git a/gemini-extension.json b/gemini-extension.json index 60ebb590..19cf202d 100644 --- a/gemini-extension.json +++ b/gemini-extension.json @@ -1,13 +1,13 @@ { - "name": "firefox-devtools-mcp", + "name": "firefox-mcp", "version": "0.10.7", "description": "Control Firefox for browsing, web testing, and debugging. Fill forms, capture network and console activity, take screenshots, run scripts, and profile performance. Supports Android devices.", "mcpServers": { - "firefox-devtools": { + "firefox": { "command": "npx", "args": [ "-y", - "@mozilla/firefox-devtools-mcp@latest", + "@mozilla/firefox-mcp@latest", "--auto-profile", "--tool-preset", "developer", diff --git a/manifest.mcpb.json b/manifest.mcpb.json index 1036a10a..2b9c4fcb 100644 --- a/manifest.mcpb.json +++ b/manifest.mcpb.json @@ -1,18 +1,18 @@ { "manifest_version": "0.3", - "name": "firefox-devtools-mcp", - "display_name": "Firefox DevTools MCP", + "name": "firefox-mcp", + "display_name": "Firefox MCP", "version": "0.10.7", "description": "Control Firefox for browsing, web testing, and debugging. Fill forms, capture network and console activity, take screenshots, run scripts, and profile performance. Supports Android devices.", "author": { "name": "Mozilla", - "url": "https://github.com/mozilla/firefox-devtools-mcp" + "url": "https://github.com/mozilla/firefox-mcp" }, "repository": { "type": "git", - "url": "https://github.com/mozilla/firefox-devtools-mcp.git" + "url": "https://github.com/mozilla/firefox-mcp.git" }, - "homepage": "https://github.com/mozilla/firefox-devtools-mcp", + "homepage": "https://github.com/mozilla/firefox-mcp", "license": "MIT OR Apache-2.0", "server": { "type": "node", diff --git a/package-lock.json b/package-lock.json index ee026ad5..3befae55 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "@mozilla/firefox-devtools-mcp", + "name": "@mozilla/firefox-mcp", "version": "0.10.7", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@mozilla/firefox-devtools-mcp", + "name": "@mozilla/firefox-mcp", "version": "0.10.7", "license": "MIT OR Apache-2.0", "dependencies": { @@ -16,7 +16,7 @@ "yargs": "17.7.2" }, "bin": { - "firefox-devtools-mcp": "dist/index.js" + "firefox-mcp": "dist/index.js" }, "devDependencies": { "@anthropic-ai/mcpb": "2.1.2", diff --git a/package.json b/package.json index 7ebc2f0b..58e26757 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,15 @@ { - "name": "@mozilla/firefox-devtools-mcp", + "name": "@mozilla/firefox-mcp", "version": "0.10.7", "description": "Model Context Protocol (MCP) server that lets AI agents browse the web and debug web pages with Firefox", - "mcpName": "io.github.mozilla/firefox-devtools-mcp", + "mcpName": "io.github.mozilla/firefox-mcp", "author": "Mozilla", "license": "MIT OR Apache-2.0", "type": "module", "main": "dist/index.js", "types": "dist/index.d.ts", "bin": { - "firefox-devtools-mcp": "dist/index.js" + "firefox-mcp": "dist/index.js" }, "scripts": { "dev": "tsx watch src/index.moz.ts", @@ -18,6 +18,7 @@ "build:all": "npm run build && npm run build:moz", "build:mcpb": "node scripts/build-mcpb.mjs", "publish:moz": "node scripts/publish-moz-package.mjs", + "publish:compat": "node scripts/publish-compat-package.mjs", "start": "node dist/index.js", "setup": "node scripts/setup-mcp-config.js", "docs:tools": "tsx scripts/generate-tools-doc.ts", @@ -104,12 +105,12 @@ ], "repository": { "type": "git", - "url": "git+https://github.com/mozilla/firefox-devtools-mcp.git" + "url": "git+https://github.com/mozilla/firefox-mcp.git" }, "bugs": { - "url": "https://github.com/mozilla/firefox-devtools-mcp/issues" + "url": "https://github.com/mozilla/firefox-mcp/issues" }, - "homepage": "https://github.com/mozilla/firefox-devtools-mcp#readme", + "homepage": "https://github.com/mozilla/firefox-mcp#readme", "publishConfig": { "access": "public" } diff --git a/plugins/firefox-devtools-mcp/agents/e2e-tester.md b/plugins/firefox-devtools-mcp/agents/e2e-tester.md index 590cc1af..ddd082fc 100644 --- a/plugins/firefox-devtools-mcp/agents/e2e-tester.md +++ b/plugins/firefox-devtools-mcp/agents/e2e-tester.md @@ -4,7 +4,7 @@ description: Agent for running E2E tests on web applications. Navigates pages, f model: sonnet --- -You are an E2E testing agent specializing in automated browser testing using Firefox DevTools MCP. +You are an E2E testing agent specializing in automated browser testing using Firefox MCP. ## Your Task diff --git a/plugins/firefox-devtools-mcp/agents/web-extractor.md b/plugins/firefox-devtools-mcp/agents/web-extractor.md index 8dc6922c..b1aa3a39 100644 --- a/plugins/firefox-devtools-mcp/agents/web-extractor.md +++ b/plugins/firefox-devtools-mcp/agents/web-extractor.md @@ -4,7 +4,7 @@ description: Agent for browsing and extracting structured content from web pages model: sonnet --- -You are a web extraction agent specializing in retrieving structured content from web pages using Firefox DevTools MCP. +You are a web extraction agent specializing in retrieving structured content from web pages using Firefox MCP. ## Your Task diff --git a/plugins/firefox-devtools-mcp/skills/browser-automation/SKILL.md b/plugins/firefox-devtools-mcp/skills/browser-automation/SKILL.md index b512487f..cc0c3a1a 100644 --- a/plugins/firefox-devtools-mcp/skills/browser-automation/SKILL.md +++ b/plugins/firefox-devtools-mcp/skills/browser-automation/SKILL.md @@ -3,7 +3,7 @@ name: browser-automation description: This skill should be used when the user asks about browser automation, testing web pages, extracting content, filling forms, taking screenshots, or monitoring console/network activity. Activates for E2E testing, form automation, browsing tasks, or debugging web applications. --- -When the user asks about browser automation, use Firefox DevTools MCP to control a real Firefox browser. +When the user asks about browser automation, use Firefox MCP to control a real Firefox browser. ## Before Starting diff --git a/plugins/firefox-devtools-mcp/skills/web-performance/SKILL.md b/plugins/firefox-devtools-mcp/skills/web-performance/SKILL.md index f0f40e8b..fb62473e 100644 --- a/plugins/firefox-devtools-mcp/skills/web-performance/SKILL.md +++ b/plugins/firefox-devtools-mcp/skills/web-performance/SKILL.md @@ -3,7 +3,7 @@ name: web-performance description: Find and fix why a website is slow by capturing and analyzing a Firefox performance profile, or by analyzing a profile the user already has (a saved file or a profiler.firefox.com share link). Use for slow page loads, janky scrolling or animation, slow interactions or a slow STR, long tasks, layout thrashing, or heavy JavaScript. --- -Work from a real profile, find the cause in the user's code, report it honestly, and if asked, fix it and prove the fix worked. The firefox-devtools MCP drives Firefox and records a profile when there is none yet; `profiler-cli` queries the profile, whether you captured it or the user brought it. Report in web-platform terms (LCP, main-thread blocking, reflow, render-blocking resources), not Gecko internals - unless the target is Firefox itself rather than a page, in which case platform frames are the subject and the fix lands in mozilla-central. +Work from a real profile, find the cause in the user's code, report it honestly, and if asked, fix it and prove the fix worked. The Firefox MCP drives Firefox and records a profile when there is none yet; `profiler-cli` queries the profile, whether you captured it or the user brought it. Report in web-platform terms (LCP, main-thread blocking, reflow, render-blocking resources), not Gecko internals - unless the target is Firefox itself rather than a page, in which case platform frames are the subject and the fix lands in mozilla-central. ## Step 0: Prerequisites diff --git a/plugins/firefox-devtools-troubleshoot/skills/diagnose/SKILL.md b/plugins/firefox-devtools-troubleshoot/skills/diagnose/SKILL.md index 4054e19c..50d7dc1e 100644 --- a/plugins/firefox-devtools-troubleshoot/skills/diagnose/SKILL.md +++ b/plugins/firefox-devtools-troubleshoot/skills/diagnose/SKILL.md @@ -1,9 +1,9 @@ --- name: firefox-devtools-diagnose -description: Diagnose Firefox DevTools MCP setup issues. Activate when the firefox-devtools-mcp plugin fails to connect, its tools are not available, or the user reports Firefox DevTools not working in Cowork. +description: Diagnose Firefox MCP setup issues. Activate when the firefox-devtools-mcp plugin fails to connect, its tools are not available, or the user reports Firefox MCP not working in Cowork. --- -When Firefox DevTools MCP tools are unavailable or the user reports issues with the firefox-devtools-mcp plugin, run this diagnostic sequence automatically. Do not ask the user to do these checks manually. +When Firefox MCP tools are unavailable or the user reports issues with the firefox-devtools-mcp plugin, run this diagnostic sequence automatically. Do not ask the user to do these checks manually. ## Diagnostic Steps @@ -29,7 +29,7 @@ Since an absent tool list can't be attributed to a single cause from your side, - Open **Customize > Plugins** in Claude Cowork and confirm `firefox-devtools-mcp` appears in the list. - Confirm they are currently in the **Cowork** tab, not the **Chat** tab β€” plugins only work in Cowork. -- If the plugin is missing: direct them to the installation steps at https://github.com/mozilla/firefox-devtools-mcp. +- If the plugin is missing: direct them to the installation steps at https://github.com/mozilla/firefox-mcp. - If the plugin is present but they were in Chat: ask them to switch to Cowork and retry. - If the plugin is present and they are already in Cowork: continue to the next step. diff --git a/scripts/_helpers/publish-staged.mjs b/scripts/_helpers/publish-staged.mjs new file mode 100644 index 00000000..c13d681a --- /dev/null +++ b/scripts/_helpers/publish-staged.mjs @@ -0,0 +1,64 @@ +/** + * Publishes a package built from this repository under its own package.json. + * Copies the entries of `pkg.files` from the repository root into a temporary + * folder, writes `pkg` there as package.json, then runs npm publish from there. + */ + +import { existsSync, cpSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'; +import { execSync } from 'node:child_process'; +import { resolve, dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { tmpdir } from 'node:os'; + +export const root = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..'); + +function isPublished({ name, version }) { + try { + const output = execSync(`npm view ${name}@${version} version --prefer-online`, { + stdio: ['ignore', 'pipe', 'ignore'], + }); + return output.toString().trim() === version; + } catch { + return false; + } +} + +/** + * Does nothing when this version is already on npm, so that a publish job can + * be rerun after it stopped halfway. + * + * @param {object} options + * @param {object} options.pkg content of the published package.json + * @param {string} options.stagingPrefix prefix of the temporary folder name + * @param {string[]} options.npmArgs extra arguments forwarded to npm publish + * @param {(stagingDir: string) => void} [options.prepare] adjusts the staged files before publishing + */ +export function publishStaged({ pkg, stagingPrefix, npmArgs, prepare }) { + if (isPublished(pkg)) { + console.log(`${pkg.name}@${pkg.version} is already published, skipping.`); + return; + } + + const stagingDir = mkdtempSync(resolve(tmpdir(), stagingPrefix)); + + try { + for (const entry of pkg.files) { + const src = resolve(root, entry); + const dst = resolve(stagingDir, entry); + if (!existsSync(src)) { + console.warn(`Warning: ${entry} not found, skipping`); + continue; + } + mkdirSync(dirname(dst), { recursive: true }); + cpSync(src, dst, { recursive: true }); + } + + writeFileSync(resolve(stagingDir, 'package.json'), JSON.stringify(pkg, null, 2) + '\n'); + prepare?.(stagingDir); + + console.log(`Publishing ${pkg.name}@${pkg.version}...`); + execSync(`npm publish ${npmArgs.join(' ')}`, { cwd: stagingDir, stdio: 'inherit' }); + } finally { + rmSync(stagingDir, { recursive: true, force: true }); + } +} diff --git a/scripts/build-mcpb.mjs b/scripts/build-mcpb.mjs index 115b069e..023ad850 100644 --- a/scripts/build-mcpb.mjs +++ b/scripts/build-mcpb.mjs @@ -1,6 +1,6 @@ #!/usr/bin/env node /** - * Builds the firefox-devtools-mcp .mcpb bundle (Claude Desktop extension). + * Builds the firefox-mcp .mcpb bundle (Claude Desktop extension). * Assembles a staging directory with dist/, production node_modules and * manifest.json, then runs `mcpb pack` on it. */ @@ -18,7 +18,7 @@ const manifest = JSON.parse(readFileSync(resolve(root, 'manifest.mcpb.json'), 'u console.log('Building server...'); execSync('npm run build', { cwd: root, stdio: 'inherit' }); -const stagingDir = mkdtempSync(resolve(tmpdir(), 'firefox-devtools-mcpb-')); +const stagingDir = mkdtempSync(resolve(tmpdir(), 'firefox-mcpb-')); try { cpSync(resolve(root, 'dist'), resolve(stagingDir, 'dist'), { recursive: true }); @@ -44,7 +44,7 @@ try { const outDir = resolve(root, 'dist-mcpb'); mkdirSync(outDir, { recursive: true }); - const outFile = resolve(outDir, `firefox-devtools-mcp-${pkg.version}.mcpb`); + const outFile = resolve(outDir, `firefox-mcp-${pkg.version}.mcpb`); console.log('Packing .mcpb bundle...'); execSync(`npx mcpb pack "${stagingDir}" "${outFile}"`, { diff --git a/scripts/demo-server.js b/scripts/demo-server.js index b199abb6..8265d697 100644 --- a/scripts/demo-server.js +++ b/scripts/demo-server.js @@ -91,7 +91,7 @@ const HTML_PAGE = `
-

🦊 Firefox DevTools MCP

+

🦊 Firefox MCP

Demo Page for Testing MCP Tools

Use this page with the MCP Inspector to test various tools!

@@ -204,7 +204,7 @@ const HTML_PAGE = ` function logObject() { console.log('Object:', { - name: 'Firefox DevTools MCP', + name: 'Firefox MCP', version: '0.1.0', features: ['console', 'dialog', 'input', 'screenshot'], config: { headless: false, timeout: 5000 } @@ -263,7 +263,7 @@ const HTML_PAGE = ` } // Initial log - console.log('🦊 Firefox DevTools MCP Demo Page Loaded!'); + console.log('🦊 Firefox MCP Demo Page Loaded!'); console.info('Server running on http://localhost:3456'); console.info('Use MCP Inspector to test tools: list_console_messages, list_pages, etc.'); @@ -286,7 +286,7 @@ const server = http.createServer((req, res) => { server.listen(PORT, () => { console.log(''); - console.log('🦊 Firefox DevTools MCP - Demo Server'); + console.log('🦊 Firefox MCP - Demo Server'); console.log('====================================='); console.log(''); console.log(`🌐 Server running at: http://localhost:${PORT}`); diff --git a/scripts/generate-moz-package.mjs b/scripts/generate-moz-package.mjs index bc0956fe..7cf7d614 100644 --- a/scripts/generate-moz-package.mjs +++ b/scripts/generate-moz-package.mjs @@ -1,7 +1,7 @@ #!/usr/bin/env node /** * Generates package.moz.json from package.json by applying the overrides - * needed for the @mozilla/firefox-devtools-mcp-moz npm package. + * needed for the @mozilla/firefox-mcp-moz npm package. */ import { readFileSync, writeFileSync } from 'node:fs'; @@ -13,13 +13,13 @@ const pkg = JSON.parse(readFileSync(resolve(root, 'package.json'), 'utf8')); const moz = { ...pkg, - name: '@mozilla/firefox-devtools-mcp-moz', + name: '@mozilla/firefox-mcp-moz', description: pkg.description + ' (moz build with privileged context support)', main: 'dist.moz/index.js', types: 'dist.moz/index.d.ts', bin: { - 'firefox-devtools-mcp-moz': './dist.moz/index.js', + 'firefox-mcp-moz': './dist.moz/index.js', }, files: ['dist.moz', 'README.md', 'LICENSE', 'scripts', 'plugins'], publishConfig: { diff --git a/scripts/publish-compat-package.mjs b/scripts/publish-compat-package.mjs new file mode 100755 index 00000000..79d64aea --- /dev/null +++ b/scripts/publish-compat-package.mjs @@ -0,0 +1,46 @@ +#!/usr/bin/env node +/** + * Publishes the current dist/ build as @mozilla/firefox-devtools-mcp, the + * package name used before the rename to firefox-mcp, so that existing + * `npx @mozilla/firefox-devtools-mcp@latest` setups keep updating. + * Run it after the main package is built. + * + * Any extra arguments are forwarded to npm publish, e.g.: + * node publish-compat-package.mjs --access public --provenance + */ + +import { existsSync, readFileSync, writeFileSync } from 'node:fs'; +import { resolve } from 'node:path'; +import { publishStaged, root } from './_helpers/publish-staged.mjs'; + +if (!existsSync(resolve(root, 'dist', 'index.js'))) { + console.error('dist/index.js not found, run npm run build first.'); + process.exit(1); +} + +const pkg = JSON.parse(readFileSync(resolve(root, 'package.json'), 'utf8')); +const compat = { + ...pkg, + name: '@mozilla/firefox-devtools-mcp', + // A bin name of its own, so both packages can be installed globally side by side + bin: { 'firefox-devtools-mcp': 'dist/index.js' }, +}; + +// prepublishOnly would rebuild inside the staging directory +delete compat.scripts; + +// mcpName claims the MCP registry entry of the canonical package, not this one +delete compat.mcpName; + +publishStaged({ + pkg: compat, + stagingPrefix: 'firefox-devtools-mcp-compat-', + npmArgs: process.argv.slice(2), + prepare: (stagingDir) => { + const readme = resolve(stagingDir, 'README.md'); + const notice = + `**This package is now published as [\`${pkg.name}\`](https://www.npmjs.com/package/${pkg.name}).** ` + + `\`${compat.name}\` gets the same releases, so existing setups keep working.\n\n`; + writeFileSync(readme, notice + readFileSync(readme, 'utf8')); + }, +}); diff --git a/scripts/publish-moz-package.mjs b/scripts/publish-moz-package.mjs index 9cf2667d..1d2321b8 100644 --- a/scripts/publish-moz-package.mjs +++ b/scripts/publish-moz-package.mjs @@ -1,6 +1,6 @@ #!/usr/bin/env node /** - * Builds and publishes the firefox-devtools-mcp-moz package. + * Builds and publishes the firefox-mcp-moz package. * Creates a staging directory with dist.moz/ and package.moz.json as package.json, * then runs npm publish from there. * @@ -8,37 +8,16 @@ * node publish-moz-package.mjs --access public --provenance */ -import { readFileSync, existsSync, cpSync, copyFileSync, mkdirSync, mkdtempSync, rmSync } from 'node:fs'; +import { readFileSync } from 'node:fs'; import { execSync } from 'node:child_process'; -import { resolve, dirname } from 'node:path'; -import { fileURLToPath } from 'node:url'; -import { tmpdir } from 'node:os'; - -const root = resolve(dirname(fileURLToPath(import.meta.url)), '..'); +import { resolve } from 'node:path'; +import { publishStaged, root } from './_helpers/publish-staged.mjs'; console.log('Building moz package...'); execSync('npm run build:moz', { cwd: root, stdio: 'inherit' }); -const mozPkg = JSON.parse(readFileSync(resolve(root, 'package.moz.json'), 'utf8')); -const stagingDir = mkdtempSync(resolve(tmpdir(), 'firefox-devtools-mcp-moz-')); - -try { - for (const entry of mozPkg.files) { - const src = resolve(root, entry); - const dst = resolve(stagingDir, entry); - if (!existsSync(src)) { - console.warn(`Warning: ${entry} not found, skipping`); - continue; - } - mkdirSync(dirname(dst), { recursive: true }); - cpSync(src, dst, { recursive: true }); - } - - copyFileSync(resolve(root, 'package.moz.json'), resolve(stagingDir, 'package.json')); - - const extraArgs = process.argv.slice(2).join(' '); - console.log(`Publishing ${mozPkg.name}@${mozPkg.version}...`); - execSync(`npm publish ${extraArgs}`, { cwd: stagingDir, stdio: 'inherit' }); -} finally { - rmSync(stagingDir, { recursive: true, force: true }); -} +publishStaged({ + pkg: JSON.parse(readFileSync(resolve(root, 'package.moz.json'), 'utf8')), + stagingPrefix: 'firefox-mcp-moz-', + npmArgs: process.argv.slice(2), +}); diff --git a/scripts/setup-mcp-config.js b/scripts/setup-mcp-config.js index f1aee91c..c4dc9ce0 100755 --- a/scripts/setup-mcp-config.js +++ b/scripts/setup-mcp-config.js @@ -62,7 +62,7 @@ function detectNodePath() { async function main() { console.log( - `${colors.bright}${colors.blue}πŸš€ Firefox DevTools MCP Configuration Setup${colors.reset}\n` + `${colors.bright}${colors.blue}πŸš€ Firefox MCP Configuration Setup${colors.reset}\n` ); // Ask which client to configure @@ -136,7 +136,7 @@ async function main() { // Create MCP config const mcpConfig = { mcpServers: { - 'firefox-devtools': { + 'firefox': { command: finalNodePath, args: [distIndexPath, '--headless=' + (headless.toLowerCase() === 'y' ? 'true' : 'false'), '--viewport=' + viewport], }, @@ -192,9 +192,9 @@ async function main() { if (fs.existsSync(configPath)) { try { existingConfig = JSON.parse(fs.readFileSync(configPath, 'utf8')); - if (existingConfig.mcpServers && existingConfig.mcpServers['firefox-devtools']) { + if (existingConfig.mcpServers && existingConfig.mcpServers['firefox']) { const overwrite = await question( - `\n${colors.yellow}⚠️ 'firefox-devtools' server already exists in ${clientName}. Overwrite? (y/n): ${colors.reset}` + `\n${colors.yellow}⚠️ 'firefox' server already exists in ${clientName}. Overwrite? (y/n): ${colors.reset}` ); if (overwrite.toLowerCase() !== 'y') { console.log(`Skipped ${clientName}`); diff --git a/server.json b/server.json index db42b209..ba82dcaf 100644 --- a/server.json +++ b/server.json @@ -1,19 +1,19 @@ { "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json", - "name": "io.github.mozilla/firefox-devtools-mcp", - "title": "Firefox DevTools MCP", + "name": "io.github.mozilla/firefox-mcp", + "title": "Firefox MCP", "description": "Control and debug Firefox: navigate, fill forms, inspect network and console, profile.", "version": "0.10.7", - "websiteUrl": "https://github.com/mozilla/firefox-devtools-mcp", + "websiteUrl": "https://github.com/mozilla/firefox-mcp", "repository": { - "url": "https://github.com/mozilla/firefox-devtools-mcp", + "url": "https://github.com/mozilla/firefox-mcp", "source": "github" }, "packages": [ { "registryType": "npm", "registryBaseUrl": "https://registry.npmjs.org", - "identifier": "@mozilla/firefox-devtools-mcp", + "identifier": "@mozilla/firefox-mcp", "version": "0.10.7", "transport": { "type": "stdio" diff --git a/src/cli.ts b/src/cli.ts index ded1aeb1..421bd95c 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,5 +1,5 @@ /** - * CLI argument parsing for Firefox DevTools MCP server + * CLI argument parsing for Firefox MCP server */ import type { Options as YargsOptions } from 'yargs'; @@ -101,7 +101,7 @@ export const cliOptions = { firefoxArg: { type: 'array', description: - 'Additional arguments for Firefox. Only applies when Firefox is launched by firefox-devtools-mcp.', + 'Additional arguments for Firefox. Only applies when Firefox is launched by firefox-mcp.', }, startUrl: { type: 'string', @@ -229,7 +229,7 @@ export function parseArguments(version: string, argv = process.argv, includePriv const { enablePrivilegedContext: _, ...rest } = cliOptions; const options = includePrivileged ? cliOptions : rest; const yargsInstance = yargs(hideBin(argv)) - .scriptName('npx firefox-devtools-mcp@latest') + .scriptName('npx @mozilla/firefox-mcp@latest') .options(options) .example([ [ diff --git a/src/config/constants.ts b/src/config/constants.ts index 35afe5c3..18771398 100644 --- a/src/config/constants.ts +++ b/src/config/constants.ts @@ -1,12 +1,11 @@ /** - * Configuration constants for Firefox DevTools MCP server + * Configuration constants for Firefox MCP server */ // Injected at build time by esbuild define declare const __SERVER_NAME__: string | undefined; declare const __SERVER_VERSION__: string | undefined; -export const SERVER_NAME = - typeof __SERVER_NAME__ !== 'undefined' ? __SERVER_NAME__ : 'firefox-devtools'; +export const SERVER_NAME = typeof __SERVER_NAME__ !== 'undefined' ? __SERVER_NAME__ : 'firefox-mcp'; export const SERVER_VERSION = typeof __SERVER_VERSION__ !== 'undefined' ? __SERVER_VERSION__ : 'dev'; diff --git a/src/firefox/core.ts b/src/firefox/core.ts index 596c87b4..85289c47 100644 --- a/src/firefox/core.ts +++ b/src/firefox/core.ts @@ -316,7 +316,7 @@ export class FirefoxCore { throw new Error( `Another WebDriver session is already active in Firefox on 127.0.0.1:${port}, ` + 'and Marionette allows only one at a time. If it belongs to another ' + - 'firefox-devtools-mcp server started with --connect-existing, that server releases ' + + 'firefox-mcp server started with --connect-existing, that server releases ' + 'Firefox when it calls close_firefox_session or after it has been idle; try again then.' ); } diff --git a/src/firefox/profile.ts b/src/firefox/profile.ts index 10c36540..300f19f6 100644 --- a/src/firefox/profile.ts +++ b/src/firefox/profile.ts @@ -1,5 +1,5 @@ /** - * Profile path resolution for Firefox DevTools MCP + * Profile path resolution for Firefox MCP * * Unmarked user supplied paths use a dedicated subfolder to avoid reusing a * real browser profile in an automated session. Marked MCP profiles can be diff --git a/src/index.ts b/src/index.ts index 1a8014db..580e42ac 100644 --- a/src/index.ts +++ b/src/index.ts @@ -310,7 +310,7 @@ export async function run( const transport = new StdioServerTransport(); await mcpServer.connect(transport); - log('Firefox DevTools MCP server running on stdio'); + log('Firefox MCP server running on stdio'); log('Ready to accept tool requests'); // Clean up the Marionette session so Firefox accepts new connections. diff --git a/src/tools/downloads.ts b/src/tools/downloads.ts index a09dca31..af997e5c 100644 --- a/src/tools/downloads.ts +++ b/src/tools/downloads.ts @@ -1,5 +1,5 @@ /** - * Download tracking tools for Firefox DevTools MCP + * Download tracking tools for Firefox MCP * Surfaces BiDi download events and controls download behavior */ diff --git a/src/tools/network.ts b/src/tools/network.ts index 4880614f..8b34a4fd 100644 --- a/src/tools/network.ts +++ b/src/tools/network.ts @@ -1,5 +1,5 @@ /** - * Network monitoring tools for Firefox DevTools MCP + * Network monitoring tools for Firefox MCP * Provides network request inspection capabilities */ diff --git a/src/types/common.ts b/src/types/common.ts index 3571569e..b831ddc0 100644 --- a/src/types/common.ts +++ b/src/types/common.ts @@ -1,5 +1,5 @@ /** - * Common types shared across the Firefox DevTools MCP server + * Common types shared across the Firefox MCP server */ export type McpContentItem = diff --git a/src/utils/errors.ts b/src/utils/errors.ts index 6f89750a..ce64f8f4 100644 --- a/src/utils/errors.ts +++ b/src/utils/errors.ts @@ -1,5 +1,5 @@ /** - * Custom error classes for Firefox DevTools MCP + * Custom error classes for Firefox MCP */ /**