@extension.dev/mcp 10.10.10 → 10.10.12
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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +44 -0
- package/README.md +2 -2
- package/claude/rules/mcp-tools.md +9 -9
- package/dist/module.js +470 -87
- package/dist/src/lib/artifacts-api.d.ts +1 -0
- package/dist/src/lib/cdp-devtools.d.ts +4 -0
- package/dist/src/lib/cdp-extension-page.d.ts +12 -0
- package/dist/src/lib/common-schema.d.ts +1 -1
- package/dist/src/lib/exec.d.ts +1 -0
- package/dist/src/lib/process-identity.d.ts +6 -0
- package/dist/src/lib/process-manager.d.ts +1 -1
- package/dist/src/lib/registry.d.ts +3 -0
- package/dist/src/tools/assert.d.ts +1 -1
- package/dist/src/tools/dom-snapshot.d.ts +1 -1
- package/dist/src/tools/eval.d.ts +1 -1
- package/dist/src/tools/inspect-gecko.d.ts +1 -0
- package/dist/src/tools/logs-filter.d.ts +1 -0
- package/dist/src/tools/open.d.ts +1 -1
- package/dist/src/tools/reload.d.ts +1 -1
- package/dist/src/tools/stop.d.ts +1 -0
- package/dist/src/tools/storage.d.ts +1 -1
- package/package.json +7 -3
- package/server.json +2 -2
|
@@ -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.
|
|
13
|
+
"version": "10.10.12",
|
|
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.
|
|
4
|
+
"version": "10.10.12",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cezar Augusto",
|
|
7
7
|
"email": "hello@extension.dev",
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,49 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 10.10.12
|
|
4
|
+
|
|
5
|
+
- `extension_stop` on Windows reads the Windows process table to find what
|
|
6
|
+
is left of a session, so a stop that ended the whole tree says
|
|
7
|
+
`stopped` instead of "survivors were not verified". Before this, every
|
|
8
|
+
Windows stop answered `stopped: false`, and `extension_dev` with
|
|
9
|
+
`replace: true` refused every time. A stop still says unverified when
|
|
10
|
+
the table cannot be read. Measured on a Windows runner.
|
|
11
|
+
- The lockfile raises `proxy-addr`, `source-map-js` and Vue past their
|
|
12
|
+
open advisories.
|
|
13
|
+
|
|
14
|
+
## 10.10.11
|
|
15
|
+
|
|
16
|
+
The rest of the 2026-10-05 audit ledger, apart from the Safari WebDriver
|
|
17
|
+
fields that wait on the engine (entry 110h, Extension.js BUGS_TO_FIX 905).
|
|
18
|
+
|
|
19
|
+
- `extension_eval` says where it ran and what came back: the tab's url and
|
|
20
|
+
title on Firefox, a note when the value was not serializable, only real
|
|
21
|
+
background targets as the background, and `eval-lost` or
|
|
22
|
+
`eval-unsupported` when the answer never arrived. A woken worker is no
|
|
23
|
+
longer said to have idled when it may never have started.
|
|
24
|
+
- `extension_logs` and `extension_assert` report a cut stream: a follow
|
|
25
|
+
that closed early is a partial read, dropped-line markers are not
|
|
26
|
+
counted as events, and console-errors-empty is inconclusive when lines
|
|
27
|
+
were dropped. An unknown console `context` is refused as a bad request
|
|
28
|
+
instead of failing the whole call.
|
|
29
|
+
- `extension_wait` and `extension_start` report only what they observed:
|
|
30
|
+
a start session is `build-ready`, a build contract or a stopped session
|
|
31
|
+
is `no-session`, and start refuses Safari and preview-path hosts it
|
|
32
|
+
cannot serve.
|
|
33
|
+
- `extension_open` names the DevTools panel frame that appeared, and says
|
|
34
|
+
when the panel registry could not be read or the target was inferred.
|
|
35
|
+
- Platform answers of the wrong shape (channels, build index, shares,
|
|
36
|
+
login config) are unreadable, never empty, and an unpinned publish
|
|
37
|
+
matches the build the platform named.
|
|
38
|
+
- `extension_stop` counts a process as reaped only once it is gone, and
|
|
39
|
+
ends a Windows session through `taskkill /T /F`. A session marker that
|
|
40
|
+
could not be written is a warning on the started answer, and the
|
|
41
|
+
`release promote` command exits non-zero on an answer it cannot read.
|
|
42
|
+
- `extension_list_extensions` on Firefox marks a lone temporary add-on as
|
|
43
|
+
an inferred match.
|
|
44
|
+
- The scheduled test tier builds through the real pinned engine with
|
|
45
|
+
`--output json` and checks the fixtures against what it writes.
|
|
46
|
+
|
|
3
47
|
## 10.10.10
|
|
4
48
|
|
|
5
49
|
Every sentence the server says is now backed by something it read
|
package/README.md
CHANGED
|
@@ -151,7 +151,7 @@ Two flags (or environment variables) narrow the server before an agent sees it:
|
|
|
151
151
|
|
|
152
152
|
A refused call answers `E_TOOL_DISABLED` with the flag to change.
|
|
153
153
|
|
|
154
|
-
A real store submission, a promotion to stable and a share revoke 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; `EXTENSION_DEV_APPROVAL_GATE=0` turns it off.
|
|
154
|
+
A real store submission, a promotion to stable and a share revoke 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 (a store submission needs a workspace owner), and the same call with the returned `approvalId` runs it once. `EXTENSION_DEV_APPROVAL_GATE=1` extends this to every promotion; `EXTENSION_DEV_APPROVAL_GATE=0` turns it off.
|
|
155
155
|
|
|
156
156
|
Every tool also carries MCP annotations (`readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`), so clients can auto-approve reads and ask before the rest.
|
|
157
157
|
|
|
@@ -304,7 +304,7 @@ Extension.js release records one, and that leg reads `skip`.
|
|
|
304
304
|
|
|
305
305
|
## Sharing a build in progress
|
|
306
306
|
|
|
307
|
-
An unpacked extension is unusually hard to hand to someone: the only way to look at a colleague's work-in-progress has been to take their zip and run untrusted code with real browser permissions on your own machine. `extension_preview_web` with `share: true` uploads the `dist/` it just built and returns a link that renders those exact bytes in the emulator. Whoever opens it installs nothing and signs in to nothing, which is what lets a designer, a PM, or a reviewer into the loop at all. Those bytes run in an isolated sandbox origin or they do not run at all: preview refuses a shared build rather than serving it in its own renderer. Sharing needs auth (`extension_auth` or `EXTENSION_DEV_TOKEN`), the link lives 30 days, and `DELETE`ing the returned `revokeUrl` with the same token kills it early. Re-sharing an unchanged build returns that same link rather than a second one, and only a revoked link is replaced by a different one, because revocation is permanent: the address is burned and never resolves again. That makes `revokeUrl` the handle to the link you just made, so every share is also appended to `.extension.dev/shared-previews.json` in the project (gitignored) so it survives losing the tool output. The upload holds up to 2,000 files and about 64MB of text, or roughly 48MB when the build is mostly images, fonts or wasm, which travel base64-encoded. Without `share`, the tool returns a local-only deep link and uploads nothing.
|
|
307
|
+
An unpacked extension is unusually hard to hand to someone: the only way to look at a colleague's work-in-progress has been to take their zip and run untrusted code with real browser permissions on your own machine. `extension_preview_web` with `share: true` uploads the `dist/` it just built and returns a link that renders those exact bytes in the emulator. Whoever opens it installs nothing and signs in to nothing, which is what lets a designer, a PM, or a reviewer into the loop at all. Those bytes run in an isolated sandbox origin or they do not run at all: preview refuses a shared build rather than serving it in its own renderer. Sharing needs auth (`extension_auth` or `EXTENSION_DEV_TOKEN`), the link lives for the workspace plan's share window (30 days on Free, longer on Pro) and the answer carries its exact `expiresAt`, and `DELETE`ing the returned `revokeUrl` with the same token kills it early. Re-sharing an unchanged build returns that same link rather than a second one, and only a revoked link is replaced by a different one, because revocation is permanent: the address is burned and never resolves again. That makes `revokeUrl` the handle to the link you just made, so every share is also appended to `.extension.dev/shared-previews.json` in the project (gitignored) so it survives losing the tool output. The upload holds up to 2,000 files and about 64MB of text, or roughly 48MB when the build is mostly images, fonts or wasm, which travel base64-encoded. Without `share`, the tool returns a local-only deep link and uploads nothing.
|
|
308
308
|
|
|
309
309
|
`extension_shares` is the other half of that: it lists every link the token has shared, live and dead, with the `previewUrl` and `revokeUrl` of each, and revokes one by `artifactId` or by pasting any of its URLs. Pass `projectPath` and it reconciles the platform's answer with the project's own record, so a link shared from another machine shows up as `remoteOnly` and a record with nothing behind it any more shows up under `localOnly`. It never rewrites the local file.
|
|
310
310
|
|
|
@@ -33,7 +33,7 @@ Run a test stage against a live dev session: state expectations and read one ver
|
|
|
33
33
|
| `projectPath` | string | yes | | Extension project root (needs a live dev session) |
|
|
34
34
|
| `expect` | array of object | yes | | One 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). |
|
|
35
35
|
| `browser` | string | no | | Session browser; defaults to this project's live session |
|
|
36
|
-
| `timeout` | number | no | | Command timeout in ms
|
|
36
|
+
| `timeout` | number | no | | 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. |
|
|
37
37
|
|
|
38
38
|
## extension_auth
|
|
39
39
|
|
|
@@ -148,11 +148,11 @@ Take a shallow structured DOM snapshot of one chosen surface through the agent b
|
|
|
148
148
|
| `maxBytes` | number | no | `262144` | |
|
|
149
149
|
| `withConsole` | number \| boolean | no | | Also include recent console lines. A number is how many; true means 50. |
|
|
150
150
|
| `browser` | string | no | | Session browser; defaults to this project's live session |
|
|
151
|
-
| `timeout` | number | no | | Command timeout in ms
|
|
151
|
+
| `timeout` | number | no | | 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. |
|
|
152
152
|
|
|
153
153
|
## extension_eval
|
|
154
154
|
|
|
155
|
-
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
|
|
155
|
+
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}.
|
|
156
156
|
|
|
157
157
|
| input | type | required | default | description |
|
|
158
158
|
| --- | --- | --- | --- | --- |
|
|
@@ -162,7 +162,7 @@ Evaluate an expression in a running extension context. Start the session with al
|
|
|
162
162
|
| `url` | string | no | | content/page: pick the tab by url (match pattern, then substring). Preferred over `tab`. |
|
|
163
163
|
| `tab` | number | no | | Numeric chrome.tabs id, only to disambiguate when several tabs match. |
|
|
164
164
|
| `browser` | string | no | | Session browser; defaults to this project's live session |
|
|
165
|
-
| `timeout` | number | no | | Command timeout in ms
|
|
165
|
+
| `timeout` | number | no | | 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. |
|
|
166
166
|
|
|
167
167
|
## extension_inspect
|
|
168
168
|
|
|
@@ -232,7 +232,7 @@ Open an extension surface, or replay an event, in a running session. Pass surfac
|
|
|
232
232
|
| `tab` | number | no | | 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. |
|
|
233
233
|
| `asTab` | boolean | no | `false` | popup/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. |
|
|
234
234
|
| `browser` | string | no | | Session browser; defaults to this project's live session |
|
|
235
|
-
| `timeout` | number | no | | Command timeout in ms
|
|
235
|
+
| `timeout` | number | no | | 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. |
|
|
236
236
|
|
|
237
237
|
## extension_preview_web
|
|
238
238
|
|
|
@@ -319,7 +319,7 @@ Reload a running extension's background context, or a tab. Start the session wit
|
|
|
319
319
|
| `context` | "background" \| "content" \| "page" | no | `"background"` | |
|
|
320
320
|
| `tab` | number | no | | For content/page: a specific tab id |
|
|
321
321
|
| `browser` | string | no | | Session browser; defaults to this project's live session |
|
|
322
|
-
| `timeout` | number | no | | Command timeout in ms
|
|
322
|
+
| `timeout` | number | no | | 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. |
|
|
323
323
|
|
|
324
324
|
## extension_shares
|
|
325
325
|
|
|
@@ -347,8 +347,8 @@ Run the PRODUCTION build in a browser: build the project, serve it, and launch.
|
|
|
347
347
|
| `browser` | "chrome" \| "chromium" \| "edge" \| "brave" \| "opera" \| "vivaldi" \| "yandex" \| "firefox" \| "waterfox" \| "librewolf" \| "zen" \| "floorp" \| "safari" \| "chromium-based" \| "gecko-based" \| "firefox-based" \| "webkit-based" | no | `"chrome"` | |
|
|
348
348
|
| `build` | boolean | no | `true` | Build before serving. false serves the existing dist/<browser> as-is and fails when there is none. |
|
|
349
349
|
| `polyfill` | boolean | no | `true` | Apply cross-browser polyfill (build only) |
|
|
350
|
-
| `port` | number | no | |
|
|
351
|
-
| `noBrowser` | boolean | no | `false` |
|
|
350
|
+
| `port` | number | no | | 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. |
|
|
351
|
+
| `noBrowser` | boolean | no | `false` | 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. |
|
|
352
352
|
| `outputPath` | string | no | | 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. |
|
|
353
353
|
| `profile` | string | no | | Profile path, or "false" to reuse the real user profile. Omit for a throwaway one. |
|
|
354
354
|
| `startingUrl` | string | no | | URL the browser opens on launch |
|
|
@@ -381,7 +381,7 @@ Read or write chrome.storage in a running extension. Every call runs in the exte
|
|
|
381
381
|
| `key` | string | no | | Key to get or set |
|
|
382
382
|
| `value` | any | no | | Value to set (any JSON value); required for action=set |
|
|
383
383
|
| `browser` | string | no | | Session browser; defaults to this project's live session |
|
|
384
|
-
| `timeout` | number | no | | Command timeout in ms
|
|
384
|
+
| `timeout` | number | no | | 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. |
|
|
385
385
|
|
|
386
386
|
## extension_submit
|
|
387
387
|
|