Build, run, inspect, and publish browser extensions from any MCP client. 34 tools, 13 browsers.
io.github.extensiondev/mcp — Model Context Protocol (MCP) server for browser extensions
The io.github.extensiondev/mcp server lets an MCP client build, run, inspect, and publish browser extensions. It provides 30 tools and supports 11 browsers, covering extension packaging and cross-browser extension workflows via the Model Context Protocol.
🛠️ Key Features
30 tools
Build, run, inspect, and publish browser extensions
Supports 11 browsers
Cross-browser extension focus
🚀 Use Cases
Building and publishing browser extensions from an MCP client
Running and inspecting extensions during development
Targeting multiple browsers with one workflow
⚡ Developer Benefits
MCP client integration for extension development
Tooling breadth (30 tools) for extension lifecycle tasks
Multi-browser support (11 browsers)
⚠️ Limitations
Supported functionality is limited to build, run, inspect, and publish extension operations, as described in the provided data.
Give your AI agent hands for browser extension development. 34 MCP tools that scaffold, run, inspect, debug, test, and build cross-browser extensions on your machine, plus a platform lane (private alpha) to share and publish them.
bash
claude mcp add extension-dev npx @extension.dev/mcp
Works with Claude Code, Claude Desktop, Cursor, and any MCP client.
Extensions fail silently: content scripts that never inject, panels that never open, permissions that return undefined with no error. These tools give the agent eyes on the live browser, so it debugs from evidence instead of guessing.
Scaffold from the 50+ templates behind templates.extension.dev, or add a popup, sidebar, or content script to an existing project
Run the dev server with HMR in Chrome, Firefox, Edge and every browser below, plus Safari on macOS (no HMR yet)
See the live DOM, logs from every extension context, chrome.storage, and the loaded-extension list
Act: evaluate code in any context, trigger the action button and commands, reload the extension
Test: state expectations about the running extension and get one verdict each
Ship: validate the manifest cross-browser and build for production. On the platform lane: share a preview link, promote a build, and submit to the stores
Built on Extension.js, the open source framework extension.dev sponsors.
Watch it work
Browsers
extension_dev opens the extension in the browser you name.
Google Chrome
Chromium
Microsoft Edge
Brave
Opera
Mozilla Firefox
Apple Safari
The Chromium family and Firefox get HMR, control, eval, inspect and assert (Firefox over its debugger protocol and the agent bridge, no CDP). Safari gets dev and build on macOS, no HMR and no inspect; the full list of what works there is under Safari. Plus Vivaldi, Yandex, Waterfox, Zen and Floorp, and any Chromium or Gecko binary by path.
Clients
Claude Code
Claude Desktop
Cursor
VS Code
Codex
Setup
Claude Code
bash
claude mcp add extension-dev -- npx @extension.dev/mcp --features=local,platform
Or install it as a plugin, the MCP server plus the /extension, /extension-add, /extension-debug, and /extension-publish commands in one step:
By default the server exposes the 23 of its 34 tools that work on this machine (the 11 platform tools are off). --features=local,platform adds the platform group. Env: EXTENSION_DEV_FEATURES.
--no-ship refuses every call that puts something in front of other people (publish, promote, a real submit, a shared preview, a revoke). Env: EXTENSION_DEV_NO_SHIP=1.
--project <workspace>/<project> pins the server to one project. Env: EXTENSION_DEV_PROJECT.
A refused call answers E_TOOL_DISABLED with the flag to change. Human approval for store submissions and stable promotions, the MCP annotations every tool carries, and the <untrusted-data-ID> fence around page-written text are described under Server flags.
Telemetry
extension_create sends one draft_seeded event to PostHog at us.i.posthog.com after a successful scaffold (template slug, source and commit, a random per-process session id, never a path or a name), and the platform tools send a per-install id header with their calls. EXTENSION_DEV_NO_TELEMETRY=1 or DO_NOT_TRACK=1 stops both. The full payload is listed under Telemetry.
Pair with the skill
This server gives agents hands; @extension.dev/skill gives them judgment: the cross-browser rules, silent-failure gotchas, debugging playbooks, and store checklist, in the open Agent Skills format. The package also ships Claude Code rules and the four slash commands under claude/.
Browse 50+ templates (list) and read one's source (source)
build
extension_docs_search
Search the Extension.js and extension.dev docs by keyword
build
extension_add_feature
Plan an options page, popup, side panel, content script, devtools panel or new tab page for an existing project
build
extension_build
Build for production
run
extension_dev
Dev server with HMR
run
extension_start
Build + launch the production build (build: false launches the existing dist; outputPath launches any prebuilt unpacked directory)
run
extension_wait
Poll the dev-server ready contract
run
extension_stop
Stop a dev/start/preview session (server + browser)
see
extension_manifest_validate
Cross-browser manifest validation
see
extension_analyze
Static analysis of the built extension on disk
see
extension_inspect
Deep live inspection of a running extension (closed shadow roots, probes)
see
extension_dom_snapshot
Shallow DOM snapshot of a chosen tab or extension surface over the agent bridge
see
extension_list_extensions
List loaded extensions (Chromium and Firefox)
see
extension_logs
Stream logs from every context
see
extension_doctor
Diagnose the dev session leg by leg (ready contract, ports, token, executor, browser)
see
extension_theme_verify
Verify a Chrome theme manifest against the colors Chrome actually paints
test
extension_assert
State expectations about a running extension and get one verdict each: pass, fail, or inconclusive
act
extension_eval
Evaluate in a context (needs allowEval: true on extension_dev)
act
extension_storage
Read/write chrome.storage
act
extension_reload
Reload extension or tab
act
extension_open
Open a surface (popup, options, sidebar, devtools panel, override pages) / trigger action, command
browsers
extension_browsers
Detect, list, install, and uninstall browsers
On with --features=local,platform, the 11 that reach the extension.dev platform (private alpha):
Tier
Tool
Description
platform
extension_auth
Device login at extension.dev for one project or a list of them, plus login status and logout
platform
extension_workspace_create
Create an extension.dev workspace, headless, via device approval; the approver becomes its owner
platform
extension_project_create
Create the extension.dev project for a built extension, or several under one approval, headless, via device approval
platform
extension_preview_web
Render a build in the web emulator, and share it as a link
platform
extension_shares
List every link you have shared, share a platform build as a link, and revoke one permanently
platform
extension_publish
Mint a shareable link for a build extension.dev already holds (nothing is uploaded)
platform
extension_release_promote
Promote a build to a release channel, headless
platform
extension_submit
Submit for store review: Chrome, Firefox, Edge and Safari, through extension.dev
platform
extension_release_status
Read release channels, release history, recent builds, and store configuration, submission and review state
platform
extension_builds
Read the platform's builds (recent builds, one build's artifacts and integrity, its CI logs), start a rebuild, change build settings with an owner's approval, and add a release channel
platform
extension_workspace
Read a workspace with any of its project logins: plan and limits, projects and last builds, usage, and a project's settings
A dev session carries the control channel that extension_storage, extension_reload, extension_open and extension_dom_snapshot ride: it is local, same machine, same user, and on unless extension_dev is called with allowControl: false. extension_eval is the one gate that stays off until allowEval: true is passed on extension_dev (it implies control). A session does not change its gates on a second call: call extension_dev again with what you need plus replace: true, which stops the first session.
Asserting instead of guessing
Every other tool hands back a reading. extension_assert states the expectation and returns the verdict.
Each check comes back pass, fail or inconclusive, and the run passes only when every check passed. inconclusive means this platform cannot cover the question today, and the check carries settledBy naming the evidence that would answer it: a content script passes only on a line it wrote itself, "no console errors" over a session that never built is inconclusive, and a read the session refuses (chrome.storage on a session started with allowControl: false) is inconclusive rather than a failure.
Safari
A Safari dev session runs on the same bridge as every other engine: on Extension.js 4.1.21 or newer, extension_dev with browser: "safari" (macOS with Xcode) builds the app, opens it, reloads it on every save and streams its logs. Safari's MV3 background CSP blocks eval, there is no CDP or RDP path for extension_inspect, and opening a tab needs a safaridriver session; the limits are listed under Safari.
Platform (private alpha)
The eleven platform tools connect agents to extension.dev. They stay off until the server is started with --features=local,platform, and sharing, publishing, promoting and submitting need a login:
You approve a code at extension.dev/device; no GitHub token reaches your machine, and the project-scoped token is stored locally, never returned to the agent, and lives at most 7 days. extension_preview_web with share: true uploads the build it just made and returns a link that renders those bytes in the web emulator, with its expiresAt and a revokeUrl. extension_publish returns the shareable URL of a build extension.dev already holds; extension_submit sends a built extension into store review through extension.dev, which holds your store credentials, and defaults to a dry run.