MCP server
@extension.dev/mcp gives a coding agent hands on a real browser and on the platform: 35 tools that scaffold, run, inspect, test and build an extension on your machine, and ship it through extension.dev. Reach for it when the agent should debug from evidence, instead of fixing a content script that never injected without noticing it never injected.
Quick start
claude mcp add extension-dev npx @extension.dev/mcpThen ask the agent to run your extension: it starts a dev session and a browser opens with the extension loaded. The same server works with Claude Desktop, Cursor, VS Code, Codex and any MCP client, and every client's block is on Install in your client.
How it works
The server does not reimplement Extension.js. It wraps the CLI and the local agent bridge. Tools that run a build or launch a browser shell out to the extension command, and so do the act verbs (eval, storage, reload, open), doctor, dom_snapshot and assert. The rest run in process and read the session's ready.json contract and the bridge's local channel as any other client would. The agent and the CLI always behave the same way, and the agent never holds anything the CLI does not.
Two tool groups
Without --features the server starts with the local group alone, the 24 tools that work on this machine. The 11 platform tools (account, workspace, builds, share, release and store) come on with --features=local,platform or EXTENSION_DEV_FEATURES=local,platform:
claude mcp add extension-dev -- npx @extension.dev/mcp --features=local,platformOr install it as a plugin, which adds the server plus the /extension, /extension-add, /extension-debug and /extension-publish commands. The plugin starts the server with the default local group:
/plugin marketplace add extensiondev/mcp
/plugin install extension-mcp@extensiondev-mcpThe server is listed in the MCP registry as io.github.extensiondev/mcp. The same shape works in any client configured by hand:
{
"mcpServers": {
"extension-dev": {
"command": "npx",
"args": ["@extension.dev/mcp", "--features=local,platform"]
}
}
}Session gates
extension_dev is the entry point, and the session it starts decides what the act tools may do.
extension_storage,extension_reload,extension_openandextension_dom_snapshotride the local control channel, which a dev session carries by default. Start it withallowControl: falsefor a read-only session (logs, inspect, wait, doctor).extension_evalis the one gate that stays off. It needs a session started withallowEval: true, which writes a session token file with0600permissions and implies control.
A session does not grow a gate on a second call: that call is refused so the session does not fork. Call extension_dev again with the flag you need plus replace: true, which stops the first session.
Reading is always free. Running code inside the extension is opt-in per session. The control verbs act on the extension this machine already runs, which is why they are on unless you turn them off.
Engine pinning for scaffolds
A project scaffolded by extension_create declares its Extension.js version in its own package.json. That project-local pin wins over the server's environment, so later sessions build with the version the scaffold declared.
Pair with the skill
The server pairs with @extension.dev/skill, which teaches the agent when to reach for each tool. The server without the skill gives an agent hands with no instructions.
Reference
The server registers 35 tools, one page each, generated from the schemas the server registers so the pages cannot drift from the code. The 24 local tools need no account. The 11 platform tools come on with --features=local,platform and are described on Platform tools. Every page carries the inputs, whether the tool only reads, the gate it needs, and a prompt that reaches for it.
Create and build
| Tool | What it does | |
|---|---|---|
extension_add_feature | Plan the surface before adding an options page, a popup, a side panel, a content script, a devtools panel, a new tab page or a background script to an existing extension. | reads |
extension_build | Build a browser extension for production. | acts |
extension_create | Create a browser extension project from a template in the extension.dev catalog; call extension_templates first to see what is available. | acts |
extension_docs_search | Find the docs page to cite before answering any question about a WebExtension API, a manifest key, a permission, or a difference between Chrome, Firefox, Edge and Safari. | reads |
extension_templates | Browse the extension.dev template catalog. | reads |
Run
| Tool | What it does | |
|---|---|---|
extension_dev | Run the extension while you edit it: dev build, hot module replacement, and a browser with the extension loaded. | acts |
extension_start | Run the PRODUCTION build in a browser: build the project, serve it, and launch. | acts |
extension_stop | Stop a session that extension_dev or extension_start is running: terminate the server and the browser it launched, and remove the live-preview carrier if extension_dev placed one. | acts |
extension_wait | Wait for a running dev or start session to be ready, or for a rebuild after a source edit (for: "rebuild"). | reads |
See
| Tool | What it does | |
|---|---|---|
extension_analyze | Analyze a BUILT extension on disk: file sizes, declared entry points, permissions, bundle composition, store-readiness checks, and manifestByBrowser, the emitted manifest of eve... | reads |
extension_doctor | Diagnose a dev session end to end: ready contract, dev-server process, control-port agreement, control channel, eval token, executor, browser liveness. | reads |
extension_dom_snapshot | Take a shallow structured DOM snapshot of one chosen surface: element counts, extension roots, open shadow roots, optional byte-capped HTML, and optional recent console lines. | reads |
extension_inspect | Inspect a running extension deeply over the browser's debugger protocol: full HTML (open shadow roots of the extension-root hosts inlined; other shadow roots are not crossed by... | acts |
extension_list_extensions | List the extensions in the running dev browser: id, name, version, and, on Chromium, live contexts. | reads |
extension_logs | Read or stream logs from every context of a running dev session (service worker, content scripts, popup, options, sidebar, devtools, pages) in one ordered timeline. | reads |
extension_manifest_validate | Validate a manifest.json across browsers. | reads |
extension_screenshot | Take a screenshot of one open extension surface (popup, options, sidebar, newtab, history, bookmarks) or web page in a live extension_dev or extension_start session and save it... | acts |
extension_theme_verify | Verify a Chrome theme manifest before it ships. | reads |
Test
| Tool | What it does | |
|---|---|---|
extension_assert | Run a test stage against a live dev session: state expectations and read one verdict for each, instead of reading a blob and hand-rolling the judgement. | acts |
Act
| Tool | What it does | |
|---|---|---|
extension_eval | Evaluate an expression in a running extension context: the background, an extension surface (popup, options, sidebar, devtools, newtab, history, bookmarks), a content script or... | acts |
extension_open | Open an extension surface (popup, options, sidebar, the newtab, history or bookmarks override page, or the extension's DevTools panel), navigate a tab to a url, or replay an eve... | acts |
extension_reload | Reload a running extension's background context, or a tab. | acts |
extension_storage | Read or write chrome.storage in a running extension. | acts |
Browsers
| Tool | What it does | |
|---|---|---|
extension_browsers | Find, install and remove the browsers Extension.js tooling can launch. | acts |
Platform
| Tool | What it does | |
|---|---|---|
extension_auth | Sign this machine in to extension.dev, report that login, or clear it: action status (the default), login and logout. | acts |
extension_builds | Read, rebuild and configure the platform's builds of the logged-in project on extension.dev: action list (the default), get, logs, recheck, rebuild, configure and create-channel. | acts |
extension_preview_web | Preview a build in the web emulator and share it as a quick link anyone can open, with no install, sign-in or dev server. | acts |
extension_project_create | Create an extension.dev project for an extension that does not have one yet, without opening the console: right after extension_create and extension_build, once the source is pu... | acts |
extension_publish | Publish a build of the logged-in project on extension.dev and answer the link to send testers, which opens a page with a download and a run command for each browser. | acts |
extension_release_promote | Promote a built extension to a release channel (stable, preview, beta) on extension.dev, headless: action promote (the default) points channel at buildId, cut opens a release pu... | acts |
extension_release_status | Read where a project stands on extension.dev from the public registry (registry.extension.land): its release channels with each channel's audience and recent builds (include:'re... | reads |
extension_shares | List, create and revoke the emulator preview links that give a tester one build and its zip: the uploads this login has shared, the same links extension_preview_web share:true h... | acts |
extension_submit | Submit a built extension to a store's review through extension.dev, which holds the store credentials and runs the upload on the platform (Chrome Web Store, Firefox AMO, Edge Ad... | acts |
extension_workspace | Read the extension.dev workspace a stored login belongs to: its plan and limits, its projects, and its usage. | reads |
extension_workspace_create | Create an extension.dev workspace that does not exist yet, without opening the console. | acts |
The flags, the approvals that wait for a person and the one telemetry event are on Server flags and telemetry. What works against Safari is on Run on Safari.
When it fails
- A platform tool returns an auth error: the stored device login lives at most 7 days. Log in again with
extension_auth, or setEXTENSION_DEV_TOKEN. - The device page says the project does not exist: login mints a code for any name, and the check happens at approval. Create the project at extension.dev/new, then log in again.
extension_evalanswerseval-disabled: the session was started withoutallowEval: true, and no route of the tool runs without that token. On a Chromium MV3 session the context defaults topage, the active tab. Passcontext: "background"to reach the service worker over the debug port.- An act tool refuses: eval and control are session opt-in. Call
extension_devagain with the gate you need plusreplace: true, then retry. extension_list_extensionsmisses an extension: a dormant MV3 service worker with no open page is absent until it wakes.
Next
- Install in your client, Server flags and telemetry, Platform tools, Run on Safari
- Pair with Chrome DevTools MCP says which server to reach for
- Agent bridge is the capability behind the local tools
- Agent logs and Inspect and act in depth
- Publish a build links a project's build page
- Access tokens