@extension.dev/mcp 10.10.1 → 10.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +214 -0
  4. package/README.md +29 -4
  5. package/bin/extension-mcp.js +14 -4
  6. package/claude/CLAUDE.md +2 -1
  7. package/dist/module.d.ts +1 -0
  8. package/dist/module.js +2194 -264
  9. package/dist/src/index.d.ts +3 -2
  10. package/dist/src/lib/approval-gate.d.ts +5 -1
  11. package/dist/src/lib/artifacts-api.d.ts +1 -0
  12. package/dist/src/lib/bridge-tabs.d.ts +8 -1
  13. package/dist/src/lib/cdp-devtools.d.ts +27 -0
  14. package/dist/src/lib/cdp-extension-page.d.ts +18 -0
  15. package/dist/src/lib/cdp-targets.d.ts +7 -0
  16. package/dist/src/lib/cdp.d.ts +2 -0
  17. package/dist/src/lib/common-schema.d.ts +3 -3
  18. package/dist/src/lib/credentials.d.ts +24 -3
  19. package/dist/src/lib/device-flow.d.ts +6 -3
  20. package/dist/src/lib/envelope.d.ts +1 -1
  21. package/dist/src/lib/exec.d.ts +1 -0
  22. package/dist/src/lib/publish.d.ts +3 -1
  23. package/dist/src/lib/registry.d.ts +1 -0
  24. package/dist/src/lib/session-browser.d.ts +1 -1
  25. package/dist/src/lib/session-paths.d.ts +10 -1
  26. package/dist/src/lib/tool-policy.d.ts +33 -0
  27. package/dist/src/tools/browsers.d.ts +1 -1
  28. package/dist/src/tools/build.d.ts +1 -1
  29. package/dist/src/tools/detect-browsers.d.ts +2 -0
  30. package/dist/src/tools/dev.d.ts +1 -1
  31. package/dist/src/tools/eval.d.ts +2 -0
  32. package/dist/src/tools/inspect-gecko.d.ts +1 -0
  33. package/dist/src/tools/logout.d.ts +1 -1
  34. package/dist/src/tools/open.d.ts +25 -1
  35. package/dist/src/tools/preview-web.d.ts +7 -2
  36. package/dist/src/tools/project-create.d.ts +15 -0
  37. package/dist/src/tools/publish.d.ts +5 -0
  38. package/dist/src/tools/release-promote.d.ts +5 -0
  39. package/dist/src/tools/shares.d.ts +5 -0
  40. package/dist/src/tools/start.d.ts +6 -1
  41. package/dist/src/tools/submit.d.ts +5 -0
  42. package/dist/src/tools/workspace-create.d.ts +42 -0
  43. package/package.json +18 -13
  44. package/server.json +3 -3
@@ -10,7 +10,7 @@
10
10
  "name": "extension-mcp",
11
11
  "source": "./",
12
12
  "description": "MCP tools for browser extension development: scaffold from 50+ templates, run the dev server with HMR, inspect the live DOM and logs, and publish store-ready builds for Chrome, Edge, and Firefox.",
13
- "version": "10.10.1",
13
+ "version": "10.10.3",
14
14
  "category": "development",
15
15
  "author": {
16
16
  "name": "Cezar Augusto"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "extension-mcp",
3
3
  "description": "MCP tools for browser extension development: scaffold from 50+ templates, run the dev server with HMR, inspect the live DOM and logs, and publish store-ready builds for Chrome, Edge, and Firefox. Ships /extension, /extension-add, /extension-debug, and /extension-publish commands.",
4
- "version": "10.10.1",
4
+ "version": "10.10.3",
5
5
  "author": {
6
6
  "name": "Cezar Augusto",
7
7
  "email": "hello@extension.dev",
package/CHANGELOG.md CHANGED
@@ -1,5 +1,219 @@
1
1
  # Changelog
2
2
 
3
+ ## 10.10.3
4
+
5
+ - The engine pin moves off the canary to Extension.js `4.1.31` stable:
6
+ `extension_dev`, `extension_start` and `extension_build` spawn that
7
+ release when a project has no engine of its own, and the nightly
8
+ engine-pin check reads it against `latest` again.
9
+
10
+ - A human now approves a real store submission and a promotion to stable
11
+ before either runs, by default. The first call answers
12
+ `approval-required` with an `approvalUrl` on extension.dev
13
+ (`/device/approve/<id>`) and an `approvalId`; once a workspace member
14
+ approves (an owner, for a submission), the same call with that
15
+ `approvalId` runs exactly that action, once. Promotions to other channels
16
+ and share revokes stay ungated unless `EXTENSION_DEV_APPROVAL_GATE=1`;
17
+ `EXTENSION_DEV_APPROVAL_GATE=0` turns the default off. Whatever the
18
+ setting, a platform that answers `APPROVAL_REQUIRED` now gets the same
19
+ approval flow instead of a bare failure.
20
+
21
+ - Two server flags narrow what an agent can reach. `--features=local`
22
+ or `--features=platform` (env `EXTENSION_DEV_FEATURES`) lists one tool
23
+ group; `local` alone is about 40% smaller. `--no-ship` (env
24
+ `EXTENSION_DEV_NO_SHIP`) hides `extension_publish` and
25
+ `extension_release_promote` and refuses a real submit, a share link and
26
+ a share revoke, while dry runs and listing keep working. A refused call
27
+ answers the new code `E_TOOL_DISABLED` with the flag to change. Both
28
+ default to everything on, so no existing setup changes.
29
+ - Every tool now carries MCP annotations (`readOnlyHint`,
30
+ `destructiveHint`, `idempotentHint`, `openWorldHint`) from one policy
31
+ table, so clients can auto-approve reads and ask before the rest. A
32
+ merged tool takes its worst action: `extension_shares` is destructive
33
+ because revoke is.
34
+ - A device-flow step waiting on a human (`extension_auth` login,
35
+ `extension_project_create`, `extension_workspace_create`) now answers
36
+ `ok: true` with `status: "authorization-pending"` and no error, instead
37
+ of `ok: false` with `E_AUTH_PENDING`, so clients stop rendering the
38
+ first login step as a failure. The approval link and code stay in
39
+ `hint` and `value`; `E_AUTH_PENDING` is retired.
40
+
41
+ ## 10.10.2
42
+
43
+ - The engine pin moves to the Extension.js canary
44
+ `4.1.31-canary.1791055414.4bbb683a` (ruled 2026-10-01, refreshed
45
+ 2026-10-03 when the canary moved on): `extension_dev`,
46
+ `extension_start` and `extension_build` spawn that build when a project
47
+ has no engine of its own, and the nightly engine-pin check now reads a
48
+ canary pin against the canary dist-tag instead of latest. The canary's
49
+ log query treats level `off` as none (it was a synonym for all), which
50
+ changes nothing for `extension_logs`, whose `off` stays "signals only".
51
+ The canary also adopts a project root only when it owns the manifest
52
+ (same folder, the `src/manifest.json` layout, a dependency on
53
+ Extension.js, or an `extension.config.*` beside it) and otherwise builds
54
+ into the manifest's own folder; the session artifact resolver here
55
+ applies the same four tests, so `extension_wait` and `extension_logs`
56
+ keep reading the ready.json the engine writes.
57
+ - Logins to several projects now live side by side in `auth.json`, one
58
+ entry per workspace/project with the latest marked active, instead of
59
+ one slot the next login overwrote. `extension_publish`,
60
+ `extension_release_promote`, `extension_submit`, `extension_shares` and
61
+ `extension_preview_web` take `project` ('<workspace>/<project>', or a
62
+ project slug that matches one login) to pick a stored login, which
63
+ outranks `EXTENSION_DEV_TOKEN`; omitted, the order stays environment
64
+ first, then the active login. `extension_auth` status lists every login
65
+ under `logins`, and logout with `project` removes just that one. A
66
+ version 1 file is read as a store of one and rewritten on the next login
67
+ (BUGS_TO_FIX_MCP.md entry 36).
68
+ - Four findings from the six-browser sweep (BUGS_TO_FIX_MCP.md entries 40
69
+ to 43): `extension_open` reads new headless off the `User-Agent` field
70
+ of `/json/version` as well (`--headless=new` keeps `Chrome/151` in the
71
+ `Browser` field) and, whatever the launch flags said, falls back to the
72
+ tab route on any window refusal: Chromium's gesture refusal for a popup,
73
+ an options or popup window the engine called opened but no document
74
+ appeared for within 3 s, and Gecko's "Popup is disabled"; a Gecko
75
+ browser that gets Chromium's gesture sentence (the engine counts every
76
+ non-Firefox name as Chromium, extension.js ledger 642) is answered with
77
+ Gecko wording; and when the background refuses the `runtime.getURL` eval
78
+ the tab route needs (an extension CSP that forbids eval), the
79
+ `moz-extension://` base is read off the profile's
80
+ `extensions.webextensions.uuids` pref through the add-on id the built
81
+ manifest declares, so the fallback still lands (40). `extension_eval` context `background` wakes an idle
82
+ MV3 worker through `ServiceWorker.startWorker` from a page session
83
+ before evaluating, with a warning that it was idle, instead of answering
84
+ `E_NO_TARGET` (41). `extension_open surface: "devtools"` takes `waitMs`
85
+ and `reload` (reload the inspected tab once DevTools is open, for
86
+ extensions that create their panel when the page reports to them) and
87
+ the missing-panel hint names both (42). A page eval the PAGE's CSP
88
+ refuses on a Gecko MV2 build is re-run through `tabs.executeScript`, the
89
+ same wrapper the no-scripting-API case uses (43); an MV3 Gecko build
90
+ keeps the policy explanation, pending engine ledger 560.
91
+ - `extension_eval` over CDP awaits a promise-valued expression again. The
92
+ CDP routes added for entries 29 and 31 passed `replMode` on every
93
+ `Runtime.evaluate`, and Chrome 151 answers a replMode evaluate with the
94
+ promise object itself, ignoring `awaitPromise`, so `Promise.resolve(42)`,
95
+ an async IIFE or `chrome.tabs.query({}).then(...)` read as `{}` with
96
+ `ok: true` on pages and workers alike. The evaluate now runs without
97
+ replMode, and only an expression Chrome refuses for a top-level `await`
98
+ is re-run in replMode with the promise settled through
99
+ `Runtime.awaitPromise` (BUGS_TO_FIX_MCP.md entry 39, a regression of
100
+ 10.10.2's own, never released).
101
+ - `extension_open` takes `surface: "devtools"` on Chromium: it opens the
102
+ browser's real DevTools on a tab (the one `url` matches, else the first
103
+ web page) through CDP `Target.openDevTools`, waits for the extension's
104
+ `devtools_page` to register its panel, shows it (`panel` picks a title
105
+ when there are several) and hands back the panel document's url, which
106
+ `extension_eval` reads with context `page` and that url, with
107
+ `chrome.devtools` available. Context `devtools` on `extension_eval` now
108
+ evaluates over CDP on an MV3 session like the other surfaces, and an
109
+ extension document lookup matches the iframe targets a DevTools panel
110
+ and its devtools page are. Works headed or headless (measured Chrome
111
+ 151). Gecko gets a refusal that says no protocol opens its developer
112
+ tools (BUGS_TO_FIX_MCP.md entry 38).
113
+ - `zen` and `floorp` join the browser enum of `extension_dev`,
114
+ `extension_start` and friends, the Gecko family, `extension_browsers`
115
+ detection (app bundles, Linux and Windows paths) and the process match
116
+ `extension_stop` uses, the same way waterfox is listed; the engine has
117
+ launched both since 4.1.26 (entry 37).
118
+ - The dependency floors move past every advisory `pnpm audit` reported on
119
+ 2026-09-30 (42: 18 high, 22 moderate, 2 low, all transitive): axios,
120
+ brace-expansion, fast-uri, js-yaml, nanoid, devalue, hono, ip-address,
121
+ qs and postcss-selector-parser through `pnpm.overrides`, vitest to 4.1.11
122
+ as a dev dependency. The audit reads zero; nothing the server does
123
+ changes.
124
+ - The bundled template catalog moves to the corpus at `2c3a486a`, which
125
+ renamed the `new-*` examples to `newtab-*` and added the `devtools-*`
126
+ family and `sidebar-monorepo-nx`. `extension_add_feature`'s newtab row
127
+ now names `newtab`, `newtab-react`, `newtab-vue`, `newtab-svelte` and
128
+ `newtab-preact`; the catalog-sync PR had failed on the old names every
129
+ day since 2026-09-26 (BUGS_TO_FIX_MCP.md entry 14).
130
+
131
+ Nine findings from a session that brought ten third-party extensions under
132
+ the server in one day (BUGS_TO_FIX_MCP.md entries 15 to 27; the ones this
133
+ release closes are 16 to 19 and 21 to 25):
134
+
135
+ - `extension_dev` and `extension_start` spawn the engine in the project
136
+ directory, not where the MCP client started the server, so the engine a
137
+ session drives is the project's own and the started envelope names it
138
+ under `value.engine` (entry 25).
139
+ - Every session artifact path (ready.json, logs, the build summary) now
140
+ resolves from the engine's project root, the nearest package.json,
141
+ deno.json or deno.jsonc at or above the manifest, so a project whose
142
+ manifest sits in a subfolder no longer makes `extension_wait` watch a
143
+ contract the engine never writes (entry 23).
144
+ - A failed `extension_build` carries the compiler errors the engine stamped
145
+ on its contract under `value.errors`, or the bundler's own output under
146
+ `value.output`, and its hint no longer asserts a manifest location the
147
+ engine does not require (entry 16).
148
+ - `extension_wait` on an `extension_start` session answers `launched` at
149
+ once with the production-build guidance instead of spending its budget on
150
+ a "transient" `E_NOT_ATTACHED` that is permanent there; a clamped budget
151
+ is reported in `warnings` on every exit; and a dead-contract note names
152
+ only the browser the call asked about (entry 18).
153
+ - `extension_eval` names the extension's own content security policy when
154
+ the engine refuses with "call to eval() blocked by CSP", instead of
155
+ blaming the expression (entry 19), and on MV2 Gecko a page or content
156
+ eval goes through `tabs.executeScript` from the background when the
157
+ engine has no scripting API, with the content-world caveat stated
158
+ (entry 24).
159
+ - `extension_open` with a `url` opens a new tab unless `tab` names one, so
160
+ a page under test is never taken over; a path with no scheme resolves
161
+ against the extension's own origin on Chromium and Gecko (entry 21).
162
+ - `extension_manifest_validate` reads `public/` when resolving manifest
163
+ references, warns rather than blocks on a missing web-accessible resource
164
+ and on a Chromium-only side panel, counts `devtools_page` and options
165
+ pages when ranking similar templates and ranks by surface overlap ratio,
166
+ and on Firefox warns on a missing `browser_specific_settings.gecko.id`,
167
+ on Chromium-only keys and on `extension_ids`, and gives an MV2 manifest
168
+ the keys to port for MV3 (entries 17 and 22).
169
+ - `extension_start` takes `outputPath`, an existing unpacked extension
170
+ directory to launch as it is through the engine's preview verb, so an
171
+ artifact another toolchain produced, or the exact release candidate, can
172
+ be run and watched without an Extension.js build (entry 26). A directory
173
+ with no manifest.json is refused before anything launches.
174
+ - `extension_manifest_validate` warns on Firefox when
175
+ `browser_specific_settings.gecko.data_collection_permissions` is missing,
176
+ which AMO now requires for new add-ons, and shows the minimal form.
177
+
178
+ Seven more from the same session's functional sweep (entries 29 to 35):
179
+
180
+ - `extension_eval` reaches the Chromium background over CDP: the MV3 service
181
+ worker or MV2 background page is a target of its own, and evaluating on it
182
+ is the inspector path the extension's content security policy does not
183
+ govern, so state only the worker knows is readable again under
184
+ `script-src 'self'`. An idle worker with no target answers `E_NO_TARGET`
185
+ with how to wake it (entry 29).
186
+ - `extension_eval` with context `page` and a url evaluates on the matching
187
+ tab's CDP target, so a site that enforces Trusted Types (YouTube, Gmail)
188
+ no longer refuses the string; the active-tab refusal names Trusted Types
189
+ and the url route (entry 31). Every CDP route falls back to the in-bundle
190
+ relay when the session has no debug port.
191
+ - `extension_open` asks the browser whether it is headless (HeadlessChrome
192
+ names itself) and renders popup, options and sidebar as a tab at once
193
+ when it is, instead of opening a popup that is gone before the next call
194
+ (entry 32). A page the browser swapped for its own error page answers
195
+ `navigate-blocked` with the browser's title instead of `navigated`, and
196
+ eval refuses such a tab (entry 35).
197
+ - `extension_browsers` reports the newest managed version when several sit
198
+ in the cache, the one the engine launches (entry 30).
199
+ - `extension_inspect` probes on Gecko return the same shape as on Chromium,
200
+ `{selector, count, samples[]}` with a text snippet per element
201
+ (entry 34).
202
+ - `extension_assert` on Gecko reads `background-worker-booted` off the
203
+ control channel (the bridge executor runs in the background) and
204
+ `surface-rendered` off the surface relay, instead of answering
205
+ inconclusive for want of a CDP target list; a selector clause stays
206
+ inconclusive there and names the tool that probes it (entry 33).
207
+
208
+ - `@extension.dev/urls` moves to `^0.8.1`, which reserves `chromium`,
209
+ `firefox`, `mcp` and `skill` as mint slugs.
210
+ - `extension_browsers` install hands the canary's installer the server's
211
+ own managed-binary search as `locateInstalledBinary`, which that
212
+ installer now requires to verify an install before it reports success.
213
+ - The stored login reader no longer types a missing entry as `undefined`
214
+ where it promises `null`, so consumers that compile the server's source
215
+ under `noUncheckedIndexedAccess` typecheck it.
216
+
3
217
  ## 10.10.1
4
218
 
5
219
  Five Gecko findings from one agent session on Firefox and Waterfox
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  # @extension.dev/mcp [![Version][npm-version-image]][npm-version-url] [![Downloads][npm-downloads-image]][npm-downloads-url] [![Discord][discord-image]][discord-url]
9
9
 
10
- > Give your AI agent hands for browser extension development. 30 MCP tools that scaffold, run, inspect, debug, and publish cross-browser extensions.
10
+ > Give your AI agent hands for browser extension development. 31 MCP tools that scaffold, run, inspect, debug, and publish cross-browser extensions.
11
11
 
12
12
  <img alt="Logo" align="right" src="https://media.extension.land/brand/extension-dev/logo-dock.png" width="20.7%" />
13
13
 
@@ -26,7 +26,7 @@ Extensions fail silently: content scripts that never inject, panels that never o
26
26
  These tools give agents eyes on the live browser, so they debug from evidence instead of guessing:
27
27
 
28
28
  - **Scaffold** from the 50+ template catalog behind [templates.extension.dev](https://templates.extension.dev), or add a popup, sidebar, or content script to an existing project
29
- - **Run** the dev server with HMR in Chrome, Edge, Firefox, Brave, Opera, Vivaldi, Yandex, Waterfox, LibreWolf, or any Chromium- or Gecko-based binary, plus Safari on macOS (no HMR yet), no build config
29
+ - **Run** the dev server with HMR in Chrome, Edge, Firefox, Brave, Opera, Vivaldi, Yandex, Waterfox, LibreWolf, Zen, Floorp, or any Chromium- or Gecko-based binary, plus Safari on macOS (no HMR yet), no build config
30
30
  - **See** the live DOM, unified logs from every extension context, `chrome.storage` contents, and the loaded-extension list
31
31
  - **Act**: evaluate code in any context, trigger the action button and commands, reload the extension, replay events
32
32
  - **Ship**: validate the manifest cross-browser, build for production, publish a shareable preview, and promote builds to release channels headlessly
@@ -75,6 +75,30 @@ Or install it as a plugin, the MCP server plus the `/extension`, `/extension-add
75
75
  }
76
76
  ```
77
77
 
78
+ ### Choosing what the agent can reach
79
+
80
+ Two flags (or environment variables) narrow the server before an agent sees it:
81
+
82
+ - `--features=local` exposes only the tools that work on this machine (create, run, inspect, build), which also cuts the tool list by about 40%. `--features=platform` exposes only the extension.dev account, share, release and store tools. Both are on by default. Env: `EXTENSION_DEV_FEATURES`.
83
+ - `--no-ship` keeps everything that stays on this machine and refuses every call that reaches other people: `extension_publish`, `extension_release_promote`, `extension_submit` with `dryRun: false`, `extension_preview_web` with `share: true`, and a share revoke. Dry runs and share listing still work. Env: `EXTENSION_DEV_NO_SHIP=1`.
84
+
85
+ A refused call answers `E_TOOL_DISABLED` with the flag to change.
86
+
87
+ A real store submission and a promotion to stable also wait for a person by default: the first call answers `approval-required` with a link on extension.dev, a workspace member approves exactly that action, and the same call with the returned `approvalId` runs it once. `EXTENSION_DEV_APPROVAL_GATE=1` extends this to every promotion and share revoke; `EXTENSION_DEV_APPROVAL_GATE=0` turns it off.
88
+
89
+ Every tool also carries MCP annotations (`readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`), so clients can auto-approve reads and ask before the rest.
90
+
91
+ ```json
92
+ {
93
+ "mcpServers": {
94
+ "extension-dev": {
95
+ "command": "npx",
96
+ "args": ["@extension.dev/mcp", "--no-ship"]
97
+ }
98
+ }
99
+ }
100
+ ```
101
+
78
102
  ### Pair with the skill
79
103
 
80
104
  This server gives agents hands; [`@extension.dev/skill`](https://www.npmjs.com/package/@extension.dev/skill) gives them judgment: the cross-browser rules, silent-failure gotchas, debugging playbooks, and store checklist, packaged in the open [Agent Skills](https://agentskills.io) format. With both installed, agents know to verify against the live browser instead of guessing, and these tools make that a one-call operation.
@@ -106,7 +130,7 @@ cp node_modules/@extension.dev/mcp/claude/commands/*.md ~/my-extension/.claude/c
106
130
  | build | `extension_add_feature` | Add sidebar/popup/content script |
107
131
  | build | `extension_build` | Build for production |
108
132
  | run | `extension_dev` | Dev server with HMR |
109
- | run | `extension_start` | Build + launch the production build (`build: false` launches the existing dist) |
133
+ | run | `extension_start` | Build + launch the production build (`build: false` launches the existing dist; `outputPath` launches any prebuilt unpacked directory) |
110
134
  | run | `extension_wait` | Poll the dev-server ready contract |
111
135
  | run | `extension_stop` | Stop a dev/start/preview session (server + browser) |
112
136
  | see | `extension_manifest_validate` | Cross-browser manifest validation |
@@ -121,9 +145,10 @@ cp node_modules/@extension.dev/mcp/claude/commands/*.md ~/my-extension/.claude/c
121
145
  | act | `extension_eval` | Evaluate in a context (needs `allowEval: true` on `extension_dev`) |
122
146
  | act | `extension_storage` | Read/write `chrome.storage` |
123
147
  | act | `extension_reload` | Reload extension or tab |
124
- | act | `extension_open` | Open a surface / trigger `action`, `command` |
148
+ | act | `extension_open` | Open a surface (popup, options, sidebar, devtools panel, override pages) / trigger `action`, `command` |
125
149
  | browsers | `extension_browsers` | Detect, list, install, and uninstall browsers |
126
150
  | platform | `extension_auth` | Device login at extension.dev, plus login status and logout |
151
+ | platform | `extension_workspace_create` | Create an extension.dev workspace, headless, via device approval; the approver becomes its owner |
127
152
  | platform | `extension_project_create` | Create the extension.dev project for a built extension, headless, via device approval |
128
153
  | platform | `extension_preview_web` | Render a build in the web emulator, and share it as a link |
129
154
  | platform | `extension_shares` | List every link you have shared, and revoke one permanently |
@@ -8,7 +8,7 @@
8
8
  // Apache License 2.0 (c) 2026 Cezar Augusto and the extension.dev collaborators
9
9
 
10
10
  import {createRequire} from 'node:module'
11
- import {startServer, runCli} from '../dist/module.js'
11
+ import {startServer, runCli, isServerFlag, resolveServerOptions} from '../dist/module.js'
12
12
 
13
13
  const require = createRequire(import.meta.url)
14
14
  const {version} = require('../package.json')
@@ -16,18 +16,28 @@ const {version} = require('../package.json')
16
16
  const usage = `@extension.dev/mcp ${version}
17
17
 
18
18
  Usage:
19
- extension-mcp Start the MCP server on stdio
19
+ extension-mcp [flags] Start the MCP server on stdio
20
20
  extension-mcp login [flags] Device login at extension.dev
21
21
  extension-mcp logout Remove the stored credentials
22
22
  extension-mcp whoami Show the stored identity
23
23
  extension-mcp release [...] Headless release commands
24
24
  extension-mcp --version Print the version
25
+
26
+ Server flags:
27
+ --features=local,platform Tool groups to expose (default: both)
28
+ --no-ship Refuse publish, promote, real submits,
29
+ share links and share revokes
25
30
  `
26
31
 
27
32
  const [, , cmd, ...rest] = process.argv
28
33
 
29
- if (cmd === undefined) {
30
- startServer()
34
+ if (cmd === undefined || isServerFlag(cmd)) {
35
+ const resolved = resolveServerOptions(process.argv.slice(2), process.env)
36
+ if (!resolved.ok) {
37
+ process.stderr.write(`${resolved.message}\n\n${usage}`)
38
+ process.exit(1)
39
+ }
40
+ startServer(resolved.options)
31
41
  } else if (['login', 'logout', 'whoami', 'release'].includes(cmd)) {
32
42
  runCli(cmd, rest)
33
43
  .then((code) => process.exit(code))
package/claude/CLAUDE.md CHANGED
@@ -26,7 +26,8 @@ The extension.dev platform ships 50+ templates in the [examples](https://github.
26
26
  | Content script | `content` | `content-react` | `content-vue` | `content-svelte` | n/a |
27
27
  | Sidebar | `sidebar` | `sidebar-shadcn` | n/a | n/a | `ai-claude` |
28
28
  | Action popup | `action` | n/a | n/a | n/a | `ai-chatgpt` |
29
- | New tab | `new` | `new-react` | `new-vue` | `new-svelte` | n/a |
29
+ | New tab | `newtab` | `newtab-react` | `newtab-vue` | `newtab-svelte` | n/a |
30
+ | DevTools | `devtools` | `devtools-react` | `devtools-vue`| `devtools-svelte`| n/a |
30
31
  | Full framework | `javascript` | `react` | `vue` | `svelte` | n/a |
31
32
 
32
33
  **When recommending a template:**
package/dist/module.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export { startServer, runCli, version } from "./src/index";
2
+ export { isServerFlag, resolveServerOptions } from "./src/lib/tool-policy";