Skip to main content
Glama
extensiondev

@extension.dev/mcp

by extensiondev

@extension.dev/mcp Version Downloads Discord

Give your AI agent hands for browser extension development. 35 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.

claude mcp add extension-dev npx @extension.dev/mcp

Works with Claude Code, Claude Desktop, Cursor, and any MCP client.

extension.dev · Docs · Templates · Discord

Why an MCP server for extensions

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.

Related MCP server: @nimbus21.ai/chrome-devtools-mcp

Watch it work

Asked to run the extension, the agent starts the dev session, Chrome opens with it loaded, and the agent reports the session, from a real Claude Code session

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

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:

/plugin marketplace add extensiondev/mcp
/plugin install extension-mcp@extensiondev-mcp

Cursor

Install MCP Server

Or paste the .mcp.json block below into .cursor/mcp.json.

VS Code

code --add-mcp '{"name":"extension-dev","command":"npx","args":["@extension.dev/mcp","--features=local,platform"]}'

Or paste it into .vscode/mcp.json under servers, with "type": "stdio" on the entry.

Codex

codex mcp add extension-dev -- npx @extension.dev/mcp --features=local,platform

Or write it into ~/.codex/config.toml as a [mcp_servers.extension-dev] table with the same command and args.

Other clients (Claude Desktop and .mcp.json)

.mcp.json:

{
  "mcpServers": {
    "extension-dev": {
      "command": "npx",
      "args": [
        "@extension.dev/mcp",
        "--features=local,platform"
      ]
    }
  }
}

Flags

  • By default the server exposes the 24 of its 35 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/.

npm i -D @extension.dev/skill
mkdir -p .claude/skills && cp -R node_modules/@extension.dev/skill/skills/extension-dev .claude/skills/

Tools

On by default, the 24 that work on this machine:

Tier

Tool

Description

build

extension_create

Scaffold from a template

build

extension_templates

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_screenshot

Screenshot of an open extension surface or page, saved as a .png over the session's debug port

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.

Asked whether the extension works, the agent runs it, states expectations and reads one verdict each, from a real Claude Code session

{
  "projectPath": "/path/to/extension",
  "expect": [
    { "assert": "background-worker-booted" },
    { "assert": "surface-rendered", "surface": "popup", "selector": "[data-testid=root]" },
    { "assert": "storage-key-present", "key": "settings", "area": "local" },
    { "assert": "console-errors-empty", "context": ["background", "popup"] },
    { "assert": "content-script-injected", "url": "https://shop.example/cart" }
  ]
}

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:

npx @extension.dev/mcp login --project <workspace>/<project>

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.

Chrome Web Store

Firefox Add-ons

Edge Add-ons

App Store

The details, the approval flow and the batch login for several projects are under Share a build in progress, Publish is not submit and Login.

Community

License

Apache-2.0 (c) 2026 Cezar Augusto and the extension.dev collaborators. See LICENSE.

Available Tools

32 tools
extension_add_featureA
Read-onlyIdempotent

Plan a new feature surface for an existing extension. This returns step-by-step instructions, the manifest additions to make, and reference templates from the extension.dev catalog. It modifies no files: apply the returned plan yourself.

ParametersJSON Schema
NameRequiredDescriptionDefault
featureYesFeature surface to add
frameworkNoreact
projectPathYesExtension project root

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description reinforces and clarifies the annotations: 'It modifies no files: apply the returned plan yourself' explains why readOnlyHint/destructiveHint=false hold for a tool whose name contains 'add'. It also enumerates what gets returned (instructions, manifest additions, templates), which goes beyond the annotation set.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with purpose and followed by return contents and the no-write constraint. No filler or restatement of the tool name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the burden of describing return values, and it does so (step-by-step instructions, manifest additions, reference templates). Safety is covered by annotations and the explicit no-write statement. Only per-parameter clarifications are missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67% and the description adds no parameter-level detail. The 'feature surface' wording loosely echoes the feature enum but supplies no extra meaning for projectPath or framework beyond what the schema already encodes.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Plan a new feature surface for an existing extension.' That is clearly distinct from extension_build/extension_create in intent, though it never names a sibling explicitly. An agent can tell what the tool produces (a plan, not a build).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'for an existing extension' implies usage scope versus creation tools, and 'apply the returned plan yourself' tells the agent what to do next. However, there is no explicit when-not or named alternative (e.g., extension_templates, extension_build) to route between.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_analyzeA
Read-onlyIdempotent

Analyze a BUILT extension on disk: file sizes, declared entry points, permissions, bundle composition, and store-readiness checks. This is static only: it reads dist/ from the filesystem and never touches a browser, so build first with extension_build. Use extension_inspect for a running extension's live DOM and console.

ParametersJSON Schema
NameRequiredDescriptionDefault
formatNosummary
browserNoBrowser build to analyzechrome
projectPathYesExtension project root

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive/closed-world, but the description adds genuinely new behavioral context: it is static only, reads dist/<browser> from the filesystem, never touches a browser, and therefore must be preceded by a build. That workflow prerequisite and scope boundary go well beyond the structured annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with what is analyzed and what it outputs, then the static-only constraint, then the sibling alternative. No filler and each sentence carries distinct information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description compensates by listing the concrete outputs (sizes, entry points, permissions, bundle composition, store-readiness checks). Combined with the readOnly annotations and the build-first prerequisite, an agent has everything needed to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67% and the description adds little: it references 'dist/<browser>' which loosely maps to the browser parameter, but the format enum values (summary/tree/json) carry no description in either schema or prose. With the schema doing most of the work and coverage above the midpoint, a baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (analyze) against a precise resource (a BUILT extension on disk) and enumerates exactly what is reported: file sizes, entry points, permissions, bundle composition, and store-readiness. It also explicitly differentiates from the sibling extension_inspect, so an agent can pick between them without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit prerequisite ('build first with extension_build') and an explicit alternative plus its selection condition ('Use extension_inspect for a running extension's live DOM and console'). Both the when-to-use and the when-not-to-use path are spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_assertA
Idempotent

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. Every expectation comes back pass, fail or inconclusive, where inconclusive means this platform cannot cover the question today and the verdict says what would settle it. An inconclusive check is never a pass. Start the session with extension_dev; use extension_inspect or extension_logs when you want the raw reading instead of a verdict.

ParametersJSON Schema
NameRequiredDescriptionDefault
expectYesOne object per expectation, each { assert: <check id>, ...args }. background-worker-booted: no args. surface-rendered: surface (popup, options, sidebar, newtab, history, bookmarks), optional selector and minNodes. content-script-injected: url. storage-key-present: key, optional area (default local), equals, context. console-errors-empty: optional context (array), since (seq cursor), ignore (substrings).
browserNoSession browser; defaults to this project's live session
timeoutNoCommand timeout in ms. When omitted, the default depends on the route: 30000 through the dev session's control channel, 10000 over the Firefox debugger protocol, and 15000 per command over the Chromium debug port.
projectPathYesExtension project root (needs a live dev session)

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare the safety profile (non-readonly, idempotent, non-destructive), so the bar is lower, and the description adds genuinely new behavioral context: every check returns pass/fail/inconclusive, and inconclusive is never a pass. It does not disclose failure or timeout behavior of the overall run, which keeps it short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, each doing work: what it does, what the verdicts mean, and how to start/sidestep. The purpose is front-loaded and there is no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the return semantics and does so adequately by defining the three verdict states and the inconclusive caveat. Prerequisite session state is also covered, so an agent can call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema itself enumerates the check ids, their args, browser defaults, and the route-dependent timeout values. The prose adds no parameter meaning beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Run a test stage against a live dev session') and clarifies the output shape ('one verdict for each' expectation). It explicitly separates itself from extension_inspect and extension_logs, which return raw readings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit prerequisites ('Start the session with extension_dev') and names the alternatives to use when a raw reading is wanted rather than a verdict. It also frames the when-to-use case: assertions instead of hand-rolling judgement over a blob.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_authA
Destructive

Sign this machine in to extension.dev, report that login, or clear it. Pass action:'status' (the default) to name the workspace and project the stored token is scoped to and when it expires, never the token itself; that identity comes from the stored token alone, and does not change with the current working directory or whichever project folder you are in. Status also asks the platform's whoami endpoint whether that credential actually resolves there: the answer rides value.server.verdict as confirmed, refused or unavailable (when the server could not be reached), with status logged-in for the first and last and refused-by-server for the second, so a local file claiming a login the server refused is never reported as logged in. Pass action:'login' for a two-phase flow: call with project to get a code plus a URL the user authorizes at extension.dev/device, then call again with the returned deviceCode. GitHub federation happens server-side, so no GitHub token lands on this machine. Minted tokens live at most 7 days, server-enforced, so CI must re-mint before expiry on the console's project settings, Access tokens page. Pass action:'logout' to delete the local credentials only (with project, just that project's login); the token stays valid server-side until it is revoked at the URL the response returns. Several logins live side by side on one machine, one per workspace/project, and status lists them all under logins. To sign in to several existing projects of one workspace at once, pass projects instead of project: one approval, one stored token per project.

ParametersJSON Schema
NameRequiredDescriptionDefault
apiNoPlatform base URL (default EXTENSION_DEV_API_URL, else https://www.extension.dev)
actionNostatus
projectNologin: target project as '<workspace>/<project>'; the token is scoped to it. The slug pair is the console address bar: an existing project's page is console.extension.dev/<workspace>/<project>. Create one at extension.dev/new if none exists yet. Logins to several projects are all kept, the latest is the default; token-scoped tools take `project` to pick another. logout: remove only this project's login (omitted, every stored login goes).
projectsNologin: sign in to several existing projects of one workspace with one approval, instead of one approval each. 1 to 20 names as '<workspace>/<project>', all in the same workspace, each by its exact slug (lowercase letters and digits joined by single dashes, at most 48 characters), none twice. Pass it instead of `project`, never beside it. The approval page lists every name; one missing project refuses the whole list and mints nothing. Resume with the returned `deviceCode` and the same list. Every token is stored as that project's own login and all expire within 7 days, so the same call renews them together.
deviceCodeNologin: resume token from the prior call's `deviceCode`; omit on the first call.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only give a coarse destructiveHint=true/openWorldHint=true; the description supplies the real behavioral detail: status never returns the token, logout deletes credentials locally while the server token stays valid until revoked, tokens are capped at 7 days server-side, GitHub federation happens server-side so no GitHub token lands locally, and server verdict can downgrade a local login to refused-by-server.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose and organized in action order (status, login, logout, multi-login, projects), and nearly every clause carries load-bearing detail. It is, however, a single dense ~350-word paragraph with some redundant restatement, which costs it the top mark.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description compensates fully by naming returned fields and their semantics (value.server.verdict with confirmed/refused/unavailable, status logged-in/refused-by-server, `logins`). Everything an agent needs to call and interpret this tool is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 80% and its per-parameter descriptions are detailed, so this is largely the baseline-3 territory; the description nonetheless adds genuine semantics the schema lacks, notably the two-phase login/deviceCode resume flow and the `projects`-instead-of-`project` exclusivity rule.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Starts with a specific verb+resource ('Sign this machine in to extension.dev, report that login, or clear it') and then enumerates the three action modes with distinct behaviors. An agent can distinguish it from every sibling (auth vs build/preview/publish) without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use each action (status as default read, login two-phase with project/deviceCode, logout local-only) and names alternatives: `projects` versus `project` with the constraint 'Pass it instead of `project`, never beside it.' It also routes to the console URL for re-minting CI tokens.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_browsersA
Destructive

Find, install and remove the browsers Extension.js tooling can launch. Pass action:'detect' (the default) to scan both system-installed and managed browsers, and report each one's binary path, version, engine and debugger support. Pass action:'list' for the managed cache this tool downloads into, with sizes on disk. Pass action:'install' to download a managed binary: several hundred MB in one blocking call, so allow a generous client timeout. Pass action:'uninstall' to remove managed binaries; it never touches a system install.

ParametersJSON Schema
NameRequiredDescriptionDefault
allNouninstall: remove every managed binary.
actionNodetect
browserNoinstall/uninstall: which managed binary. Required for install.
browsersNodetect: limit the scan to these. Omit to check all.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (destructive/openWorld/idempotent=false), the description disambiguates which action is destructive and its blast radius ('uninstall... never touches a system install'), and warns that install is a several-hundred-MB blocking call requiring a generous client timeout. That is exactly the operational context the structured hints cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four dense sentences, front-loaded with the overall purpose and default action, then one sentence per action. No filler; the timeout warning and uninstall-safety note are placed where they are actionable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description still tells the agent what detect and list return (binary path, version, engine, debugger support; cache sizes) and what install/uninstall do to disk. Combined with the annotations and a four-parameter schema, nothing essential for a correct call is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema documents 75% of parameters, but the 'action' enum itself carries no per-value description in the schema, so the description's explanation of each action and the stated default meaningfully extends it. It also confirms browser is required for install and that browsers limits the detect scan (omit to check all), though it says nothing about the 'all' uninstall flag beyond what schema already covers.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a concrete verb set and resource ('Find, install and remove the browsers Extension.js tooling can launch') and then breaks the tool into four named actions, so the agent knows exactly what it operates on. It never references a sibling, though, so mapping this against launch-oriented siblings like extension_start is left to inference.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Each enum value is paired with the condition that selects it and its return shape: detect (default) scans system + managed and reports path/version/engine/debugger support; list shows cached downloads with sizes; install fetches a managed binary; uninstall removes managed binaries. Requirements (browser is required for install) and exclusions ('never touches a system install') are both stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_buildA
Idempotent

Build a browser extension for production. The output lands in dist//. Pass zip:true to also package a .zip for store submission. With browser:'safari' the build converts the extension into a macOS app through Xcode, and bundleId sets the identifier it ships under. The build refuses a manifest with build-blocking errors unless you pass skipValidation:true, because such a manifest yields a broken bundle the bundler itself never flags.

ParametersJSON Schema
NameRequiredDescriptionDefault
zipNoCreate a .zip file for store distribution
modeNoBundler mode override (also sets NODE_ENV)production
silentNoSuppress build output
appNameNoSafari targets only: name of the generated macOS app, which also names the Xcode scheme and the .app on disk. Defaults to the manifest name.
browserNochrome
bundleIdNoSafari targets only: a reverse-DNS bundle identifier you own, such as com.acme.readinglist. Without one the app is packaged under a generated dev.extensionjs.* identifier derived from the app name, which two projects with the same name share, and the first team to register it takes it.
polyfillNoApply cross-browser polyfill
macOsOnlyNoSafari targets only: generate a macOS-only Xcode project. Pass false for a universal project that also targets iOS and iPadOS, which is what you want if the extension ships on iPhone or iPad.
zipSourceNoInclude source code zip (required by some stores)
projectPathYesExtension project root
zipFilenameNoCustom .zip file name (defaults to name and version)
skipValidationNoBuild even when extension_manifest_validate reports build-blocking errors. The build normally refuses: the engine itself stops only on missing scripts, icons, DNR rule files, default_locale and manifest_version, and ships a bundle over the rest.
forceRegenerateNoSafari targets only: regenerate the Xcode project even when the engine considers it up to date. Use it when an earlier packaging run left the project broken.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark this as a non-readonly but non-destructive, idempotent, closed-world operation; the description adds real behavioral context beyond that: where output lands, that validation failures block the build and why, that skipValidation can yield a broken bundle, and that Safari builds convert to a macOS app.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, front-loaded with the core action and output location, and each sentence carries distinct information rather than padding. The bundleId sentence is dense but earns its length given the collision warning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 13-param, no-output-schema tool, the description covers the highest-stakes behaviors (validation gating, Safari/Xcode path, store packaging) and leaves the low-stakes flags to the thorough schema. Adequate, though a note on return values or build-output differences would round it out.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 92%, so the baseline is 3, but the prose adds meaning beyond the schema: it explains the collision risk of omitting bundleId (shared generated dev.extensionjs.* identifier) and the exact consequence of skipValidation. It does not cover the remaining params (mode, silent, polyfill, forceRegenerate) in prose, so it isn't a full 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource+"for production" scope, immediately distinguishing it from sibling build-adjacent tools like extension_dev. An agent knows this produces a production bundle rather than running a dev server.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear conditional guidance for the flags that matter (zip:true for store packaging, skipValidation:true to bypass the validation refusal, browser:'safari' for Xcode conversion). It does not explicitly name a sibling alternative or state when NOT to build, so it stops short of the 5 bar.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_createA

Create a browser extension project from a template in the extension.dev catalog. Call extension_templates first to see what is available. The scaffolder may initialize a git repository in the new project (with a first commit), and it also writes store metadata and a .gitignore of its own. Read the result's defaultsApplied block for the decisions this tool can read back: parent directory, template, package manager, target browser and whether a git repository was initialized by this call.

ParametersJSON Schema
NameRequiredDescriptionDefault
installNoInstall dependencies after creation
templateNoTemplate slug from the extension.dev catalog (e.g. 'react', 'ai-claude', 'content-vue'). extension_templates discovers them.typescript
parentDirNoDirectory to create the project inside. Defaults to the MCP server process cwd, NOT the caller's cwd, so pass it whenever you care where the project lands. Aliases: parent, into.
projectNameYesName of the extension project (used as directory name). Alias: name.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare non-read-only, non-idempotent, open-world and non-destructive behavior, yet the description adds real side-effect detail beyond them: git repository initialization with a first commit, store metadata and a self-authored .gitignore. This is exactly the kind of disclosure that annotations cannot convey. It still omits failure/overwrite behavior, so not a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then ordered instructions, then behavioral caveats, in four dense but non-redundant sentences. The final sentence is long but carries the readback contract, so every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a scaffolding mutation with no output schema, the description covers prerequisite, side effects, and how to read back applied defaults. It is largely complete; the notable gap is behavior on an existing target directory or failure, which the non-idempotent annotation hints at but the description never explains.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so baseline is 3; the schema already documents each parameter including parentDir's cwd caveat and aliases. The description's defaultsApplied note concerns output readback rather than parameter meaning, so it does not add much beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Create a browser extension project from a template in the extension.dev catalog.' An agent immediately knows this scaffolds a project. However, the description never distinguishes itself from the sibling extension_project_create, which is an apparent overlap it should address.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly gives a prerequisite and ordering: 'Call extension_templates first to see what is available.' That routes the agent correctly before invoking. It stops short of stating when-not to use it (e.g. versus extension_project_create) or what happens if the target directory already exists.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_devA

Run the extension while you edit it: dev build, hot module replacement, and a browser with the extension loaded. Reach for this first when the ask is "run my extension". ONLY this tool unlocks the control channel that extension_storage, extension_reload, extension_open and extension_dom_snapshot need (allowControl:true) and the eval channel that extension_eval needs (allowEval:true, which implies allowControl, so you never need to pass both). Use extension_start instead to run the production build in a browser. The result carries the process info that extension_wait and extension_inspect need.

ParametersJSON Schema
NameRequiredDescriptionDefault
hostNoBind host, default 127.0.0.1. Use 0.0.0.0 in Docker or devcontainers.
portNoDev server port (0 for auto-assign)
browserNochrome
carrierNoLoad the bundled Live Preview carrier beside your extension (Chromium only) so allowlisted pages (preview.extension.dev, localhost) can pair with the session and stream its real-lane chrome.* trace. Written into the auto-loaded ./extensions folder, gitignored, and removed on extension_stop or extension_build: never part of a release.
profileNoProfile path, or "false" to reuse the real user profile. Omit for a throwaway one.
replaceNoStop the live session for this projectPath first, reported as replacedSession. Without it a second call is refused rather than forking: two sessions fight over one profile and the newer browser dies on the lock.
polyfillNoApply cross-browser polyfill
allowEvalNoEnable extension_eval (runs code in a context; writes a 0600 session token). Implies allowControl, so you never need to pass both.
noBrowserNoStart the dev server without launching a browser
extensionsNoExtra extension paths or store URLs to load alongside the project
publicHostNoHost the browser dials for HMR and reload when it differs from the bind host
geckoBinaryNoCustom Gecko/Firefox binary to launch; `browser` still names the target family the engine builds for (gecko-based when none is given).
projectPathYesExtension project root
startingUrlNoURL the browser opens on launch
allowControlNoEnable the agent-bridge control channel that extension_storage/reload/open/dom_snapshot need
chromiumBinaryNoCustom Chromium-based binary to launch; `browser` still names the target family the engine builds for (chromium-based when none is given).

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover the safety profile (readOnlyHint=false, destructiveHint=false, idempotentHint=false), so the description's value is the extra behavioral context it adds: the exclusive unlock of the allowControl/allowEval channels, the implication chain (allowEval implies allowControl), the 0600 session token, and the fact that the result carries process info needed by extension_wait/extension_inspect. It does not restate annotation claims, and it adds real coupling semantics that structured fields do not convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the primary purpose, then the disambiguating alternative, then the dependency semantics. Each sentence carries distinct information with no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 16-parameter, non-idempotent start tool with no output schema, the description supplies the missing pieces: when to use vs alternatives, what channels it uniquely enables, and what the result feeds into. Enough for correct invocation without further documentation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 94%, so the schema does the heavy lifting and baseline would be 3. The description adds value by explaining the allowControl/allowEval relationship in terms of which sibling tools consume each flag, clarifying why an agent would set them rather than just what they do.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('run the extension while you edit it') and enumerates the core capabilities: dev build, HMR, browser with extension loaded. It explicitly distinguishes itself from the sibling extension_start (production build), so an agent can pick between the two without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit trigger ('Reach for this first when the ask is "run my extension"'), names the disambiguating alternative (extension_start for production), and states the downstream conditions this tool satisfies (it is the only tool that unlocks the control and eval channels required by extension_storage, extension_reload, extension_open, extension_dom_snapshot, and extension_eval). Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_doctorA
Read-onlyIdempotent

Diagnose a dev session end to end: ready contract, dev-server process, control-port agreement, control channel, eval token, executor, browser liveness. This returns one {check, status, detail, remediation?} per leg, in dependency order. Read a 'skip' as blocked, not as a pass: it names the check that blocked it. A session started without allowControl comes back ok:true with status 'read-only', not as an error: its control channel is off by choice. Run this first when any act tool (storage, reload, eval, open) errors unexpectedly. Call it with no projectPath for a pre-flight environment check (node, the Extension.js CLI, the template cache) before any project exists.

ParametersJSON Schema
NameRequiredDescriptionDefault
browserNoBrowser session to diagnose. Defaults to the active dev session's browser for this project.
projectPathNoPath to the extension project root. Omit for a pre-flight environment check with no project.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed-world), yet the description adds real behavioral context: the per-leg {check, status, detail, remediation?} return shape, dependency ordering, that 'skip' means blocked rather than pass, and that a no-allowControl session returns ok:true with status 'read-only' instead of erroring. This is substantive disclosure beyond structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the scope, then the return shape, then the two key behavioral caveats, then the usage triggers. Dense but every clause earns its place; only slight length pressure keeps it from a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, but the description specifies the return shape (one {check, status, detail, remediation?} per leg) and the non-error read-only outcome, so an agent knows both what it will get and how to interpret it. Complete for a zero-required-param diagnostic tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description's param-relevant statements (browser defaults to the active session, omit projectPath for pre-flight) largely restate what the schema already documents, adding little syntax or format detail beyond it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (diagnose) and resource (dev session) and enumerates the exact legs checked (ready contract, dev-server process, control-port agreement, control channel, eval token, executor, browser liveness). This clearly separates it from the sibling act tools like extension_eval, extension_reload, and extension_storage.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use: 'Run this first when any act tool (storage, reload, eval, open) errors unexpectedly.' Also gives a distinct invocation mode: 'Call it with no projectPath for a pre-flight environment check.' Both the trigger and the alternative usage path are named.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_dom_snapshotA
Read-onlyIdempotent

Take a shallow structured DOM snapshot of one chosen surface through the agent bridge (localhost only; the snapshot itself needs no CDP, but listTargets and tabUrl resolution ask the browser directly and need the session's debug port: CDP page targets on Chromium, RDP tab descriptors on Firefox): element counts, extension roots, open shadow roots, optional byte-capped HTML, and optional recent console lines. This is the SURFACE PICKER: the only tool that reads an open extension surface by name (context: popup, options, sidebar, devtools) or an override page, the only one that takes a numeric chrome.tabs id, and the only one that enumerates what is open (listTargets for CDP targetIds and RDP tab actors, listTabs for numeric tab ids). An ambiguous tabUrl returns the candidates instead of guessing. It does not pierce closed shadow roots, run selector probes, or navigate: use extension_inspect for those, and for a deep read of an already-open web page. Start the session with allowControl:true (extension_dev).

ParametersJSON Schema
NameRequiredDescriptionDefault
tabNoNumeric chrome.tabs id, only to disambiguate when several tabs match. With neither `tab` nor `url`, content/page target the active tab.
urlNocontent/page: pick the tab by url (match pattern, then substring). Preferred over `tab`.
tabUrlNoTarget the tab whose URL contains this substring (case-insensitive; titles checked only when no url matches). Resolved against the live browser first: exactly one match proceeds, zero or several return the candidates instead of a guess. Alternative to `url`.
browserNoSession browser; defaults to this project's live session
contextNocontent/page targets `url`, else the active tab; the rest must already be OPENcontent
includeNoWhat to include; html is byte-capped
timeoutNoCommand timeout in ms. When omitted, the default depends on the route: 30000 through the dev session's control channel, 10000 over the Firefox debugger protocol, and 15000 per command over the Chromium debug port.
listTabsNoEnumerate open tabs as {tabId,url,title} and return, ignoring the other args. Use when you need a numeric tab id.
maxBytesNo
listTargetsNoEnumerate live page targets and return, ignoring the other args. The discovery path for `tabUrl`. Chromium: {targetId,url,title,type}. Firefox: RDP tab descriptors {actor,url,title,type}. Neither id is a numeric chrome.tabs id; for those use listTabs.
projectPathYesExtension project root (needs a live dev session)
withConsoleNoAlso include recent console lines. A number is how many; true means 50.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive), so the bar is lower. The description adds genuinely useful behavior: localhost-only, the snapshot needs no CDP but listTargets and tabUrl resolution do need the debug port, and the ambiguity policy (candidates returned instead of guessing). It does not describe pagination or output shape, but adds substantial context beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose is front-loaded, but the description is a dense run-on with nested parentheticals and backtick-heavy clause chains that slow comprehension. Every sentence carries information, yet the structure is not cleanly parsable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 12-parameter read tool with no output schema, the description sketches the return payload (element counts, extension roots, open shadow roots, optional byte-capped HTML, console lines) and covers the discovery paths, prerequisites, and exclusions. Only minor gaps remain, such as return shape details for the enumeration modes.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 92%, so the schema does most of the work and baseline is 3. The description nevertheless adds meaning beyond the schema: html is byte-capped, listTabs/listTargets ignore the other args and return a specific shape, tabUrl resolution order (live browser, substring, titles fallback). That is more than restating field definitions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource ('Take a shallow structured DOM snapshot of one chosen surface') and immediately positions itself as the unique 'SURFACE PICKER' that reads open extension surfaces by name and is the only tool taking a numeric chrome.tabs id. It also names what it is unlike (extension_inspect), so an agent can differentiate it from all 30 siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use it (reading an open surface by context name, enumerating what is open via listTargets/listTabs) and when not to (it does not pierce closed shadow roots, run selector probes, or navigate — use extension_inspect for those). It also gives a prerequisite: start the session with allowControl:true.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_evalA
Destructive

Evaluate an expression in a running extension context. Start the session with allowEval:true (extension_dev), which writes a 0600 session token; without that token every route of this tool, the debug port included, answers eval-disabled. Context defaults to 'background', except on a Chromium MV3 session (the default template) where it defaults to 'page', the active tab; pass context:'background' to evaluate in the service worker, which on Chromium goes over the debug port. Debug-port evaluates run with a user gesture, so gesture-gated APIs (permissions.request, sidePanel.open) can succeed here and still fail when the extension's own code calls them. For content and page, pass url to pick the tab, or omit both url and tab for the active tab; a numeric tab only disambiguates. Extension surfaces (popup, options, sidebar, devtools) and override pages (newtab, history, bookmarks) need no tab id but must already be open: open one with extension_open first, because a closed one returns an explicit error. On a Chromium MV3 session those pages, and context:'page' with a chrome-extension:// url, evaluate over CDP, the inspector path the extension page CSP does not govern; elsewhere they evaluate over the in-bundle relay. On Firefox a document whose content security policy forbids eval (the extension's own pages, or a site's) is evaluated over the debugger protocol instead, which takes one expression; a page inside the extension that is no declared surface (pages/*) is reached the same way by context:'page' and its moz-extension:// url once a tab shows it. Call extension_dom_snapshot with listTabs:true to enumerate {tabId, url, title}.

ParametersJSON Schema
NameRequiredDescriptionDefault
tabNoNumeric chrome.tabs id, only to disambiguate when several tabs match.
urlNocontent/page: pick the tab by url (match pattern, then substring). Preferred over `tab`.
browserNoSession browser; defaults to this project's live session
contextNoWhere to evaluate. Default background, except Chromium MV3 sessions default to page (the active tab).
timeoutNoCommand timeout in ms. When omitted, the default depends on the route: 30000 through the dev session's control channel, 10000 over the Firefox debugger protocol, and 15000 per command over the Chromium debug port.
expressionYesJavaScript expression to evaluate in the target context
projectPathYesExtension project root (needs a live dev session)

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite annotations already declaring destructive/openWorld/non-idempotent, the description adds substantial context beyond them: the 0600 session-token gate, that debug-port evaluates run with a user gesture so gesture-gated APIs behave differently, the CDP vs in-bundle relay routing, and the Firefox debugger-protocol fallback for eval-forbidding CSPs. That is exactly the behavioral detail an agent needs before calling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose and the eval-disabled gate are strongly front-loaded, and most clauses carry genuine routing information. It does run long and dense, bundling many edge cases into a single block, so it is efficient but not maximally tight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter, multi-route tool with no output schema, it covers prerequisites, context resolution, timeouts, and surface/tab addressing thoroughly. It stops short of describing the returned result shape or error formats, but the operational guidance needed to invoke it correctly is nearly complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so each parameter is already documented, including the context default, timeout defaults, and url-vs-tab precedence. The description largely restates those defaults rather than adding syntax or format meaning beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence gives a precise verb+resource: 'Evaluate an expression in a running extension context.' It immediately names the prerequisite tool (extension_dev with allowEval:true) and cooperates with extension_open and extension_dom_snapshot, leaving no ambiguity about what this tool does versus its siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states explicit when/when-not conditions: start the session with allowEval:true, otherwise every route answers eval-disabled; use extension_open before targeting a surface; pass url or tab to disambiguate content/page; context:'page' for the active tab. Alternatives and prerequisites are spelled out rather than inferred.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_inspectA
Idempotent

Inspect a running extension deeply over the browser's debugger protocol: full HTML (open shadow roots of #extension-root and [data-extension-root] hosts inlined; other shadow roots are not crossed by html, dom_snapshot or probe), DOM structure, content-script injection, console messages, and CSS selector queries through probe. This is the ONLY tool that pierces closed shadow roots (deepDom), runs selector probes, and navigates a tab to url before reading it. It reads a web or override page and picks the first inspectable target, or the first whose url contains url; it cannot address an extension surface by name and takes no chrome.tabs id. Use extension_dom_snapshot to choose which tab or which open surface (popup, options, sidebar, devtools) to read, or to enumerate what is open. Use extension_analyze for a built extension's files and sizes on disk. Chromium rides the Chrome DevTools Protocol and needs the session's debug port, not allowControl. Firefox is fully paired: summary, meta, html, dom_snapshot, extension_roots and probes ride the agent bridge and need allowEval:true, console rides the RDP watcher replay on engine 4.0.15 and later, and deepDom needs an MV2 session with host permissions for the target url, because the Firefox MV3 background CSP blocks bridge evals. This requires an active dev or start session.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlNoURL to inspect; the tab is navigated there first
probeNoCSS selectors to query; returns counts and samples for each
browserNoSession browser; defaults to this project's live session
deepDomNoPierce CLOSED shadow roots (open roots of the extension-root hosts are already inlined in html; other open roots are not read). Chromium: CDP DOM pierce. Firefox: a content-script walk via tabs.executeScript (MV2 only, needs host permissions for the target url); the answer says whether that context could see closed roots at all.
includeNoWhat to include
maxBytesNoTruncate HTML output at this byte count (0 = unlimited)
projectPathYesExtension project root (needs a live dev session)

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With annotations covering the safety profile, the description still adds substantial behavioral context: it navigates the tab to `url` before reading, it cannot address an extension surface by name or accept a chrome.tabs id, and it lays out engine-specific requirements (bridge evals blocked by Firefox MV3 CSP, console replay needing engine 4.0.15+). This is exactly the auth/permission and side-effect disclosure the annotations don't carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose, exclusivity, and sibling routing are front-loaded in the first three sentences, and nearly every clause carries actionable information. It is dense and one unbroken paragraph, though, which makes the browser-matrix tail harder to parse than it needs to be.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter tool with no output schema and complex cross-browser execution paths, the description supplies the missing context an agent needs: session prerequisites, what each browser can and cannot do, which shadow roots the default reads cross, and how probe output is shaped. Nothing essential to invoking it correctly is omitted.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The prose largely restates what the schema already documents for `url`, `probe`, `deepDom`, and `include` (its deepDom browser notes closely mirror the schema text), adding little semantic detail beyond the structured fields.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource ('Inspect a running extension deeply over the browser's debugger protocol') and enumerates exactly what is read: full HTML, DOM structure, content-script injection, console messages, and CSS selector probes. It explicitly differentiates from siblings ('This is the ONLY tool that pierces closed shadow roots...') and names extension_dom_snapshot and extension_analyze as the alternatives for adjacent jobs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states when to use each alternative ('Use extension_dom_snapshot to choose which tab... Use extension_analyze for a built extension's files on disk') and the gating precondition ('requires an active dev or start session'). It further gives per-browser conditions (Chromium needs the session's debug port, not allowControl; Firefox needs allowEval:true; deepDom needs an MV2 session with host permissions).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_list_extensionsA
Read-onlyIdempotent

List the extensions in the running dev browser: id, name, version, and, on Chromium, live contexts. This session's own extension carries ownExtension:true, with name and version from the ready contract even when the browser exposes no identity. Chromium rides the Chrome DevTools Protocol, so an entry needs at least one live context, and a dormant MV3 service worker may be absent until it wakes. Firefox rides the RDP root actor (listAddons, engine 4.0.15 and later), so entries are installed add-ons regardless of contexts, are marked temporarilyInstalled where relevant, and carry no contexts. Other extensions' contexts are never attached to or evaluated in. This requires an active dev or start session.

ParametersJSON Schema
NameRequiredDescriptionDefault
browserNoSession browser; defaults to this project's live session
projectPathYesExtension project root (needs a live dev session)

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly/idempotent/non-destructive), yet the description adds substantial behavior: Chromium's requirement of at least one live context, dormant MV3 service workers being absent until woken, the Firefox RDP listAddons mechanism and engine-version floor, and the temporaryInstallation marker. It also assures the agent that other extensions' contexts are never attached to or evaluated in, which is real scope disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose and returned fields are front-loaded, and the browser-specific caveats follow in logical order with no filler sentences. It is dense and slightly run-on in places, but every sentence carries information an agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the burden of describing results and does so: returned fields, the ownExtension flag, the temporarilyInstalled marker, and per-browser context presence. The session prerequisite and cross-browser divergence are both covered, leaving no gap an agent needs before calling it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters (browser, projectPath) are already documented in structured form. The description reinforces the session requirement but adds no new syntax, format, or defaulting detail beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List the extensions in the running dev browser') and enumerates the returned fields (id, name, version, live contexts), which clearly separates it from siblings like extension_browsers or extension_inspect. The per-browser framing further pins down exactly what gets listed.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear precondition ('This requires an active dev or start session') and explains when entries appear differently on Chromium vs Firefox. It stops short of naming sibling alternatives or stating when not to use this tool, so it is strong context without explicit routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_logsA
Read-onlyIdempotent

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. This reads the same agent-bridge plane as the extension logs CLI: a one-shot returns the most recent matching lines from logs.ndjson, and follow:true connects to the live control channel, receives the broker's replay of its recent ring (up to 5,000 events, counted in value.replayed) and then the frames that arrive during followMs (value.live). This requires an active extension_dev session.

ParametersJSON Schema
NameRequiredDescriptionDefault
tabNoOnly events from this tab id.
urlNoOnly events whose url/hostname matches (glob or substring), e.g. https://shop.example/*.
levelNoMinimum severity; a level includes everything more severe.all
limitNoHow many of the most recent events to return.
sinceNoOnly events with seq greater than this; the cursor for polling forward.
followNoCollect from the live control channel for a bounded window instead of reading the file.
browserNoWhich dist/extension-js/<browser>/ to read. Defaults to this project's live session, else chrome.
contextNoRestrict to these contexts. Omit for all.
followMsNoHow long to collect live frames when follow=true (clamped 500–15000ms).
projectPathYesExtension project root (needs a live dev session)
signalsOnlyNoOnly structured dx.signal diagnostics (code/status/remediation), no plain console lines.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations by disclosing that this reads the agent-bridge plane used by the `extension logs` CLI, that one-shot reads logs.ndjson, that follow replays a broker ring of up to 5,000 events (counted in value.replayed) then live frames during followMs (value.live), and that an active dev session is required. This is rich operational context an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three dense but front-loaded sentences; the core purpose leads and mode specifics follow. Every sentence carries information, though the middle sentence is heavy with detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 11-parameter tool with no output schema, the description covers the prerequisite session, both operational modes, and the shape of returned counts (replayed/live). It misses only explicit return-format details for one-shot reads, which is minor given the strong annotation coverage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds meaning beyond the schema by explaining follow's replay/live split, the value.replayed and value.live outputs, and the followMs collection window. This enriches the follow and followMs parameters beyond their schema entries.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Read or stream logs') and resource ('logs from every context of a running dev session'), and enumerates the contexts explicitly. An agent can distinguish this from sibling tools like extension_inspect or extension_dev without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly explains the two modes (one-shot file read vs follow:true live channel) and states the prerequisite of an active extension_dev session. It lacks explicit when-not-to-use guidance or direct comparison to sibling tools, but the mode selection context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_manifest_validateA
Read-onlyIdempotent

Validate a manifest.json across browsers. This reports missing fields, invalid permissions, dangling file references, and cross-browser compatibility issues. Read buildBlocking for the errors that make extension_build refuse.

ParametersJSON Schema
NameRequiredDescriptionDefault
browserNoSingle browser to validate against; alias for browsers:[browser] to match the other tools.
browsersNoBrowsers to validate against
projectPathNoPath to the extension project root; manifest.json is resolved from it (root or src/). Accepted in place of manifestPath.
manifestPathNoPath to manifest.json. Or pass projectPath and the manifest is located for you.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive, closed-world, so the safety profile is covered. The description adds real behavioral substance beyond that: the four categories of findings it produces and the existence of a buildBlocking field that determines whether a build is refused. It does not mention severity levels, whether validation is fast/offline, or how findings are ordered, which keeps it out of 5 territory.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core action and scope, followed by the finding categories and then the downstream consequence. Nothing is redundant and the most decision-relevant clause ('across browsers') appears first.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description compensates by naming buildBlocking and the categories of findings an agent should expect. That is enough to call it correctly, but it does not sketch the overall result shape (e.g. per-browser grouping or pass/fail summary), leaving a small gap for a tool with an entirely undocumented return value.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and all four parameters (browser, browsers, projectPath, manifestPath) carry their own descriptions, including the aliasing relationship between browser and browsers and the projectPath/manifestPath substitution. The description text adds nothing about parameters, so the baseline of 3 is correct.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb and resource ('Validate a manifest.json') and immediately scopes it ('across browsers'), then enumerates the exact defect classes it surfaces (missing fields, invalid permissions, dangling file references, cross-browser issues). This is distinguishable from siblings like extension_build, extension_doctor, and extension_analyze without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a clear operative context by tying itself to extension_build ('the errors that make extension_build refuse') and pointing at the buildBlocking field, which tells an agent this is the pre-build gate. It stops short of explicit when-not guidance, e.g. why to choose this over extension_doctor or extension_analyze, so it falls one step short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_openA

Open an extension surface, or replay an event, in a running session. Pass surface:'popup', 'options' or 'sidebar' to open a UI surface, or 'newtab', 'history' or 'bookmarks' to open the matching chrome_url_overrides page in a tab (always a tab, resolved by the server, never sent to the engine). On Chromium, when Chrome refuses the sidebar for lack of a user gesture, the server opens the real panel through a synthetic click on the extension's own page and says so in warnings; if that fails too it renders the sidebar document as a tab. Pass surface:'devtools' to open the browser's DevTools on a tab (the one url matches, else the first web page) and show the extension's panel there, picked by panel title when there are several: Chromium only, over CDP Target.openDevTools, headed or headless; the result names the panel document's url, which extension_eval reads with context 'page' and that url (the panel is no tab, so the tab-based readers do not reach it). Pass surface:'action' to trigger the toolbar action, which opens its popup or replays chrome.action.onClicked when there is none. Pass surface:'command' with name to replay a chrome.commands.onCommand shortcut. Note that action and command replay invoke your listener without a user gesture, so the gesture-derived activeTab grant does not apply; the engine's own frame is returned as is. Start the session with allowControl:true (extension_dev).

ParametersJSON Schema
NameRequiredDescriptionDefault
tabNoWith `url`: navigate this chrome.tabs id in place instead of opening a new tab (rides the engine's navigate verb, so the session needs allowControl: true). Without it an existing page is never taken over.
urlNoNavigate a real tab here instead of opening a surface, in a NEW tab unless `tab` names one (a blank or new-tab page is reused). An absolute url opens as given; a path with no scheme, such as pages/options.html, is resolved against the extension's own origin. Use for content-script test pages, or a surface as a page.
nameNoFor surface 'command': the chrome.commands name to trigger.
asTabNopopup/options/sidebar: render the surface's document in a real tab instead of a popup window. This is how you inspect a surface HEADLESSLY, and it is applied automatically when a headless session refuses to open one. Same page and APIs, but no popup sizing and window.close() closes the tab.
panelNoFor surface 'devtools': the title the extension gave chrome.devtools.panels.create, when it registers more than one panel. Omitted, the extension's first panel is shown.
reloadNoFor surface 'devtools': reload the inspected tab once DevTools is open, for extensions that create their panel only when the page reports to them on a load that starts with DevTools open (Preact Devtools). Discards the page state under test.
waitMsNoFor surface 'devtools': how long to wait for the panel to register after DevTools opens (default 15000, up to 120000). Extensions that create their panel on a page event need longer, or `reload`.
browserNoSession browser; defaults to this project's live session
surfaceNoWhich surface to open or event to replay.
timeoutNoCommand timeout in ms. When omitted, the default depends on the route: 30000 through the dev session's control channel, 10000 over the Firefox debugger protocol, and 15000 per command over the Chromium debug port.
projectPathYesExtension project root (needs a live dev session)

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: it discloses Chromium-only sidebar fallback via synthetic click and tab rendering, the warnings channel, CDP Target.openDevTools usage, that action/command replay runs without a user gesture so activeTab does not apply, and that reload discards page state. This is exactly the extra side-effect and caveat context annotations do not carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded and each sentence conveys substantive behavioral detail rather than filler, but it is a single dense run-on block with heavy parenthetical asides that would read better as a per-surface breakdown. Appropriately sized for nine surfaces, slightly overpacked in structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 11-parameter tool with no output schema it covers the main intents, prerequisites, and fallback behaviors well, and even hints at the return shape for the devtools case. It is largely self-sufficient, though the return framing for the non-devtools surfaces is left implicit.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds cross-parameter meaning the schema does not: how `url` interacts with `tab`, that `panel` selects among multiple panels, and that the devtools result url is consumed by extension_eval with context 'page'. That linking value lifts it above baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (open/replay) and resource (extension surface or event) and enumerates every surface value with its distinct effect. It also names related siblings (extension_dev for the allowControl session, extension_eval for reading the panel document), so an agent can place it precisely in the toolset.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It tells the agent which surface value to pass for each intent (UI surface vs chrome_url_overrides tab vs DevTools vs action/command replay) and gives a prerequisite (start the session with allowControl:true). It lacks explicit when-not-to-use guidance against alternatives like extension_reload or extension_inspect, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_preview_webA

Preview an in-progress extension in the web emulator, with no real browser. This builds the project (unless build:false) and previews dist/. Pass share:true unless you are working inside the extension.dev monorepo: it uploads the build and returns a link anyone can open, with no install, sign-in or dev server, and it is the only lane that works from an npm install of this server. Sharing also serves the build as a zip, so it hands over the built code; read the share property before using it. The default lane instead returns a deep link over the dev-only preview://build scheme, which resolves only against a preview.extension.dev dev server on this machine, so it is for people developing extension.dev itself. Call extension_shares to list and revoke every link shared this way, so one never vanishes with this response.

ParametersJSON Schema
NameRequiredDescriptionDefault
openNoAlso open the deep link in a running session's browser, in a focus-safe background tab. Needs a live extension_dev/extension_start session.
buildNoBuild first. false previews the existing dist/<browser> as-is.
probeNoFetch the surface's dev middleware first to confirm the artifact loads on the local host. With share:true it also checks the shared link the way a browser would, following the zip's redirects and asserting the final response allows the preview origin, and reports that as share.browserLoadable.
shareNoUpload the built dist and return a public link (share.previewUrl) that renders those exact bytes for anyone: no install, sign-in or dev server. Uploading is metered against your plan's allowance on extension.dev; left false, the result's share property says what the local deepLink needs, what share:true spends, and the exact call to get a shareable link. It also serves the build as a zip (share.zipUrl), so sharing hands over the code. Needs a token scoped to an extension.dev project (extension_auth or EXTENSION_DEV_TOKEN); without one you get a login hint and the local preview still succeeds. Live until share.expiresAt; DELETE share.revokeUrl to kill it sooner. Revocation is permanent, and re-sharing an unchanged build returns the same link unless it was revoked, so each share is also appended to the project's gitignored .extension.dev/shared-previews.json.
openInNoWhich session's browser to open it in. Defaults to `browser`.
browserNoWhich dist/<browser> output to preview. The emulator renders it as mocked Chrome either way.chrome
hostUrlNoOrigin of the running preview.extension.dev dev server (default http://localhost:3110).
projectNoWhich stored login to use, as '<workspace>/<project>' (or a project slug that matches one login), when extension_auth has signed in to more than one project on this machine. Omitted, the most recent login is used, after EXTENSION_DEV_TOKEN when that is set. Named, it outranks EXTENSION_DEV_TOKEN. extension_auth (action: status) lists the stored logins.
distPathNoPreview this built directory instead of dist/<browser> under projectPath. Implies build:false.
projectPathYesExtension project root

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare the generic safety profile (writes, open-world, non-idempotent); the description adds substantial behavioral context beyond them: sharing uploads and hands over built code, is metered against a plan allowance, requires a scoped token or yields a login hint, is live until share.expiresAt, revocation is permanent, and each share is logged to a gitignored file. This is well past the bar set by annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and the no-real-browser qualifier are front-loaded, and the sentences are dense with decision-relevant information rather than filler. It is long for a single paragraph, and a couple of clauses (e.g. the gitignore log detail) border on optional, but nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 10 parameters, no output schema, and an open-world network write, the description does the heavy lifting: it names the returned fields an agent must inspect (share, share.previewUrl, share.zipUrl, share.expiresAt, share.revokeUrl, deepLink) and covers auth and cleanup. A tighter mapping of the default-lane result shape would make it fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the parameter descriptions are themselves extremely detailed, so the schema already carries the parameter burden. The body text adds nuance about the share/build interaction but largely restates what the schema properties say. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (preview an in-progress extension in a web emulator) and immediately scopes it against alternatives: 'with no real browser,' the share lane vs. the local deep-link lane. An agent can distinguish it from extension_dev, extension_start and extension_build without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly tells the agent when to pass share:true and when not to ('unless you are working inside the extension.dev monorepo'), explains which lane works from an npm install, and names extension_shares as the revocation path. When/when-not/alternative are all present.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_project_createA

Create an extension.dev project for an extension that does not have one yet, without opening the console. Use it right after extension_create and extension_build, once the extension's source is pushed to a GitHub repository, and BEFORE extension_auth: extension_auth can only log in to a project that already exists, and this tool is what brings that project into existence. Ask for nothing but the project slug and the repo; the platform finds the GitHub App installation on the approving account itself, and if there is none it returns a connect link to open. Two-phase, like login: the first call returns a code and a URL where a signed-in member of the workspace approves creating exactly this project; call again with the returned deviceCode to finish. The approval mints a provisioning grant that lives minutes, can only create the one named project, and is never stored on this machine. On success the platform creates the project and its mirror repository, and dispatches the first build when it can: the answer says in firstBuild whether one was dispatched and, when none was, why (no commits, no build workflow, a spent build allowance, a paused dispatch). Then run extension_auth (action: login) against the new project, and extension_publish to share it. To create several projects in one workspace under one approval, pass projects instead of project and repo: the approval page lists every name, each project is created by its own request, and each one's 7-day token is stored as that project's login, so no extension_auth call is needed afterwards. A list takes a few calls to finish: while projects remain the answer is status 'creating' with the same deviceCode to call again, and the grant is held in this server's memory only. One approval creates at most 10 projects, the cap the platform states in its login config, because it creates at most 10 per hour for one approving account; the next 10 can start in a new call once that limit allows. A longer list is refused before any approval is asked for, never split silently, and so is any list on a platform that does not advertise batch onboarding.

ParametersJSON Schema
NameRequiredDescriptionDefault
apiNoPlatform base URL (default EXTENSION_DEV_API_URL, else https://www.extension.dev)
repoNoSource GitHub repository as '<owner>/<repo>'. The extension's code must be pushed there, and the owner must be the same GitHub account that approves the device code.
projectNoTarget project as '<workspace>/<project>'. The workspace is the GitHub login of the approving user for personal workspaces; the project slug is the new project's name and must not exist yet.
browsersNoBrowsers the platform builds, each enabled with the same install and build command and its own output directory. Pass every browser the extension targets, for example ["chrome", "edge", "firefox"], so the project needs no console visit to go cross-browser.
projectsNoCreate several projects in one workspace under one approval, instead of `project` and `repo`. 1 to 10 entries (the platform's cap per approval; never more than 20), each { project: '<workspace>/<project>', repo: '<owner>/<repo>' }, all in the same workspace, each project named by its exact slug (lowercase letters and digits joined by single dashes, at most 48 characters), none twice and none existing yet. An entry may also carry displayName, description, installCommand, buildCommand, outputDirectory, browsers and outputDirectories for that project alone; the same inputs at the top level are the shared default for every entry that leaves them out. The answer carries one row per project: created and logged in, created with no token (run a batch extension_auth login), refused with the platform's code, or not attempted. A refusal on one project never hides the others.
deviceCodeNoResume token from the prior call's `deviceCode`; omit on the first call. A batch returns the same deviceCode until every listed project has an answer.
descriptionNoShort project description. Defaults to a generic sentence naming the repo.
displayNameNoHuman name for the project. Defaults to the project slug.
buildCommandNoBuild command producing the extension bundle.npm run build
installCommandNoDependency install command the build runs first.npm install
installationIdNoOptional override. Leave it out: the platform finds the extension.dev GitHub App installation on the approving account itself. Pass it only when an operator needs to name one explicitly, and it must still be an installation on that account or the platform refuses it.
outputDirectoryNoDirectory the build writes the loadable extension into. With more than one browser, `<browser>` in the path becomes each browser's name (Extension.js writes `dist/<browser>`), and when it is left out every browser defaults to `dist/<browser>`.dist/chrome
outputDirectoriesNoPer-browser output directory overrides, for example {"edge": "build/manifestv3"}. A browser named here wins over `outputDirectory`.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well past the annotations: two-phase device-code approval flow, a provisioning grant that lives minutes, can create only the named project, and is never stored locally, plus project + mirror-repo creation, first-build dispatch with a `firstBuild` reason field, and server-memory-only grant retention for batches. Rate/lifecycle limits (10 per approval, 10 per hour, next batch after the hour allows) are disclosed, which annotations cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and sequencing are front-loaded, and most sentences carry routing or behavioral information. It is long (~400 words) and restates the 10-per-approval cap twice across the batch paragraph, so it could be tightened, but there is little pure filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex 13-parameter, nested-object, no-output-schema creation tool, the description covers the two-phase protocol, the return shape (`firstBuild` status/reason, one row per project with created/no-token/refused/not-attempted), and failure modes (connect link, batch refusal on unsupported platforms). Nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3 and the schema already documents each parameter. The description adds cross-parameter semantics the schema cannot: `projects` substituting for `project`+`repo`, sharing top-level inputs as defaults, the 1–10 cap, and that `deviceCode` is reused until every listed project has an answer. It is additive rather than redundant.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb and resource ('Create an extension.dev project for an extension that does not have one yet, without opening the console') and immediately distinguishes itself from three siblings (extension_create, extension_build, extension_auth). An agent can identify exactly what this does and when it applies without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit sequencing: 'Use it right after extension_create and extension_build, once the extension's source is pushed to a GitHub repository, and BEFORE extension_auth', with the reason extension_auth cannot create the project. It also states the follow-up (extension_publish) and the batch alternative, so when-to-use and what-comes-next are both pinned down.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_publishA

Publish the project your stored token is scoped to (extension_auth, or EXTENSION_DEV_TOKEN) to extension.dev, and return its shareable URL. This is what "deploy" or "ship" an extension usually means; extension_submit is the separate store-review path. The target is the token's project: there is no projectPath, and no local file is uploaded. With several logins stored, pass project ('/') to pick which one; it outranks EXTENSION_DEV_TOKEN. For a public project the URL is the canonical public page and ttlHours does not apply. For a private one it is a fresh time-limited share link (?share=) whose lifetime is ttlHours.

ParametersJSON Schema
NameRequiredDescriptionDefault
apiNoPlatform base URL (default EXTENSION_DEV_API_URL, else https://www.extension.dev)
projectNoWhich stored login to use, as '<workspace>/<project>' (or a project slug that matches one login), when extension_auth has signed in to more than one project on this machine. Omitted, the most recent login is used, after EXTENSION_DEV_TOKEN when that is set. Named, it outranks EXTENSION_DEV_TOKEN. extension_auth (action: status) lists the stored logins.
buildShaNoPin the URL to a build sha (7-40 hex chars). The platform rejects a sha missing from a readable build index; when its index cannot be read it echoes the sha back and a pin on a failed build is accepted, so value.buildSha is the platform's claim, not a verified build. extension_release_status lists the builds it knows.
ttlHoursNoPrivate-project share-link lifetime in hours, 1-168 (default 24). Ignored for public projects.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite annotations covering the safety profile (readOnlyHint=false, openWorldHint=true, destructiveHint=false), the description adds substantial non-obvious behavior: the target is the token's project with no projectPath and no local file upload, public projects get a canonical URL where ttlHours is ignored while private ones get a time-limited ?share= link, and buildSha is an unverified platform claim the platform may echo back on a failed build. These are real gotchas that annotations cannot express.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with verb, target and return value, then threading the alternative path, token precedence, and public/private URL semantics in order of relevance. The prose is dense and every sentence carries information, though the final paragraph is long enough that a reader must parse carefully.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description compensates by explaining the return value in both cases (canonical public URL vs fresh ?share= link with ttlHours lifetime). It also covers the auth model, multi-login disambiguation, and the buildSha verification caveat, which is everything needed to call a four-parameter, zero-required deploy tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is already 100%, so the schema fully documents api, project, buildSha and ttlHours. The description's parameter-relevant content (project precedence over EXTENSION_DEV_TOKEN, ttlHours ignored for public projects, absence of a projectPath) largely restates the schema rather than extending it, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Publish the project your stored token is scoped to ... to extension.dev') and names the concrete artifact returned (shareable URL). It also explicitly distinguishes itself from the sibling extension_submit by labeling that tool the 'separate store-review path', so an agent can route without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives the when-to-use framing directly ('This is what "deploy" or "ship" an extension usually means') and names the alternative path (extension_submit) with the condition that selects it. It further states prerequisites for the multi-login case (pass `project`, which outranks EXTENSION_DEV_TOKEN), leaving little to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_release_promoteA
Destructive

Promote a built extension to a release channel (stable, preview, beta, …) on extension.dev, headless. This WRITES: it is the only verb that changes what a channel points at. It is auth-gated by your stored login (extension_auth) or a release token in EXTENSION_DEV_TOKEN, minted and revoked under project settings, Access tokens. Tokens live at most 7 days, so CI must re-mint before expiry. The project comes from the token; with several logins stored, project picks which one. Call extension_release_status to find a valid buildId. The status is 'promoted' only when the platform says every asked browser's release was dispatched and the channel pointer moved; 'promoted-partially' lists in its warnings what did not happen (a browser whose dispatch failed, a channel pointer that was not moved) and must not be repeated whole; 'promote-unconfirmed' means the platform's answer did not carry the result, so read extension_release_status before promoting again. Cutting a version-bump PR is not available headlessly, because it writes to your source repo and needs an interactive login.

ParametersJSON Schema
NameRequiredDescriptionDefault
apiNoPlatform base URL (default EXTENSION_DEV_API_URL, else https://www.extension.dev)
buildIdYesBuild commit SHA to promote (a 7-char short SHA is fine)
channelYesTarget release channel, e.g. stable, preview, beta
projectNoWhich stored login to use, as '<workspace>/<project>' (or a project slug that matches one login), when extension_auth has signed in to more than one project on this machine. Omitted, the most recent login is used, after EXTENSION_DEV_TOKEN when that is set. Named, it outranks EXTENSION_DEV_TOKEN. extension_auth (action: status) lists the stored logins.
versionNoVersion label for the release (optional)
browsersNoBrowsers to release. Optional: when omitted the platform reads the build's browsers from its index, and falls back to chrome alone when that index cannot be read, so pass them to be sure.
approvalIdNoThe approval handle returned by a prior approval-required response. Promoting changes what a public channel serves and is not reversible in place, so when the platform's approval gate is on this needs a human approval: call once without this to get an approval id and URL, have a human approve at extension.dev, then call again with the same id.
releaseNotesNoRelease notes markdown (optional)
sourceChannelNoChannel to promote from (optional; inferred otherwise)

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond annotations by disclosing auth mechanisms (stored login or EXTENSION_DEV_TOKEN), the 7-day token lifetime and CI re-mint requirement, the human approval gate two-call flow, and that promotion is not reversible in place. The status semantics ('promoted', 'promoted-partially', 'promote-unconfirmed') add real operational context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the write/auth/safety facts and generally dense with useful content, but it is long and some status-handling detail could be trimmed. Nearly every sentence carries weight, so it stays efficient despite its size.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive mutation tool with nine parameters and no output schema, the description supplies the missing return semantics (status values), auth requirements, approval flow, and irreversibility. Nothing an agent needs to call it correctly appears absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and its field descriptions already cover approvalId's two-step flow, project precedence, browsers fallback, and buildId format. The description largely restates this, so it adds little parameter meaning beyond what the schema provides. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('promote a built extension to a release channel') and explicitly claims unique scope: 'the only verb that changes what a channel points at.' It is clearly distinguishable from siblings like extension_publish, extension_release_status, and extension_build.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent: 'Call extension_release_status to find a valid buildId,' and names the exclusion ('Cutting a version-bump PR is not available headlessly'). It also states the recovery conditions for partial and unconfirmed outcomes.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_release_statusA
Read-onlyIdempotent

Read where a project stands on extension.dev, from the public registry (registry.extension.land). This is read-only: it dispatches nothing and promotes nothing. Pass include:'releases' for the release channels (channel to promoted build sha), recent builds, and a public build-page URL for each, which is how you find a valid sha for extension_release_promote, extension_submit or extension_publish. Pass include:'stores' for the per-store picture after an extension_submit (chrome, firefox, edge, safari): configured or not, the last credential health check, the last recorded submission, and the latest review status, read from stores/health.json, stores/status.json and stores/submissions.json. Both are included by default. This defaults to the logged-in project (extension_auth); pass workspace and project to read another. Private projects work when your stored login covers them. Registry state can lag the store dashboards by up to a polling interval.

ParametersJSON Schema
NameRequiredDescriptionDefault
apiNoPlatform base URL (default EXTENSION_DEV_API_URL, else https://www.extension.dev)
includeNoWhich sections to read. Both by default.
projectNoProject slug override (default: the stored login's).
workspaceNoWorkspace slug override (default: the stored login's).

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint/idempotentHint/destructiveHint=false, but the description adds real value beyond them: 'dispatches nothing and promotes nothing', the caveat that registry state can lag store dashboards, and that private projects work when the stored login covers them. This is strong disclosure, though return-shape detail leans on the include explanation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose then default behavior, section semantics, overrides, and caveats. Dense and information-rich; each sentence carries weight, though the middle is somewhat packed and could be split for easier scanning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the return-value burden and does so: it describes the release channels, build URLs, and per-store fields (configured state, credential health, last submission, review status) plus their source files. An agent has enough to call and interpret it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% (baseline 3), and the description adds meaning beyond the schema by enumerating what include:'releases' returns (channel→promoted sha, builds, build-page URL) and include:'stores' returns per store. It also clarifies workspace/project override the stored login default.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Read where a project stands on extension.dev, from the public registry (registry.extension.land).' It clearly positions itself as a status/read tool distinct from the mutation siblings it references.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly tells the agent when to use include:'releases' (to find a valid sha for extension_release_promote, extension_submit, extension_publish) and include:'stores' (after extension_submit). It names the alternative tools and the conditions that route to them rather than leaving it to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_reloadA
Idempotent

Reload a running extension's background context, or a tab. Start the session with allowControl:true (extension_dev).

ParametersJSON Schema
NameRequiredDescriptionDefault
tabNoFor content/page: a specific tab id
browserNoSession browser; defaults to this project's live session
contextNobackground
timeoutNoCommand timeout in ms. When omitted, the default depends on the route: 30000 through the dev session's control channel, 10000 over the Firefox debugger protocol, and 15000 per command over the Chromium debug port.
projectPathYesExtension project root (needs a live dev session)

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare non-read-only, idempotent, non-destructive behavior, and the description is consistent with them. It adds the session-control prerequisite (allowControl:true), which is useful behavioral context, but does not say what reload resets (background state, tab contents) or what auth/session it depends on beyond that.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with zero waste; the core action is front-loaded and the prerequisite follows immediately. Nothing is padded or redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a state-changing tool with no output schema, the description conveys the action and the session requirement but leaves the effect of the reload and any return signal unstated. Annotations carry some of the safety burden, so it is adequate but with clear gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is high (80%) and the timeout/browser/projectPath params are well documented in-schema. The description's 'background context, or a tab' loosely maps to the context and tab parameters but adds no format or selection detail beyond the schema. Baseline 3 when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (reload) and resource (a running extension's background context, or a tab), which cleanly separates it from siblings like extension_build, extension_start, and extension_stop. It doesn't explicitly name those siblings, but the action is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides a genuine precondition — the session must be started with allowControl:true via extension_dev — which tells the agent when this tool is callable. It stops short of saying when to prefer this over alternatives such as extension_start or restarting the session.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_sharesA
Destructive

List and revoke the public preview links this token has shared, which is what extension_preview_web share:true hands out. Pass action:'list' (the default) for every artifact the logged-in project owns, with its artifactId, name, version, live or dead state, createdAt, expiresAt, revokedAt, size, previewUrl, zipUrl and revokeUrl, so a link whose response you lost is findable again. Each row carries owner and sharedBy as the platform returned them. Read attribution.ownership for who may revoke a share: 'project' means the workspace holds it and any member can pull it back, 'personal' means one person holds it alone, 'unknown' means no owner was disclosed. Read attribution.credit as credit only, never access; it names the publisher, and reads 'CLI token ' or 'not recorded' when no person can be named. Pass action:'revoke' with an artifactId, or with any URL of the share, to kill one permanently. Pass projectPath to reconcile against the project's own append-only .extension.dev/shared-previews.json, which is read and never rewritten: a share made on another machine shows as remoteOnly, a record with no live artifact as localOnly. That record is append-only, so localOnly is counted by distinct artifactId and a build re-shared unchanged is one share, not two; server.count and server.matched are share counts, while server.scanned counts records the platform read and is never a share count. This needs the same token as sharing (extension_auth or EXTENSION_DEV_TOKEN); without one, listing still returns the local record with a login hint.

ParametersJSON Schema
NameRequiredDescriptionDefault
apiNoPlatform base URL (default EXTENSION_DEV_API_URL, else https://www.extension.dev)
urlNoAny URL of the share to revoke (previewUrl, zipUrl, viewUrl, or revokeUrl). The artifact id is read out of it, so the link you sent someone is enough to pull it back.
limitNoHow many shares to return, 1 to 200 (platform default 100). A cut list comes back with truncated:true.
actionNolist reads every share this token owns; revoke permanently kills one and cannot be undone.list
statusNoall (default) includes expired and revoked shares, which is what makes a dead link explainable; live returns only the links the platform reported resolving at list time (a 429 or 503 from the platform answers listed-local-only, which says nothing about any link).all
projectNoWhich stored login to use, as '<workspace>/<project>' (or a project slug that matches one login), when extension_auth has signed in to more than one project on this machine. Omitted, the most recent login is used, after EXTENSION_DEV_TOKEN when that is set. Named, it outranks EXTENSION_DEV_TOKEN. extension_auth (action: status) lists the stored logins.
approvalIdNoThe approval handle returned by a prior approval-required response for a revoke. Revoking permanently burns a share and cannot be undone, so when the platform's approval gate is on this needs a human approval: call revoke once without this to get an approval id and URL, have a human approve at extension.dev, then call revoke again with the same id. Listing never needs it.
artifactIdNoWhich share to revoke (the gen_... id from a share response or from action:"list"). Required for revoke unless url is given.
projectPathNoPath to the extension project root. Reconciles the platform's answer against this project's .extension.dev/shared-previews.json record. Read-only.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With annotations already declaring destructiveHint=true and readOnlyHint=false, the description adds substantial context beyond them: revoke is permanent and cannot be undone, the platform's approval gate requires a two-step human workflow, projectPath is read-only, and the append-only local record is never rewritten. It also discloses the 429/503 failure mode that answers listed-local-only.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose and the default action are front-loaded, and the density is largely justified because there is no output schema and the field enumeration must live in the description. It is still a single very long block, and some return-value detail could be tightened.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, open-world tool with nine parameters, no output schema, and no required parameters, the description compensates fully: it enumerates the returned fields, explains attribution.ownership and attribution.credit semantics, clarifies which server.* counters are share counts, and states the token requirement.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds meaning above that baseline by framing approvalId as part of a two-step revoke workflow and explaining that status:'all' exists specifically to make a dead link explainable, though much of the surrounding detail concerns return fields rather than parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence names a specific verb pair and resource ('List and revoke the public preview links this token has shared') and directly distinguishes itself from the sibling that creates these links ('which is what extension_preview_web share:true hands out'). An agent can identify the tool's role without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly walks through when to use action:'list' versus action:'revoke', when approvalId is required, when projectPath reconciliation applies, and which token is needed (extension_auth or EXTENSION_DEV_TOKEN). It even names the fallback behavior when no token exists, leaving nothing to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_startA

Run the PRODUCTION build in a browser: build the project, serve it, and launch. There is no hot module replacement and no control channel, so your edits are not picked up and extension_eval, extension_storage, extension_reload, extension_open and extension_dom_snapshot cannot attach to this session. Use extension_dev while writing code, and this to check what actually ships. Pass build:false to launch an existing dist/ without rebuilding, or outputPath to launch any prebuilt unpacked extension directory, one another toolchain produced included, which implies build:false.

ParametersJSON Schema
NameRequiredDescriptionDefault
hostNoBind host, default 127.0.0.1. Use 0.0.0.0 in Docker or devcontainers.
portNoPassed to the engine as --port (0 for auto-assign). A production start serves nothing over it today; it matters only to a toolchain that reads it.
buildNoBuild before serving. false serves the existing dist/<browser> as-is and fails when there is none.
browserNochrome
profileNoProfile path, or "false" to reuse the real user profile. Omit for a throwaway one.
polyfillNoApply cross-browser polyfill (build only)
noBrowserNoBuild (or, with build:false, check the dist) without launching a browser. A production start serves nothing, so with no browser the engine process ends once the build does; read the result with extension_build rather than a session.
extensionsNoExtra extension paths or store URLs to load alongside the project
outputPathNoAn existing unpacked extension directory to launch as it is (a manifest.json at its root), for an artifact built by another toolchain or an exact release candidate. Implies build:false; projectPath still names the project the session belongs to. Relative paths resolve against projectPath.
publicHostNoHost the browser dials for HMR and reload when it differs from the bind host
geckoBinaryNoCustom Gecko/Firefox binary to launch; `browser` still names the target family the engine builds for (gecko-based when none is given).
projectPathYesExtension project root
startingUrlNoURL the browser opens on launch
chromiumBinaryNoCustom Chromium-based binary to launch; `browser` still names the target family the engine builds for (chromium-based when none is given).

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations by disclosing that there is no HMR and no control channel, enumerating exactly which sibling tools cannot attach (extension_eval, extension_storage, extension_reload, extension_open, extension_dom_snapshot), and explaining that a noBrowser production start ends when the build does.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose and free of filler, but the long multi-clause sentence chain is dense. Every clause does convey distinct behavior, so little is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 14-parameter launch tool with no output schema, the description covers build/serve/launch mechanics, session limitations, and the prebuilt-artifact path, which is everything an agent needs to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 93%, so the baseline is 3, but the description adds cross-parameter behavior: outputPath 'implies build:false' and build:false serves an existing dist or fails when none exists. That relational meaning is not in the schema itself.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Run the PRODUCTION build in a browser: build the project, serve it, and launch') and explicitly distinguishes itself from the sibling extension_dev, so an agent can route correctly without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use routing ('Use extension_dev while writing code, and this to check what actually ships') plus concrete conditional variants for build:false and outputPath. Alternatives and exclusions are named directly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_stopA
DestructiveIdempotent

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. This covers extension_start build:false too, which the registry records as a preview session. Call it when you are done verifying, so sessions do not accumulate.

ParametersJSON Schema
NameRequiredDescriptionDefault
allNoStop every known session across projects and browsers, found from this server's registry AND the on-disk markers written by this server or by servers that are no longer running, so it still works after an MCP restart. A marker owned by another MCP server that is still running is left alone and listed under skippedForeign unless includeOtherServers is true. It also takes back every live-preview carrier still recorded on this machine, including one in a project whose session was never stopped. projectPath/browser are then ignored.
browserNoBrowser of the session to stop. Defaults to the single live session for this project rather than assuming chrome.
projectPathNoExtension project root
includeOtherServersNoWith all: true, also stop sessions whose markers belong to another MCP server that is still running (the markers sit in a per-user directory every server shares). Off by default, since those sessions are someone else's.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry destructiveHint=true and idempotentHint=true, so the safety profile is partly covered. The description still earns credit by specifying exactly what is destroyed (server + launched browser + live-preview carrier) and the preview-session edge case. It does not address failure behavior when no session exists, leaving a small gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the primary action and scoped by three tight sentences with no filler. The first sentence is dense but every clause (server, browser, carrier) carries distinct information. Slightly heavy for its length, but no sentence is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive lifecycle tool with no output schema and thorough annotations, the description covers purpose, scope of destruction, the preview-session variant, and the usage trigger. It omits the no-op/error case when no session is found, which is the only notable missing context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the parameter docs are unusually thorough (all, browser, projectPath, includeOtherServers). The description adds no parameter-level syntax or format detail beyond what the schema states, so the baseline 3 is appropriate when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb (stop) plus resource (session) and an explicit enumeration of what is terminated: the server, the launched browser, and the live-preview carrier. It names the sibling tools that create these sessions (extension_dev, extension_start) and even calls out the extension_start build:false preview variant, so an agent can distinguish it from launcher tools without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear triggering condition: 'Call it when you are done verifying, so sessions do not accumulate.' That establishes when to invoke it relative to the dev/start lifecycle. It does not state when *not* to call it (e.g. mid-verification, or while another server owns the session), so it falls short of explicit exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_storageA
Destructive

Read or write chrome.storage in a running extension. Every call runs in the extension's background (the engine honours no context), so it proves nothing about what a content script or page can read. A set is read back and the answer says whether the stored value matches. Start the session with allowControl:true (extension_dev). Set one key per call: there is no bulk-object set.

ParametersJSON Schema
NameRequiredDescriptionDefault
keyNoKey to get or set
areaNolocal
valueNoValue to set (any JSON value); required for action=set
actionYesget reads a key (or the whole area); set writes a key
browserNoSession browser; defaults to this project's live session
timeoutNoCommand timeout in ms. When omitted, the default depends on the route: 30000 through the dev session's control channel, 10000 over the Firefox debugger protocol, and 15000 per command over the Chromium debug port.
projectPathYesExtension project root (needs a live dev session)

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial behavior the annotations cannot express: every call runs in the background so it proves nothing about content-script or page reads, a set is read back and the answer reports whether the stored value matches, and there is no bulk-object set. These are real operational traits beyond the destructiveHint/non-idempotent flags, and nothing contradicts the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense and front-loaded: purpose first, then behavioral caveats, then setup requirement, then the key-per-call constraint. Every sentence carries information, though the phrasing is compact enough that some clauses read as terse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter tool with 86% schema coverage and no output schema, the description covers the non-obvious behavior well (background execution semantics, read-back verification, session prerequisite). It is nearly complete; only explicit alternative routing is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 86%, so the baseline is 3, but the description goes beyond the schema by imposing a genuine usage constraint: 'Set one key per call: there is no bulk-object set,' which clarifies how key/value must be used. It adds meaning on top of the documented parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence names a specific verb pair and resource: 'Read or write chrome.storage in a running extension.' It is unambiguous about what the tool operates on. Sibling differentiation is only partial — it references extension_dev for session startup but never explicitly contrasts itself with extension_eval or extension_inspect.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete prerequisite ('Start the session with allowControl:true (extension_dev)') and a scoping caveat explaining what the call does and does not prove. It stops short of naming an alternative tool or an explicit when-not set of conditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_submitA
Destructive

Submit a built extension for store REVIEW through extension.dev, which holds your store credentials and dispatches from your project's mirror CI: the Chrome Web Store, Firefox AMO, Edge Add-ons and the App Store (Safari). This is store review only. It does not push a build to the extension.dev platform, and it does not make a shareable link: that is extension_publish, which is what "deploy" or "ship" an extension almost always means. Reach for this only when the ask is explicitly a store submission. It defaults to a dry run that dispatches nothing: the platform verifies the token and project, finds the store workflow, reads the build from its index when that index is readable, reads store health itself and adds a Safari plan verdict; this tool re-reads the per-store health rows beside it. The dry run does not run the owner gate, the approval, the build quota, the dispatch pause or the submission-mode check, which the real run does first. Pass dryRun:false to actually submit, which is irreversible: only the workspace owner who issued the token may, and it dispatches the store workflow; a Chrome or Edge store with no saved submission mode is uploaded as a draft (absent_mode: safe) and does not enter review. A real submission answers 'submitted' only when the platform recorded a submission for every store asked; 'submitted-partially' names the stores it did not record, which are the only ones to submit again; 'submit-unconfirmed' means no usable answer came back, so read extension_release_status before submitting again, because a second call submits a second time. The project comes from your token (extension_auth or EXTENSION_DEV_TOKEN; tokens live at most 7 days, so CI must re-mint from the console's Access tokens page); with several logins stored, project picks which one. Store credentials are never arguments, and no local file is uploaded. Call extension_release_status for valid shas, and, after a real submission, for the recorded outcome and review state.

ParametersJSON Schema
NameRequiredDescriptionDefault
apiNoPlatform base URL (default EXTENSION_DEV_API_URL, else https://www.extension.dev)
dryRunNoPreflight only. Pass false to actually dispatch (irreversible, enters store review).
channelNoRelease channel to submit from (default stable).
projectNoWhich stored login to use, as '<workspace>/<project>' (or a project slug that matches one login), when extension_auth has signed in to more than one project on this machine. Omitted, the most recent login is used, after EXTENSION_DEV_TOKEN when that is set. Named, it outranks EXTENSION_DEV_TOKEN. extension_auth (action: status) lists the stored logins.
versionNoVersion label for the submission record (optional).
browsersYesStores to submit to.
buildShaYesThe built commit SHA to submit. It needs a completed build in the project's build index; an unknown sha is rejected.
approvalIdNoThe approval handle returned by a prior approval-required response for a real submission. A real submission (dryRun:false) is irreversible and needs a human approval when the platform's approval gate is on: call once without this to get an approval id and URL, have a human approve at extension.dev, then call again with the same id. A dry run never needs it.
projectPathNoPath to the extension project root, read only for the local STORE.md advisory check. Nothing local is uploaded; without it the check falls back to the server's working directory.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructive/non-idempotent/non-readonly/openWorld, and the description builds well past that: dry-run default and exactly which gates it skips vs. the real run, irreversibility, owner-only authorization, the approval loop, draft-upload behavior for Chrome/Edge without a saved mode, the submitted/partially/unconfirmed outcome vocabulary, and the 7-day token expiry. This is unusually rich disclosure for a destructive tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and the publish-vs-submit distinction are front-loaded, and the dry-run/real-run semantics follow logically. It is a dense, single long paragraph with some redundancy (irreversibility, token expiry and submission-mode checks are restated), but for a tool with this much behavior every clause mostly earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the full burden and does: it describes return-state vocabulary, failure handling ('read extension_release_status before submitting again'), prerequisites (build index, token, owner gate), and irreversible side effects. Nothing needed to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and each parameter is already well documented, so the baseline is 3. The description adds real meaning beyond the schema: it explains where the project identity comes from (token vs. `project`), how approvalId is used across two calls, that credentials are never arguments, and that projectPath is only used for a local STORE.md advisory.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with scope: 'Submit a built extension for store REVIEW through extension.dev'. It explicitly names the sibling it is not (extension_publish) and clarifies that 'deploy' or 'ship' usually means the other tool, so an agent can distinguish them without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use ('only when the ask is explicitly a store submission'), when-not ('does not push a build to the platform, does not make a shareable link'), the alternative (extension_publish), and points to extension_release_status for valid shas and post-submission outcome. Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_templatesA
Read-onlyIdempotent

Browse the extension.dev template catalog. Pass action:'list' (the default) to search and filter it and get metadata per template. Pass action:'source' with a slug to read one template's files, for learning a pattern before building something similar. Read framework as the UI framework only, never the language: TypeScript and JavaScript templates live under slugs ('typescript', 'content-typescript'), shadcn is a React variant ('sidebar-shadcn'), and provider AIs carry the 'ai' tag ('ai-chatgpt', 'ai-claude'). Reach those through query, tags or slug.

ParametersJSON Schema
NameRequiredDescriptionDefault
slugNosource: which template to read (e.g. 'ai-claude', 'content-react'). Required for source.
tagsNolist: filter by tags, e.g. ['ai', 'chat'].
filesNosource: paths to read (e.g. ['src/manifest.json']). Omit for the file listing.
queryNolist: keyword search over slug, description, tags and useCases. Ranks by word matches, so a natural phrase works.
actionNolist
surfaceNolist: filter by surface. For a popup/action starter use query:'action', not a surface.
featuredNolist: only featured templates.
frameworkNolist: UI framework filter (empty string = vanilla JS).

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this as a safe, idempotent, open-world read, so the bar is lower. The description still adds real context beyond them: 'list' returns metadata per template, 'source' returns a template's files, and it flags a non-obvious interpretation pitfall ('framework is the UI framework only, never the language'). It omits pagination/rate-limit behavior, so not a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and the action modes, then the framework caveat, so the most important routing information comes first. The framework sentence is long but every clause carries a distinct slug/tag mapping, so it earns its space; only mild density cost.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 8 all-optional parameters, no required inputs, and no output schema, the description does the necessary work by explaining both modes and roughly what each returns. It does not describe the file-listing vs file-content return shape in detail, but it is complete enough for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 88%, so the baseline is 3, but the description adds genuine meaning the schema lacks: it clarifies that 'framework' is UI-framework-only and that TypeScript/JavaScript, shadcn variants, and provider AIs are reached via slug/tags rather than the framework enum. That disambiguation is exactly what an agent would otherwise get wrong.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence names a specific verb and resource ('Browse the extension.dev template catalog'), then splits that resource into two concrete modes ('list' for search/filter/metadata, 'source' for reading one template's files). An agent can tell what this tool is and what it does without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is spelled out per action: 'list' is the default for searching/filtering, and 'source' is for 'learning a pattern before building something similar', which gives a clear motivating context. It stops short of naming sibling alternatives (e.g. extension_docs_search) or when-not-to-use, so it is strong context rather than full routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_theme_verifyA
Read-onlyIdempotent

Verify a Chrome theme manifest before it ships. This settles the four-leg WYSIWYG contract (app-shows == manifest-says == chrome-paints, plus chrome-accepts) as far as is possible headless: it derives every color current Chrome would paint from the manifest through the transcribed Chromium resolver, and classifies each problem as D1 fabrication, D3 parity gap, or D4 acceptance gap (keys Chrome silently discards: dead legacy, incognito, unknown, out-of-range). It verifies only, and never authors or mutates a theme. The app-rendered and real-pixel legs need a browser, so they come back as needsAttended pointing at the assert:theme and install-parity harnesses, never as passed.

ParametersJSON Schema
NameRequiredDescriptionDefault
manifestNoThe Chrome theme manifest object (with a `theme` block). Pass this or manifestPath.
manifestPathNoPath to a theme manifest.json (or a { manifest } seed wrapper). Read in place of the inline manifest.

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, yet the description adds substantial context beyond them: it verifies only and never authors or mutates, explains the D1/D3/D4 problem taxonomy (including keys Chrome silently discards), and discloses the headless limitation and that attended legs return needsAttended rather than passed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the purpose and remains a tight cluster of sentences, each carrying real information about scope, method, and return semantics. It leans heavily on domain jargon (four-leg, D1/D3/D4) that a fresh agent must infer, slightly reducing clarity per unit length.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the return-value burden and does so by explaining the classification outputs and the needsAttended/passed distinction. It is nearly complete for an agent to call it correctly, missing only the explicit alternative sibling and any concrete invocation example.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and both parameters (manifest, manifestPath) are documented in the schema itself. The description adds no additional parameter syntax, format, or precedence detail beyond the schema's own 'pass this or that' guidance, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Verify a Chrome theme manifest before it ships') and richly characterizes scope: it settles the four-leg WYSIWYG contract headless and classifies problems into D1/D3/D4. The theme-specific framing implicitly distinguishes it from the general extension_manifest_validate sibling, though that sibling is never named.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear usage context ('before it ships') and explicitly scopes what it can cover headless versus what needs a browser, routing the app-rendered and real-pixel legs to the assert:theme and install-parity harnesses. It stops short of naming the obvious sibling alternative (extension_manifest_validate) by name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_waitA
Read-onlyIdempotent

Wait for a running dev or start session to be ready. This polls the ready.json contract and reports compiled (the compiler finished), browserAttached (the runtime executor connected), and guestLoaded (the browser's own target list shows your extension). Read guestLoaded as the trustworthy load signal: it catches a silently rejected --load-extension that leaves ready.json stamped attached with empty logs. It is null when it could not be checked, for example a gecko session with no CDP port. Every result reports budgetMs and elapsedMs; on status 'timeout', call again to keep waiting on the same contract. In a noBrowser session this returns as soon as the compile lands, instead of waiting for a browser that will never attach. Ports come from the contract, so they match what the server actually bound.

ParametersJSON Schema
NameRequiredDescriptionDefault
browserNoSession browser; defaults to this project's live session
timeoutNoDeprecated alias of timeoutMs, which wins when both are given.
timeoutMsNoWait budget for this call. Default 45000, clamped to 1000-50000 so one call stays under the client's 60s request timeout. On timeout, call again to keep waiting.
projectPathYesExtension project root

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the readOnly/idempotent annotations: it explains the ready.json polling contract, the three reported signals and which one (guestLoaded) to trust, why it can be null, timeout/retry semantics, and port sourcing. This is unusually rich behavioral disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense but front-loaded: the core purpose leads, followed by signal meaning, null caveat, timeout retry, and noBrowser behavior. Nearly every sentence carries actionable information, though it is on the longer side.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description compensates by naming each returned field and its meaning. Combined with the annotations covering the safety profile, an agent has everything needed to call and interpret this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents all four parameters including the deprecated alias and clamping range. The description adds little parameter-level detail beyond noting ports come from the contract, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: 'Wait for a running dev or start session to be ready.' It clearly positions itself as the waiting/polling tool among siblings like extension_start and extension_dev. An agent can distinguish it immediately.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains the trigger context (a running dev or start session) and instructs to 'call again to keep waiting' on timeout, plus the noBrowser short-circuit. No explicit sibling alternative is named, but the usage condition is clear enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_workspace_createA

Create an extension.dev workspace that does not exist yet, without opening the console. Use it before extension_project_create when the project's workspace is not there: project creation can only target an existing workspace, and this tool is what brings one into existence. Two-phase, like login: the first call returns a code and a URL where a signed-in GitHub user approves creating exactly this workspace and becomes its owner; call again with the returned deviceCode to finish. Check ownerGithubLogin in the answer: whoever approved the code owns the workspace. The approval mints a grant that lives minutes, can only create the one named workspace, names no project, and is never stored on this machine. Then run extension_project_create against '/'.

ParametersJSON Schema
NameRequiredDescriptionDefault
apiNoPlatform base URL (default EXTENSION_DEV_API_URL, else https://www.extension.dev)
workspaceYesSlug of the new workspace, lowercase letters, digits and hyphens, no slash. It must not exist yet; a personal workspace (the GitHub login) already exists for every signed-in user, so this is for a shared or organization-style workspace.
deviceCodeNoResume token from the prior call's `deviceCode`; omit on the first call.
descriptionNoShort workspace description. Optional.
displayNameNoHuman name for the workspace. Defaults to the slug.
developerUrlNoPublic URL for the workspace. Optional.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only say it is a non-read-only, non-idempotent, open-world mutation. The description adds far more: a two-phase approval flow, that the first call returns a code and URL, that a signed-in GitHub user approves and becomes owner, that the grant is short-lived, single-purpose, names no project, and is never stored locally. This is exactly the behavioral context annotations cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and the sibling relationship, then flows into the two-phase mechanics. It is long, but nearly every sentence (ownership, grant lifetime, next call) carries information an agent needs; only mild trimming is possible.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex async, auth-gated creation tool with no output schema, the description covers the return values (code, URL, deviceCode, ownerGithubLogin), the sequencing, and the follow-up. Nothing essential for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description goes further by tying deviceCode to the second call ('call again with the returned deviceCode to finish') and flagging ownerGithubLogin as the ownership signal, adding flow semantics the schema field descriptions do not fully convey.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Create an extension.dev workspace that does not exist yet, without opening the console') and distinguishes itself from extension_project_create by scope. An agent can tell what it does and when it applies without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly orders it before extension_project_create and explains why: 'project creation can only target an existing workspace.' It also notes that personal workspaces already exist, so this is for shared/org-style workspaces, and even prescribes the follow-up call ('run extension_project_create against <workspace>/<project>').

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 20 tool updatesv10.10.13
    • Changedextension_assert1 field changed
      • changedInput schema / properties / timeout / description
        Previous value: -"Command timeout in ms (default 5000)"New value: +"Command timeout in ms. When omitted, the default depends on the route: 30000 through the dev session's control channel, 10000 over the Firefox debugger protocol, and 15000 per command over the Chromium debug port."
    • Changedextension_auth2 fields changed
      • changedInput schema / properties / project / description
        Previous value: -"login: target project as '<workspace>/<project>'; the token is scoped to it. The slug pair is the console address bar: an existing project's page is console.extension.dev/<workspace>/<project>. Create one at extension.dev/new if none exists yet."New value: +"login: target project as '<workspace>/<project>'; the token is scoped to it. The slug pair is the console address bar: an existing project's page is console.extension.dev/<workspace>/<project>. Create one at extension.dev/new if none exists yet. Logins to several projects are all kept, the latest is the default; token-scoped tools take `project` to pick another. logout: remove only this project's login (omitted, every stored login goes)."
      • addedInput schema / properties / projects
        Added value: +{
        +  "description": "login: sign in to several existing projects of one workspace with one approval, instead of one approval each. 1 to 20 names as '<workspace>/<project>', all in the same workspace, each by its exact slug (lowercase letters and digits joined by single dashes, at most 48 characters), none twice. Pass it instead of `project`, never beside it. The approval page lists every name; one missing project refuses the whole list and mints nothing. Resume with the returned `deviceCode` and the same list. Every token is stored as that project's own login and all expire within 7 days, so the same call renews them together.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
    • Changedextension_build2 fields changed
      • changedInput schema / properties / bundleId / description
        Previous value: -"Safari targets only: a reverse-DNS bundle identifier you own, such as com.acme.readinglist. Without one the app is packaged under a generated dev.extensionjs.* identifier derived from the app name, which every project built from the same template shares, and the first team to register it takes it."New value: +"Safari targets only: a reverse-DNS bundle identifier you own, such as com.acme.readinglist. Without one the app is packaged under a generated dev.extensionjs.* identifier derived from the app name, which two projects with the same name share, and the first team to register it takes it."
      • changedInput schema / properties / skipValidation / description
        Previous value: -"Build even when extension_manifest_validate reports build-blocking errors. The build normally refuses: a manifest error yields a broken bundle the bundler itself never flags."New value: +"Build even when extension_manifest_validate reports build-blocking errors. The build normally refuses: the engine itself stops only on missing scripts, icons, DNR rule files, default_locale and manifest_version, and ships a bundle over the rest."
    • Changedextension_dev2 fields changed
      • changedInput schema / properties / chromiumBinary / description
        Previous value: -"Custom Chromium-based binary (overrides browser)"New value: +"Custom Chromium-based binary to launch; `browser` still names the target family the engine builds for (chromium-based when none is given)."
      • changedInput schema / properties / geckoBinary / description
        Previous value: -"Custom Gecko/Firefox binary (overrides browser)"New value: +"Custom Gecko/Firefox binary to launch; `browser` still names the target family the engine builds for (gecko-based when none is given)."
    • Addedextension_docs_search
    • Changedextension_dom_snapshot1 field changed
      • changedInput schema / properties / timeout / description
        Previous value: -"Command timeout in ms (default 5000)"New value: +"Command timeout in ms. When omitted, the default depends on the route: 30000 through the dev session's control channel, 10000 over the Firefox debugger protocol, and 15000 per command over the Chromium debug port."
    • Changedextension_eval1 field changed
      • changedInput schema / properties / timeout / description
        Previous value: -"Command timeout in ms (default 5000)"New value: +"Command timeout in ms. When omitted, the default depends on the route: 30000 through the dev session's control channel, 10000 over the Firefox debugger protocol, and 15000 per command over the Chromium debug port."
    • Changedextension_inspect1 field changed
      • changedInput schema / properties / deepDom / description
        Previous value: -"Pierce CLOSED shadow roots; open ones are read anyway. Chromium: CDP DOM pierce. Firefox: a content-script walk via tabs.executeScript (MV2 only, needs host permissions for the target url)."New value: +"Pierce CLOSED shadow roots (open roots of the extension-root hosts are already inlined in html; other open roots are not read). Chromium: CDP DOM pierce. Firefox: a content-script walk via tabs.executeScript (MV2 only, needs host permissions for the target url); the answer says whether that context could see closed roots at all."
    • Changedextension_logs2 fields changed
      • changedInput schema / properties / browser / description
        Previous value: -"Which dist/extension-js/<browser>/ to read. Defaults to this project's live session, else chromium."New value: +"Which dist/extension-js/<browser>/ to read. Defaults to this project's live session, else chrome."
      • changedInput schema / properties / context / items / enum
        Previous value: -[
        -  "background",
        -  "content",
        -  "page",
        -  "sidebar",
        -  "popup",
        -  "options",
        -  "devtools",
        -  "newtab",
        -  "history",
        -  "bookmarks"
        -]New value: +[
        +  "background",
        +  "content",
        +  "sidebar",
        +  "popup",
        +  "options",
        +  "devtools",
        +  "newtab",
        +  "history",
        +  "bookmarks"
        +]
    • Changedextension_open3 fields changed
      • addedInput schema / properties / reload
        Added value: +{
        +  "default": false,
        +  "description": "For surface 'devtools': reload the inspected tab once DevTools is open, for extensions that create their panel only when the page reports to them on a load that starts with DevTools open (Preact Devtools). Discards the page state under test.",
        +  "type": "boolean"
        +}
      • changedInput schema / properties / timeout / description
        Previous value: -"Command timeout in ms (default 5000)"New value: +"Command timeout in ms. When omitted, the default depends on the route: 30000 through the dev session's control channel, 10000 over the Firefox debugger protocol, and 15000 per command over the Chromium debug port."
      • addedInput schema / properties / waitMs
        Added value: +{
        +  "description": "For surface 'devtools': how long to wait for the panel to register after DevTools opens (default 15000, up to 120000). Extensions that create their panel on a page event need longer, or `reload`.",
        +  "type": "number"
        +}
    • Changedextension_preview_web2 fields changed
      • addedInput schema / properties / project
        Added value: +{
        +  "description": "Which stored login to use, as '<workspace>/<project>' (or a project slug that matches one login), when extension_auth has signed in to more than one project on this machine. Omitted, the most recent login is used, after EXTENSION_DEV_TOKEN when that is set. Named, it outranks EXTENSION_DEV_TOKEN. extension_auth (action: status) lists the stored logins.",
        +  "type": "string"
        +}
      • changedInput schema / properties / share / description
        Previous value: -"Upload the built dist and return a public link (share.previewUrl) that renders those exact bytes for anyone: no install, sign-in or dev server. Uploading runs on extension.dev's machines and counts against your free allowance; left false, the result's share property says what the local deepLink needs, what share:true spends, and the exact call to get a shareable link. It also serves the build as a zip (share.zipUrl), so sharing hands over the code. Needs a token scoped to an extension.dev project (extension_auth or EXTENSION_DEV_TOKEN); without one you get a login hint and the local preview still succeeds. Live until share.expiresAt; DELETE share.revokeUrl to kill it sooner. Revocation is permanent, and re-sharing an unchanged build returns the same link unless it was revoked, so each share is also appended to the project's gitignored .extension.dev/shared-previews.json."New value: +"Upload the built dist and return a public link (share.previewUrl) that renders those exact bytes for anyone: no install, sign-in or dev server. Uploading is metered against your plan's allowance on extension.dev; left false, the result's share property says what the local deepLink needs, what share:true spends, and the exact call to get a shareable link. It also serves the build as a zip (share.zipUrl), so sharing hands over the code. Needs a token scoped to an extension.dev project (extension_auth or EXTENSION_DEV_TOKEN); without one you get a login hint and the local preview still succeeds. Live until share.expiresAt; DELETE share.revokeUrl to kill it sooner. Revocation is permanent, and re-sharing an unchanged build returns the same link unless it was revoked, so each share is also appended to the project's gitignored .extension.dev/shared-previews.json."
    • Changedextension_project_create3 fields changed
      • changedInput schema / properties / deviceCode / description
        Previous value: -"Resume token from the prior call's `deviceCode`; omit on the first call."New value: +"Resume token from the prior call's `deviceCode`; omit on the first call. A batch returns the same deviceCode until every listed project has an answer."
      • addedInput schema / properties / projects
        Added value: +{
        +  "description": "Create several projects in one workspace under one approval, instead of `project` and `repo`. 1 to 10 entries (the platform's cap per approval; never more than 20), each { project: '<workspace>/<project>', repo: '<owner>/<repo>' }, all in the same workspace, each project named by its exact slug (lowercase letters and digits joined by single dashes, at most 48 characters), none twice and none existing yet. An entry may also carry displayName, description, installCommand, buildCommand, outputDirectory, browsers and outputDirectories for that project alone; the same inputs at the top level are the shared default for every entry that leaves them out. The answer carries one row per project: created and logged in, created with no token (run a batch extension_auth login), refused with the platform's code, or not attempted. A refusal on one project never hides the others.",
        +  "items": {
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "project",
        -  "repo"
        -]New value: +[]
    • Changedextension_publish2 fields changed
      • changedInput schema / properties / buildSha / description
        Previous value: -"Pin the URL to a build sha (7-40 hex chars). An unknown sha is rejected, so the returned URL always points at a real build."New value: +"Pin the URL to a build sha (7-40 hex chars). The platform rejects a sha missing from a readable build index; when its index cannot be read it echoes the sha back and a pin on a failed build is accepted, so value.buildSha is the platform's claim, not a verified build. extension_release_status lists the builds it knows."
      • addedInput schema / properties / project
        Added value: +{
        +  "description": "Which stored login to use, as '<workspace>/<project>' (or a project slug that matches one login), when extension_auth has signed in to more than one project on this machine. Omitted, the most recent login is used, after EXTENSION_DEV_TOKEN when that is set. Named, it outranks EXTENSION_DEV_TOKEN. extension_auth (action: status) lists the stored logins.",
        +  "type": "string"
        +}
    • Changedextension_release_promote2 fields changed
      • changedInput schema / properties / browsers / description
        Previous value: -"Browsers to release (optional; auto-detected from the build)"New value: +"Browsers to release. Optional: when omitted the platform reads the build's browsers from its index, and falls back to chrome alone when that index cannot be read, so pass them to be sure."
      • addedInput schema / properties / project
        Added value: +{
        +  "description": "Which stored login to use, as '<workspace>/<project>' (or a project slug that matches one login), when extension_auth has signed in to more than one project on this machine. Omitted, the most recent login is used, after EXTENSION_DEV_TOKEN when that is set. Named, it outranks EXTENSION_DEV_TOKEN. extension_auth (action: status) lists the stored logins.",
        +  "type": "string"
        +}
    • Changedextension_reload1 field changed
      • changedInput schema / properties / timeout / description
        Previous value: -"Command timeout in ms (default 5000)"New value: +"Command timeout in ms. When omitted, the default depends on the route: 30000 through the dev session's control channel, 10000 over the Firefox debugger protocol, and 15000 per command over the Chromium debug port."
    • Changedextension_shares2 fields changed
      • addedInput schema / properties / project
        Added value: +{
        +  "description": "Which stored login to use, as '<workspace>/<project>' (or a project slug that matches one login), when extension_auth has signed in to more than one project on this machine. Omitted, the most recent login is used, after EXTENSION_DEV_TOKEN when that is set. Named, it outranks EXTENSION_DEV_TOKEN. extension_auth (action: status) lists the stored logins.",
        +  "type": "string"
        +}
      • changedInput schema / properties / status / description
        Previous value: -"all (default) includes expired and revoked shares, which is what makes a dead link explainable; live returns only links that still resolve."New value: +"all (default) includes expired and revoked shares, which is what makes a dead link explainable; live returns only the links the platform reported resolving at list time (a 429 or 503 from the platform answers listed-local-only, which says nothing about any link)."
    • Changedextension_start4 fields changed
      • changedInput schema / properties / chromiumBinary / description
        Previous value: -"Custom Chromium-based binary (overrides browser)"New value: +"Custom Chromium-based binary to launch; `browser` still names the target family the engine builds for (chromium-based when none is given)."
      • changedInput schema / properties / geckoBinary / description
        Previous value: -"Custom Gecko/Firefox binary (overrides browser)"New value: +"Custom Gecko/Firefox binary to launch; `browser` still names the target family the engine builds for (gecko-based when none is given)."
      • changedInput schema / properties / noBrowser / description
        Previous value: -"Serve without launching a browser"New value: +"Build (or, with build:false, check the dist) without launching a browser. A production start serves nothing, so with no browser the engine process ends once the build does; read the result with extension_build rather than a session."
      • changedInput schema / properties / port / description
        Previous value: -"Server port (0 for auto-assign)"New value: +"Passed to the engine as --port (0 for auto-assign). A production start serves nothing over it today; it matters only to a toolchain that reads it."
    • Changedextension_stop2 fields changed
      • changedInput schema / properties / all / description
        Previous value: -"Stop every known session across projects and browsers, found from this server's registry AND the on-disk markers earlier runs left, so it still works after an MCP restart. It also takes back every live-preview carrier still recorded on this machine, including one in a project whose session was never stopped. projectPath/browser are then ignored."New value: +"Stop every known session across projects and browsers, found from this server's registry AND the on-disk markers written by this server or by servers that are no longer running, so it still works after an MCP restart. A marker owned by another MCP server that is still running is left alone and listed under skippedForeign unless includeOtherServers is true. It also takes back every live-preview carrier still recorded on this machine, including one in a project whose session was never stopped. projectPath/browser are then ignored."
      • addedInput schema / properties / includeOtherServers
        Added value: +{
        +  "default": false,
        +  "description": "With all: true, also stop sessions whose markers belong to another MCP server that is still running (the markers sit in a per-user directory every server shares). Off by default, since those sessions are someone else's.",
        +  "type": "boolean"
        +}
    • Changedextension_storage2 fields changed
      • removedInput schema / properties / context
        Removed value: -{
        -  "default": "background",
        -  "enum": [
        -    "background",
        -    "popup",
        -    "options",
        -    "sidebar",
        -    "content"
        -  ],
        -  "type": "string"
        -}
      • changedInput schema / properties / timeout / description
        Previous value: -"Command timeout in ms (default 5000)"New value: +"Command timeout in ms. When omitted, the default depends on the route: 30000 through the dev session's control channel, 10000 over the Firefox debugger protocol, and 15000 per command over the Chromium debug port."
    • Changedextension_submit1 field changed
      • addedInput schema / properties / project
        Added value: +{
        +  "description": "Which stored login to use, as '<workspace>/<project>' (or a project slug that matches one login), when extension_auth has signed in to more than one project on this machine. Omitted, the most recent login is used, after EXTENSION_DEV_TOKEN when that is set. Named, it outranks EXTENSION_DEV_TOKEN. extension_auth (action: status) lists the stored logins.",
        +  "type": "string"
        +}
  2. 8 tool updatesv10.10.1
    • Changedextension_browsers1 field changed
      • changedInput schema / properties / browsers / items / enum
        Previous value: -[
        -  "chrome",
        -  "chromium",
        -  "edge",
        -  "brave",
        -  "opera",
        -  "vivaldi",
        -  "yandex",
        -  "firefox",
        -  "waterfox",
        -  "librewolf",
        -  "safari"
        -]New value: +[
        +  "chrome",
        +  "chromium",
        +  "edge",
        +  "brave",
        +  "opera",
        +  "vivaldi",
        +  "yandex",
        +  "firefox",
        +  "waterfox",
        +  "librewolf",
        +  "zen",
        +  "floorp",
        +  "safari"
        +]
    • Changedextension_build1 field changed
      • changedInput schema / properties / browser / enum
        Previous value: -[
        -  "chrome",
        -  "chromium",
        -  "edge",
        -  "brave",
        -  "opera",
        -  "vivaldi",
        -  "yandex",
        -  "firefox",
        -  "waterfox",
        -  "librewolf",
        -  "safari",
        -  "chromium-based",
        -  "gecko-based",
        -  "firefox-based",
        -  "webkit-based"
        -]New value: +[
        +  "chrome",
        +  "chromium",
        +  "edge",
        +  "brave",
        +  "opera",
        +  "vivaldi",
        +  "yandex",
        +  "firefox",
        +  "waterfox",
        +  "librewolf",
        +  "zen",
        +  "floorp",
        +  "safari",
        +  "chromium-based",
        +  "gecko-based",
        +  "firefox-based",
        +  "webkit-based"
        +]
    • Changedextension_dev1 field changed
      • changedInput schema / properties / browser / enum
        Previous value: -[
        -  "chrome",
        -  "chromium",
        -  "edge",
        -  "brave",
        -  "opera",
        -  "vivaldi",
        -  "yandex",
        -  "firefox",
        -  "waterfox",
        -  "librewolf",
        -  "safari",
        -  "chromium-based",
        -  "gecko-based",
        -  "firefox-based",
        -  "webkit-based"
        -]New value: +[
        +  "chrome",
        +  "chromium",
        +  "edge",
        +  "brave",
        +  "opera",
        +  "vivaldi",
        +  "yandex",
        +  "firefox",
        +  "waterfox",
        +  "librewolf",
        +  "zen",
        +  "floorp",
        +  "safari",
        +  "chromium-based",
        +  "gecko-based",
        +  "firefox-based",
        +  "webkit-based"
        +]
    • Changedextension_open4 fields changed
      • addedInput schema / properties / panel
        Added value: +{
        +  "description": "For surface 'devtools': the title the extension gave chrome.devtools.panels.create, when it registers more than one panel. Omitted, the extension's first panel is shown.",
        +  "type": "string"
        +}
      • changedInput schema / properties / surface / enum
        Previous value: -[
        -  "popup",
        -  "options",
        -  "sidebar",
        -  "newtab",
        -  "history",
        -  "bookmarks",
        -  "action",
        -  "command"
        -]New value: +[
        +  "popup",
        +  "options",
        +  "sidebar",
        +  "devtools",
        +  "newtab",
        +  "history",
        +  "bookmarks",
        +  "action",
        +  "command"
        +]
      • addedInput schema / properties / tab
        Added value: +{
        +  "description": "With `url`: navigate this chrome.tabs id in place instead of opening a new tab (rides the engine's navigate verb, so the session needs allowControl: true). Without it an existing page is never taken over.",
        +  "type": "number"
        +}
      • changedInput schema / properties / url / description
        Previous value: -"Navigate a real tab here instead of opening a surface (Firefox needs allowEval: true). Use for content-script test pages, or a surface as a page: chrome-extension://<id>/popup.html."New value: +"Navigate a real tab here instead of opening a surface, in a NEW tab unless `tab` names one (a blank or new-tab page is reused). An absolute url opens as given; a path with no scheme, such as pages/options.html, is resolved against the extension's own origin. Use for content-script test pages, or a surface as a page."
    • Changedextension_preview_web2 fields changed
      • changedInput schema / properties / browser / enum
        Previous value: -[
        -  "chrome",
        -  "chromium",
        -  "edge",
        -  "brave",
        -  "opera",
        -  "vivaldi",
        -  "yandex",
        -  "firefox",
        -  "waterfox",
        -  "librewolf",
        -  "safari"
        -]New value: +[
        +  "chrome",
        +  "chromium",
        +  "edge",
        +  "brave",
        +  "opera",
        +  "vivaldi",
        +  "yandex",
        +  "firefox",
        +  "waterfox",
        +  "librewolf",
        +  "zen",
        +  "floorp",
        +  "safari"
        +]
      • changedInput schema / properties / openIn / enum
        Previous value: -[
        -  "chrome",
        -  "chromium",
        -  "edge",
        -  "brave",
        -  "opera",
        -  "vivaldi",
        -  "yandex",
        -  "firefox",
        -  "waterfox",
        -  "librewolf",
        -  "safari"
        -]New value: +[
        +  "chrome",
        +  "chromium",
        +  "edge",
        +  "brave",
        +  "opera",
        +  "vivaldi",
        +  "yandex",
        +  "firefox",
        +  "waterfox",
        +  "librewolf",
        +  "zen",
        +  "floorp",
        +  "safari"
        +]
    • Changedextension_project_create3 fields changed
      • addedInput schema / properties / browsers
        Added value: +{
        +  "default": [
        +    "chrome"
        +  ],
        +  "description": "Browsers the platform builds, each enabled with the same install and build command and its own output directory. Pass every browser the extension targets, for example [\"chrome\", \"edge\", \"firefox\"], so the project needs no console visit to go cross-browser.",
        +  "items": {
        +    "enum": [
        +      "chrome",
        +      "edge",
        +      "firefox"
        +    ],
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedInput schema / properties / outputDirectories
        Added value: +{
        +  "description": "Per-browser output directory overrides, for example {\"edge\": \"build/manifestv3\"}. A browser named here wins over `outputDirectory`.",
        +  "type": "object"
        +}
      • changedInput schema / properties / outputDirectory / description
        Previous value: -"Directory the build writes the loadable extension into."New value: +"Directory the build writes the loadable extension into. With more than one browser, `<browser>` in the path becomes each browser's name (Extension.js writes `dist/<browser>`), and when it is left out every browser defaults to `dist/<browser>`."
    • Changedextension_start2 fields changed
      • changedInput schema / properties / browser / enum
        Previous value: -[
        -  "chrome",
        -  "chromium",
        -  "edge",
        -  "brave",
        -  "opera",
        -  "vivaldi",
        -  "yandex",
        -  "firefox",
        -  "waterfox",
        -  "librewolf",
        -  "safari",
        -  "chromium-based",
        -  "gecko-based",
        -  "firefox-based",
        -  "webkit-based"
        -]New value: +[
        +  "chrome",
        +  "chromium",
        +  "edge",
        +  "brave",
        +  "opera",
        +  "vivaldi",
        +  "yandex",
        +  "firefox",
        +  "waterfox",
        +  "librewolf",
        +  "zen",
        +  "floorp",
        +  "safari",
        +  "chromium-based",
        +  "gecko-based",
        +  "firefox-based",
        +  "webkit-based"
        +]
      • addedInput schema / properties / outputPath
        Added value: +{
        +  "description": "An existing unpacked extension directory to launch as it is (a manifest.json at its root), for an artifact built by another toolchain or an exact release candidate. Implies build:false; projectPath still names the project the session belongs to. Relative paths resolve against projectPath.",
        +  "type": "string"
        +}
    • Addedextension_workspace_create
  3. 1 tool updatev10.9.0
    • Changedextension_preview_web1 field changed
      • changedInput schema / properties / share / description
        Previous value: -"Upload the built dist and return a public link (share.previewUrl) that renders those exact bytes for anyone: no install, sign-in or dev server. It also serves the build as a zip (share.zipUrl), so sharing hands over the code. Needs a token scoped to an extension.dev project (extension_auth or EXTENSION_DEV_TOKEN); without one you get a login hint and the local preview still succeeds. Live until share.expiresAt; DELETE share.revokeUrl to kill it sooner. Revocation is permanent, and re-sharing an unchanged build returns the same link unless it was revoked, so each share is also appended to the project's gitignored .extension.dev/shared-previews.json."New value: +"Upload the built dist and return a public link (share.previewUrl) that renders those exact bytes for anyone: no install, sign-in or dev server. Uploading runs on extension.dev's machines and counts against your free allowance; left false, the result's share property says what the local deepLink needs, what share:true spends, and the exact call to get a shareable link. It also serves the build as a zip (share.zipUrl), so sharing hands over the code. Needs a token scoped to an extension.dev project (extension_auth or EXTENSION_DEV_TOKEN); without one you get a login hint and the local preview still succeeds. Live until share.expiresAt; DELETE share.revokeUrl to kill it sooner. Revocation is permanent, and re-sharing an unchanged build returns the same link unless it was revoked, so each share is also appended to the project's gitignored .extension.dev/shared-previews.json."
  4. 5 tool updatesv10.8.0
    • Addedextension_assert
    • Addedextension_project_create
    • Changedextension_release_promote1 field changed
      • addedInput schema / properties / approvalId
        Added value: +{
        +  "description": "The approval handle returned by a prior approval-required response. Promoting changes what a public channel serves and is not reversible in place, so when the platform's approval gate is on this needs a human approval: call once without this to get an approval id and URL, have a human approve at extension.dev, then call again with the same id.",
        +  "type": "string"
        +}
    • Changedextension_shares1 field changed
      • addedInput schema / properties / approvalId
        Added value: +{
        +  "description": "The approval handle returned by a prior approval-required response for a revoke. Revoking permanently burns a share and cannot be undone, so when the platform's approval gate is on this needs a human approval: call revoke once without this to get an approval id and URL, have a human approve at extension.dev, then call revoke again with the same id. Listing never needs it.",
        +  "type": "string"
        +}
    • Changedextension_submit1 field changed
      • addedInput schema / properties / approvalId
        Added value: +{
        +  "description": "The approval handle returned by a prior approval-required response for a real submission. A real submission (dryRun:false) is irreversible and needs a human approval when the platform's approval gate is on: call once without this to get an approval id and URL, have a human approve at extension.dev, then call again with the same id. A dry run never needs it.",
        +  "type": "string"
        +}
  5. 2 tool updatesv10.3.1
    • Changedextension_auth1 field changed
      • changedInput schema / properties / project / description
        Previous value: -"login: target project as '<workspace>/<project>'; the token is scoped to it."New value: +"login: target project as '<workspace>/<project>'; the token is scoped to it. The slug pair is the console address bar: an existing project's page is console.extension.dev/<workspace>/<project>. Create one at extension.dev/new if none exists yet."
    • Changedextension_build1 field changed
      • changedInput schema / properties / bundleId / description
        Previous value: -"Safari targets only: a reverse-DNS bundle identifier you own, such as com.acme.readinglist. Without one the app is packaged under a generated dev.extensionjs.* identifier that Apple will not accept for distribution."New value: +"Safari targets only: a reverse-DNS bundle identifier you own, such as com.acme.readinglist. Without one the app is packaged under a generated dev.extensionjs.* identifier derived from the app name, which every project built from the same template shares, and the first team to register it takes it."
  6. 28 tool updatesv10.1.0
    • First observedextension_add_feature
    • First observedextension_analyze
    • First observedextension_auth
    • First observedextension_browsers
    • First observedextension_build
    • First observedextension_create
    • First observedextension_dev
    • First observedextension_doctor
    • First observedextension_dom_snapshot
    • First observedextension_eval
    • First observedextension_inspect
    • First observedextension_list_extensions
    • First observedextension_logs
    • First observedextension_manifest_validate
    • First observedextension_open
    • First observedextension_preview_web
    • First observedextension_publish
    • First observedextension_release_promote
    • First observedextension_release_status
    • First observedextension_reload
    • First observedextension_shares
    • First observedextension_start
    • First observedextension_stop
    • First observedextension_storage
    • First observedextension_submit
    • First observedextension_templates
    • First observedextension_theme_verify
    • First observedextension_wait

TDQS

A4.2/5.0

Scored across 32 tools

Disambiguation4/5

There is heavy surface overlap between extension_build/extension_dev/extension_start/extension_preview_web and between extension_inspect/extension_dom_snapshot/extension_eval, but the descriptions explicitly delineate each (e.g. 'ONLY this tool pierces closed shadow roots', 'use extension_dom_snapshot to choose which tab'). An agent can generally pick correctly, though the sheer density of cross-references makes misselection plausible.

Naming Consistency5/5

Every tool uses the extension_ prefix with snake_case, and most follow a predictable verb or verb_noun shape (extension_build, extension_create, extension_release_promote, extension_manifest_validate). A few noun-only names (extension_templates, extension_browsers, extension_shares) are exceptions but consistent within their purpose.

Tool Count3/5

At 32 tools the set is heavy, exceeding the 25-tool 'too many' threshold, though the domain (full extension lifecycle: scaffold, build, dev, inspect, publish, store submit, auth, releases) is genuinely broad so most tools earn their place. It still leans toward being a lot of surface for an agent to navigate.

Completeness5/5

The surface covers the whole lifecycle: templating, scaffolding, build, dev/start/preview sessions, inspection, eval, storage, reload, stop, auth, workspace/project creation, publish, release promotion/status, store submission, manifest validation, diagnoses, and docs. No obvious dead ends or missing lifecycle operations.

Maintenance

ActivityActive
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to control the Google Chrome browser through a Node.js WebSocket bridge and a dedicated browser extension. It provides tools for capturing screenshots, executing JavaScript, managing tabs, and extracting page content via the MCP protocol.
    2
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to control and interact with a Chrome browser via MCP, providing tools for navigation, screenshots, clicking, form filling, content extraction, and tab management.
    -
  • F
    license
    Not graded
    quality
    B
    maintenance
    Exposes your Chrome/Edge browser as MCP tools for AI agents, enabling browser automation through a Chrome extension with 47 tools for navigation, interaction, page reading, and more.
    12 npm
    -