Skip to content

Pair with Chrome DevTools MCP ​

chrome-devtools-mcp gives an agent raw control of a live Chrome, and its extension tools (install_extension, list_extensions, reload_extension, trigger_extension_action, uninstall_extension) load and poke a built extension. Reach for both servers at once: let chrome-devtools-mcp drive Chrome itself, and let @extension.dev/mcp own everything that depends on the project, because it wraps an Extension.js dev session instead of a bare browser.

Quick start ​

bash
claude mcp add extension-dev npx @extension.dev/mcp
claude mcp add chrome-devtools -- npx chrome-devtools-mcp@latest --categoryExtensions

The -- hands --categoryExtensions to the server. Without it, claude parses the flag as its own. The extension.dev tools are namespaced extension_*, so the two servers never collide.

The replay runs the action with no gesture and is refused; loaded into chrome-devtools-mcp's own Chrome, a real click gets activeTab and adds the banner.
json
{
  "mcpServers": {
    "extension-dev": {
      "command": "npx",
      "args": ["@extension.dev/mcp"]
    },
    "chrome-devtools": {
      "command": "npx",
      "args": ["chrome-devtools-mcp@latest", "--categoryExtensions"]
    }
  }
}
json
{
  "mcpServers": {
    "extension-dev": {
      "command": "npx",
      "args": ["@extension.dev/mcp"]
    },
    "chrome-devtools": {
      "command": "npx",
      "args": ["chrome-devtools-mcp@latest", "--categoryExtensions"]
    }
  }
}

How it works ​

The two servers split the work by what a task touches. If it touches the project (source, build, manifest, reload), reach for the extension.dev server. If it touches the browser generically (pages, network, performance), reach for chrome-devtools-mcp.

chrome-devtools-mcp triggers an action over the DevTools protocol (Extensions.triggerAction), which Chrome runs as a user action on the toolbar button, the same path as a click: the handler gets a user gesture and the activeTab grant, and the selected page must be a tab in a browser window. Extension.js takes a different route: it captures the extension's chrome.action.onClicked and chrome.commands.onCommand listeners at install time and replays them on demand. Triggering becomes scriptable and reproducible, and because it only touches addListener it works on both Chromium and Firefox. A single background.service_worker source works on Firefox too, because the framework translates it to a background.scripts event page for the Firefox build.

No gesture on replay

Replay invokes the handler without a user gesture. A real toolbar click grants temporary activeTab and satisfies gesture-gated APIs (chrome.permissions.request, interactive identity.getAuthToken). A replay does not. A handler that relies on activeTab (chrome.scripting.executeScript on the active tab, or captureVisibleTab) behaves differently than it does on a real click. The result carries gesture: false, and an action replay also carries a warning when the manifest declares activeTab. When you need click fidelity, use chrome-devtools-mcp's trigger_extension_action.

The replay wraps live only in the dev build. A production build carries no reload client and no wrap, and the addListener wraps delegate to the originals, so the extension behaves the same with or without the bridge. The framework side is documented at extension.js.org/docs/debugging/trigger-actions-and-commands.

Pipe transport

The chrome-devtools-mcp extension tools (--categoryExtensions) need a pipe connection. Attaching to an already running browser over a WebSocket endpoint (browserUrl or wsEndpoint) is not supported for that category before Chrome 149. The extension.dev server connects to the browser the dev session launched, so its extension tools work today.

Reference ​

TaskUse
Build, dev server, hot reload, production packagingextension.dev (extension_dev, extension_build)
Validate the manifest across browsers before a buildextension.dev (extension_manifest_validate)
Replay the toolbar action handler, scriptably, no popupextension.dev (extension_open with surface: "action")
Replay a keyboard shortcut command handlerextension.dev (extension_open with surface: "command")
List the extensions loaded in the dev browserextension.dev (extension_list_extensions)
Logs across service worker, content scripts, popup, optionsextension.dev (extension_logs)
Read or write chrome.storage, eval in any contextextension.dev (extension_storage, extension_eval)
Same flow on Firefox, Edge or Safariextension.dev (cross-browser by design)
Drive an arbitrary web page, click, scroll, fill formschrome-devtools-mcp
Performance traces, Lighthouse audits, network inspectionchrome-devtools-mcp
Inspect an extension you did not build (no project)chrome-devtools-mcp
Trigger the action with a real gesture (grants activeTab)chrome-devtools-mcp (trigger_extension_action)

Every chrome-devtools-mcp extension verb has an extension.dev counterpart, plus a build platform around it.

chrome-devtools-mcpextension.devNotes
install_extensionextension_dev, extension_startextension_dev loads a real build with hot reload; extension_start runs the production build, or a prebuilt folder with outputPath
list_extensionsextension_list_extensionsRead-only, on Chromium and Firefox; live contexts on Chromium only
reload_extensionextension_reloadReloads the background or a tab, and waits for the new background to reattach
trigger_extension_actionextension_open (surface: "action")Portable replay of the onClicked handler, cross-browser, no gesture. For a genuine click that grants activeTab, use the left
noneextension_open (surface: "command")Replays a chrome.commands.onCommand keyboard shortcut handler; chrome-devtools-mcp has no equivalent
uninstall_extensionextension_stopThe dev session owns load and unload
console messages filtered by service workerextension_logsOne ordered timeline across every context, with follow

When it fails ​

  • A replayed handler does nothing on the active tab: it depends on activeTab, which a replay never grants. Read gesture: false and the warning in the result, then trigger it with chrome-devtools-mcp's trigger_extension_action. That path is Chromium only.
  • chrome-devtools-mcp lists no extension tools: the category is off by default. Start it with --categoryExtensions, and in Claude Code put -- before npx so the flag reaches the server.
  • The extension tools fail against a browser you attached to: --categoryExtensions needs a pipe connection, and browserUrl or wsEndpoint are not supported for it before Chrome 149. Let chrome-devtools-mcp launch its own Chrome.
  • The same name answers from both servers: it cannot. The extension.dev tools are all extension_*, and a trigger_extension_action call is chrome-devtools-mcp's.

Next ​