install, list, reload, trigger, and uninstall, plus service-worker logs). The Extension.js MCP server (@extension.dev/mcp) covers the same extension capabilities, but build-aware and across browsers.
They are complementary, not competing. Run both: let chrome-devtools-mcp drive Chrome itself, and let Extension.js own everything that depends on your project: the build, hot reload, the generated manifest, storage, logs across every context, and the same workflow on Firefox, Edge, and Safari.
When to use which
A useful rule of thumb: if the task touches your project (source, build, manifest, reload), reach for Extension.js. If it touches the browser generically (pages, network, performance), reach for chrome-devtools-mcp.
Install both servers
Extension.js tools are namespaced underextension_*, so they never collide with chrome-devtools-mcp tools. An agent fluent in one transfers to the other.
The chrome-devtools-mcp extension tools (
--categoryExtensions) currently
require a pipe connection. Attaching to an already-running browser over a
WebSocket endpoint (browserUrl / wsEndpoint) is not supported for the
extension category until Chrome 149. Extension.js connects to the browser it
launched for your dev session, so its extension tools work today.Capability map
Every chrome-devtools-mcp extension verb has an Extension.js counterpart, plus a build platform around it.How the action / command triggers work, and their one caveat
chrome-devtools-mcp triggers an action by clicking the real toolbar button, which needs a visible window and a genuine user gesture. Extension.js takes a different approach: it captures the extension’schrome.action.onClicked (and chrome.commands.onCommand) listeners at build time and replays them on demand. That makes triggering scriptable and reproducible (the natural mode for agentic testing) and, because it only touches addListener, it works on both Chromium and Firefox (verified on both). A single background.service_worker source works on Firefox too: Extension.js translates it to a background.scripts event page for the Firefox target, since Firefox doesn’t run service-worker backgrounds.
Need a genuine-gesture click? Use chrome-devtools-mcp
The two are complementary, not competing:extension_open(surface: "action"): the everyday path. Replays the handler, cross-browser, headless, no gesture (activeTabnot granted). Use it for the vast majority of handler testing.- chrome-devtools-mcp
trigger_extension_action: a real action invocation through Puppeteer (over the supported pipe transport), soactiveTabis granted exactly like a user click. Chromium only. Reach for it only when your handler genuinely depends on the gesture.
Safe by construction
The replay wraps are injected only into your dev build: the agent bridge is gated on a control port that exists solely duringextension dev/preview, and nothing is added to a production build. The addListener wraps delegate transparently to the originals, so your extension behaves identically with or without the bridge.
Next steps
- Connect the docs to your assistant too: AI access via MCP and llms.txt.
- Wire checks into your pipeline: CI templates.
- Ship the same extension everywhere: Cross-browser compatibility.

