@extension.dev/mcp 6.6.0 → 9.0.0
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 +2 -2
- package/CHANGELOG.md +259 -0
- package/README.md +13 -21
- package/claude/ARCHITECTURE.md +4 -4
- package/claude/CLAUDE.md +2 -2
- package/claude/README.md +1 -1
- package/claude/commands/extension-add.md +1 -1
- package/claude/commands/extension-debug.md +1 -1
- package/claude/commands/extension-publish.md +1 -1
- package/claude/commands/extension.md +3 -3
- package/claude/rules/mcp-tools.md +45 -49
- package/dist/module.js +1041 -1423
- package/dist/src/lib/common-schema.d.ts +28 -0
- package/dist/src/lib/credentials.d.ts +1 -1
- package/dist/src/lib/launch-flags.d.ts +6 -6
- package/dist/src/lib/login-flow.d.ts +0 -10
- package/dist/src/lib/session-identity.d.ts +16 -0
- package/dist/src/tools/add-feature.d.ts +2 -2
- package/dist/src/tools/analyze.d.ts +29 -0
- package/dist/src/tools/auth.d.ts +33 -0
- package/dist/src/tools/browsers.d.ts +39 -0
- package/dist/src/tools/build.d.ts +5 -6
- package/dist/src/tools/detect-browsers.d.ts +1 -20
- package/dist/src/tools/dev.d.ts +11 -11
- package/dist/src/tools/{dom-inspect.d.ts → dom-snapshot.d.ts} +6 -6
- package/dist/src/tools/eval.d.ts +6 -6
- package/dist/src/tools/get-template-source.d.ts +1 -22
- package/dist/src/tools/inspect.d.ts +33 -5
- package/dist/src/tools/install-browser.d.ts +1 -18
- package/dist/src/tools/list-browsers.d.ts +1 -9
- package/dist/src/tools/list-extensions.d.ts +4 -4
- package/dist/src/tools/list-templates.d.ts +1 -35
- package/dist/src/tools/login.d.ts +1 -23
- package/dist/src/tools/logout.d.ts +1 -9
- package/dist/src/tools/logs-schema.d.ts +2 -2
- package/dist/src/tools/open.d.ts +6 -6
- package/dist/src/tools/preview-web.d.ts +4 -16
- package/dist/src/tools/publish.d.ts +2 -2
- package/dist/src/tools/release-list.d.ts +1 -23
- package/dist/src/tools/release-promote.d.ts +2 -2
- package/dist/src/tools/release-status.d.ts +37 -0
- package/dist/src/tools/reload.d.ts +6 -6
- package/dist/src/tools/shares.d.ts +2 -2
- package/dist/src/tools/start.d.ts +16 -10
- package/dist/src/tools/stop.d.ts +2 -2
- package/dist/src/tools/storage.d.ts +6 -6
- package/dist/src/tools/store-status.d.ts +1 -23
- package/dist/src/tools/{deploy.d.ts → submit.d.ts} +4 -4
- package/dist/src/tools/{source-inspect.d.ts → templates.d.ts} +27 -23
- package/dist/src/tools/uninstall-browser.d.ts +1 -21
- package/dist/src/tools/wait.d.ts +4 -4
- package/dist/src/tools/whoami.d.ts +1 -9
- package/extensions/live-preview/chromium/action/index.css +1 -1
- package/extensions/live-preview/chromium/action/index.js +1 -9
- package/extensions/live-preview/chromium/background/service_worker.js +4 -12
- package/extensions/live-preview/chromium/manifest.json +1 -2
- package/package.json +2 -2
- package/server.json +3 -3
- package/dist/src/__tests__/fixtures/ready-contract.d.ts +0 -7
- package/dist/src/__tests__/setup-session-dir.d.ts +0 -1
- package/dist/src/lib/github-device.d.ts +0 -31
- package/dist/src/tools/preview.d.ts +0 -66
- /package/dist/src/tools/{source-inspect-gecko.d.ts → inspect-gecko.d.ts} +0 -0
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"name": "extension-mcp",
|
|
11
11
|
"source": "./",
|
|
12
12
|
"description": "MCP tools for browser extension development: scaffold from 60+ 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": "
|
|
13
|
+
"version": "9.0.0",
|
|
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 60+ 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": "
|
|
4
|
+
"version": "9.0.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cezar Augusto",
|
|
7
7
|
"email": "hello@extension.dev",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"homepage": "https://github.com/extensiondev/mcp",
|
|
11
11
|
"repository": "https://github.com/extensiondev/mcp",
|
|
12
|
-
"license": "
|
|
12
|
+
"license": "Apache-2.0",
|
|
13
13
|
"keywords": [
|
|
14
14
|
"mcp",
|
|
15
15
|
"browser-extension",
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,264 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 9.0.0
|
|
4
|
+
|
|
5
|
+
Every client pays for this server's tool list at the start of every session,
|
|
6
|
+
whether or not the user ever touches an extension. That list was 36 tools and
|
|
7
|
+
52,403 bytes on the wire (roughly 13,100 tokens). It is now 28 tools and
|
|
8
|
+
43,214 bytes (roughly 10,800 tokens), a 17.5% cut, with no capability removed.
|
|
9
|
+
Eleven tools folded into the four that already owned their resource,
|
|
10
|
+
`extension_preview` folded into `extension_start`, and the prose was tightened
|
|
11
|
+
everywhere it repeated the schema or a parameter name.
|
|
12
|
+
|
|
13
|
+
9.0.0 lands close behind 8.0.0 on purpose. 8.0.0 renamed four tools for
|
|
14
|
+
disambiguation; this release cuts what the surface costs. Both are breaking,
|
|
15
|
+
adoption is still low, and doing them as one migration is cheaper for early
|
|
16
|
+
users than spacing them out.
|
|
17
|
+
|
|
18
|
+
### Migration
|
|
19
|
+
|
|
20
|
+
| Old tool | New call |
|
|
21
|
+
| --- | --- |
|
|
22
|
+
| `extension_detect_browsers({ browsers })` | `extension_browsers({ action: "detect", browsers })` |
|
|
23
|
+
| `extension_list_browsers()` | `extension_browsers({ action: "list" })` |
|
|
24
|
+
| `extension_install_browser({ browser })` | `extension_browsers({ action: "install", browser })` |
|
|
25
|
+
| `extension_uninstall_browser({ browser, all })` | `extension_browsers({ action: "uninstall", browser, all })` |
|
|
26
|
+
| `extension_login({ project, deviceCode, api })` | `extension_auth({ action: "login", project, deviceCode, api })` |
|
|
27
|
+
| `extension_whoami()` | `extension_auth({ action: "status" })` |
|
|
28
|
+
| `extension_logout()` | `extension_auth({ action: "logout" })` |
|
|
29
|
+
| `extension_list_templates({ surface, framework, tags, featured, query })` | `extension_templates({ action: "list", surface, framework, tags, featured, query })` |
|
|
30
|
+
| `extension_get_template_source({ slug, files })` | `extension_templates({ action: "source", slug, files })` |
|
|
31
|
+
| `extension_release_list({ workspace, project, api })` | `extension_release_status({ include: ["releases"], workspace, project, api })` |
|
|
32
|
+
| `extension_store_status({ workspace, project, api })` | `extension_release_status({ include: ["stores"], workspace, project, api })` |
|
|
33
|
+
| `extension_preview({ projectPath, browser, port, noBrowser, ...launch })` | `extension_start({ projectPath, build: false, browser, port, noBrowser, ...launch })` |
|
|
34
|
+
|
|
35
|
+
Every argument keeps its name and its meaning. `action` defaults to the most
|
|
36
|
+
common case (`detect`, `status`, `list`), so `extension_browsers({})` scans,
|
|
37
|
+
`extension_auth({})` reports the login, and `extension_templates({})` lists.
|
|
38
|
+
`extension_release_status` returns both sections by default and nests each
|
|
39
|
+
under `releases` and `stores`; the old flat bodies are unchanged inside them.
|
|
40
|
+
The CLI is untouched: `extension-mcp login|logout|whoami|release` still work
|
|
41
|
+
exactly as before.
|
|
42
|
+
|
|
43
|
+
`extension_submit`, `extension_publish`, `extension_analyze`,
|
|
44
|
+
`extension_inspect` and `extension_dom_snapshot` were deliberately NOT merged.
|
|
45
|
+
8.0.0 separated them because agents confused them; folding them behind an
|
|
46
|
+
`action` parameter would hide that ambiguity rather than remove it.
|
|
47
|
+
|
|
48
|
+
### Upgrading from 7.0.0
|
|
49
|
+
|
|
50
|
+
Most installs are still on 7.0.0 and two majors have landed on top of it. Do
|
|
51
|
+
both in one pass: apply the 8.0.0 renames, then the 9.0.0 merges above. 7.0.0
|
|
52
|
+
advertised 36 tools; 9.0.0 advertises 28, and every capability survived.
|
|
53
|
+
|
|
54
|
+
| 7.0.0 call | 9.0.0 call | Landed in |
|
|
55
|
+
| --- | --- | --- |
|
|
56
|
+
| `extension_deploy(...)` | `extension_submit(...)` | 8.0.0 |
|
|
57
|
+
| `extension_inspect({ projectPath })` | `extension_analyze({ projectPath })` | 8.0.0 |
|
|
58
|
+
| `extension_source_inspect(...)` | `extension_inspect(...)` | 8.0.0 |
|
|
59
|
+
| `extension_dom_inspect(...)` | `extension_dom_snapshot(...)` | 8.0.0 |
|
|
60
|
+
| `extension_detect_browsers({ browsers })` | `extension_browsers({ action: "detect", browsers })` | 9.0.0 |
|
|
61
|
+
| `extension_list_browsers()` | `extension_browsers({ action: "list" })` | 9.0.0 |
|
|
62
|
+
| `extension_install_browser({ browser })` | `extension_browsers({ action: "install", browser })` | 9.0.0 |
|
|
63
|
+
| `extension_uninstall_browser({ browser, all })` | `extension_browsers({ action: "uninstall", browser, all })` | 9.0.0 |
|
|
64
|
+
| `extension_login({ project, deviceCode, api })` | `extension_auth({ action: "login", project, deviceCode, api })` | 9.0.0 |
|
|
65
|
+
| `extension_whoami()` | `extension_auth({ action: "status" })` | 9.0.0 |
|
|
66
|
+
| `extension_logout()` | `extension_auth({ action: "logout" })` | 9.0.0 |
|
|
67
|
+
| `extension_list_templates({ surface, framework, tags, featured, query })` | `extension_templates({ action: "list", surface, framework, tags, featured, query })` | 9.0.0 |
|
|
68
|
+
| `extension_get_template_source({ slug, files })` | `extension_templates({ action: "source", slug, files })` | 9.0.0 |
|
|
69
|
+
| `extension_release_list({ workspace, project, api })` | `extension_release_status({ include: ["releases"], workspace, project, api })` | 9.0.0 |
|
|
70
|
+
| `extension_store_status({ workspace, project, api })` | `extension_release_status({ include: ["stores"], workspace, project, api })` | 9.0.0 |
|
|
71
|
+
| `extension_preview({ projectPath, browser, port, noBrowser, ...launch })` | `extension_start({ projectPath, build: false, browser, port, noBrowser, ...launch })` | 9.0.0 |
|
|
72
|
+
|
|
73
|
+
Read the `extension_inspect` row before any of the others. That name exists in
|
|
74
|
+
both versions and does not mean the same thing in each. In 7.0.0 it read a
|
|
75
|
+
BUILT extension's files off disk. In 9.0.0 it reads a RUNNING extension over
|
|
76
|
+
the browser's debugger protocol and needs a live `extension_dev` or
|
|
77
|
+
`extension_start` session. A 7.0.0 call left alone does not fail with an
|
|
78
|
+
unknown-tool error, it silently reaches the wrong tool and reports no dev
|
|
79
|
+
session instead of the file sizes you asked for. The disk reader is
|
|
80
|
+
`extension_analyze` now. Every call that passed a bare `projectPath` and
|
|
81
|
+
expected sizes, permissions and store-readiness back has to move.
|
|
82
|
+
|
|
83
|
+
`extension_deploy` carried its error names with it into `extension_submit`:
|
|
84
|
+
`DeployAuthError`, `DeployInputError`, `DeployConfigError`,
|
|
85
|
+
`DeployNetworkError` and `DeployError` are now `SubmitAuthError`,
|
|
86
|
+
`SubmitInputError`, `SubmitConfigError`, `SubmitNetworkError` and
|
|
87
|
+
`SubmitError`. Anything branching on those strings has to move with them.
|
|
88
|
+
|
|
89
|
+
Every argument keeps its name and its meaning across both majors, with two
|
|
90
|
+
exceptions:
|
|
91
|
+
|
|
92
|
+
- `extension_release_status` nests what the two 7.0.0 tools returned flat,
|
|
93
|
+
under `releases` and `stores`. The bodies inside are byte-for-byte the old
|
|
94
|
+
ones. Omitting `include` returns both sections.
|
|
95
|
+
- `extension_start` gained `build`, defaulting to `true`. `build: false` is
|
|
96
|
+
what `extension_preview` was.
|
|
97
|
+
|
|
98
|
+
Nothing else moved. `extension_publish`, `extension_preview_web`,
|
|
99
|
+
`extension_shares`, `extension_release_promote`, `extension_dev`,
|
|
100
|
+
`extension_build`, `extension_create`, `extension_add_feature`,
|
|
101
|
+
`extension_wait`, `extension_stop`, `extension_logs`, `extension_eval`,
|
|
102
|
+
`extension_storage`, `extension_reload`, `extension_open`,
|
|
103
|
+
`extension_list_extensions`, `extension_manifest_validate`,
|
|
104
|
+
`extension_theme_verify` and `extension_doctor` are unchanged in name and in
|
|
105
|
+
arguments, and the CLI (`extension-mcp login|logout|whoami|release`) never
|
|
106
|
+
moved at all.
|
|
107
|
+
|
|
108
|
+
### Merged
|
|
109
|
+
|
|
110
|
+
- **Four browser tools are one.** `extension_browsers` detects, lists,
|
|
111
|
+
installs, and uninstalls. `detect` and `list` were the confusable pair: both
|
|
112
|
+
answered "what browsers do I have", and telling them apart took a sentence of
|
|
113
|
+
prose in each description. An action enum settles it in the schema.
|
|
114
|
+
- **Three auth tools are one.** `extension_auth` signs in, reports the stored
|
|
115
|
+
login, and clears it. They were a lifecycle triad that each re-explained the
|
|
116
|
+
same token model.
|
|
117
|
+
- **Two template tools are one.** `extension_templates` searches the catalog
|
|
118
|
+
and reads a template's source. The slug you read comes from the list you just
|
|
119
|
+
searched, so the pair is one resource.
|
|
120
|
+
- **The two read-only release tools are one.** `extension_release_status`
|
|
121
|
+
returns release channels and recent builds, browser-store submissions and
|
|
122
|
+
review state, or both. They took identical arguments and read the same
|
|
123
|
+
registry. `extension_release_promote` stays separate on purpose: it is the
|
|
124
|
+
only verb that writes, and putting a write behind the same `action`
|
|
125
|
+
parameter as a read is how an agent promotes a build it meant to list.
|
|
126
|
+
- **`extension_preview` folded into `extension_start`.** Both answered "run the
|
|
127
|
+
production build in a browser"; the only difference was whether a build ran
|
|
128
|
+
first. That is now `build`, defaulting to `true`, which matches
|
|
129
|
+
`extension_preview_web`, where `build: false` already means the same thing.
|
|
130
|
+
|
|
131
|
+
### Sharpened
|
|
132
|
+
|
|
133
|
+
- **`extension_dev` and `extension_start` now say which one to pick.**
|
|
134
|
+
They are not merged: `dev` is the only tool that can unlock the control
|
|
135
|
+
channel (`allowControl`, `allowEval`) that `extension_storage`,
|
|
136
|
+
`extension_reload`, `extension_open`, `extension_dom_snapshot` and
|
|
137
|
+
`extension_eval` need, and `start` runs a production build with none of it.
|
|
138
|
+
A `mode` parameter would have made those flags look valid on a session that
|
|
139
|
+
cannot honor them. Instead each description now opens with the thing that
|
|
140
|
+
decides between them and names the other tool.
|
|
141
|
+
- **Descriptions no longer repeat the schema.** The biggest cuts, in bytes of
|
|
142
|
+
description: `extension_shares` 1,661 to 1,250, `extension_preview_web`
|
|
143
|
+
1,151 to 639, `extension_submit` 1,478 to 1,194, `extension_eval` 1,128 to
|
|
144
|
+
831, `extension_wait` 985 to 784, `extension_list_extensions` 944 to 696,
|
|
145
|
+
`extension_dom_snapshot` 965 to 854. What was cut was prose that restated a
|
|
146
|
+
parameter name, repeated a property's own description, or explained the
|
|
147
|
+
response shape the response already carries. What was kept is anything that
|
|
148
|
+
stops a tool being misused: the `activeTab` gesture warning on
|
|
149
|
+
`extension_open`, the MV3 service-worker CSP note on `extension_eval`, the
|
|
150
|
+
profile-lock explanation on `extension_dev`, and the irreversibility of
|
|
151
|
+
`extension_submit` and of revoking a share.
|
|
152
|
+
- **Repeated property schemas are shared.** `projectPath`, the session
|
|
153
|
+
`browser`, the call `timeout`, the platform `api` base and the launch browser
|
|
154
|
+
enum are defined once in `src/lib/common-schema.ts` instead of being
|
|
155
|
+
re-typed per tool.
|
|
156
|
+
|
|
157
|
+
### Considered and rejected
|
|
158
|
+
|
|
159
|
+
- **A smaller default surface with the rest opt-in.** The platform cluster
|
|
160
|
+
(`extension_auth`, `extension_publish`, `extension_submit`,
|
|
161
|
+
`extension_release_status`, `extension_release_promote`, `extension_shares`,
|
|
162
|
+
`extension_preview_web`) is 13 KB, about 30% of what is left, and is dead
|
|
163
|
+
weight for anyone building an extension locally without an extension.dev
|
|
164
|
+
account. Hiding it behind an env flag would cut the default surface by
|
|
165
|
+
roughly a third. It was not shipped because a hidden tool is an invisible
|
|
166
|
+
capability: an agent asked to publish would report that it cannot, which is
|
|
167
|
+
worse than the tokens. The version worth building expands the surface once a
|
|
168
|
+
login exists and announces it with `notifications/tools/list_changed`, and
|
|
169
|
+
that needs a client-by-client compatibility check first.
|
|
170
|
+
|
|
171
|
+
### Added
|
|
172
|
+
|
|
173
|
+
- `pnpm exec node scripts/tool-surface-size.mjs` starts the server, calls
|
|
174
|
+
`tools/list`, and reports exactly what a client receives: bytes per tool
|
|
175
|
+
split into description and schema, and the total. `--json` for the raw rows.
|
|
176
|
+
Before this, the cost of the tool surface was never measured, only guessed.
|
|
177
|
+
|
|
178
|
+
## 8.0.0
|
|
179
|
+
|
|
180
|
+
Four tools are renamed. Every rename fixes a name that made agents pick the
|
|
181
|
+
wrong tool, and one of them could cost you a store submission you did not ask
|
|
182
|
+
for. No behavior changes, no argument changes.
|
|
183
|
+
|
|
184
|
+
### Migration
|
|
185
|
+
|
|
186
|
+
| Old name | New name |
|
|
187
|
+
| --- | --- |
|
|
188
|
+
| `extension_deploy` | `extension_submit` |
|
|
189
|
+
| `extension_inspect` | `extension_analyze` |
|
|
190
|
+
| `extension_source_inspect` | `extension_inspect` |
|
|
191
|
+
| `extension_dom_inspect` | `extension_dom_snapshot` |
|
|
192
|
+
|
|
193
|
+
`extension_publish` is unchanged.
|
|
194
|
+
|
|
195
|
+
### Renamed
|
|
196
|
+
|
|
197
|
+
- **`extension_deploy` is now `extension_submit`.** The pair was inverted
|
|
198
|
+
against every other developer tool: `extension_publish` pushes a build to the
|
|
199
|
+
extension.dev platform, while `extension_deploy` submitted to the Chrome Web
|
|
200
|
+
Store, Firefox AMO, Edge Add-ons and the App Store. An agent told to "deploy
|
|
201
|
+
my extension" reached for the store tool, and picking wrong there means an
|
|
202
|
+
unintended store submission, which is irreversible. "Submit" is the stores'
|
|
203
|
+
own word for it ("submit for review"), so the name now says what happens.
|
|
204
|
+
`extension_publish` keeps its name and its job. The error names in the
|
|
205
|
+
response follow: `DeployAuthError`, `DeployInputError`, `DeployConfigError`,
|
|
206
|
+
`DeployNetworkError` and `DeployError` are now `SubmitAuthError`,
|
|
207
|
+
`SubmitInputError`, `SubmitConfigError`, `SubmitNetworkError` and
|
|
208
|
+
`SubmitError`.
|
|
209
|
+
- **Three tools were called inspect; now one is.** `extension_inspect` read a
|
|
210
|
+
built extension's files off disk, `extension_source_inspect` read a running
|
|
211
|
+
extension's live state, and `extension_dom_inspect` snapshotted one surface's
|
|
212
|
+
DOM. The name that reads as the primary one belonged to the static file
|
|
213
|
+
reader, which is the least of the three. Static analysis is now
|
|
214
|
+
`extension_analyze`, and the live-state tool takes `extension_inspect`.
|
|
215
|
+
- **`extension_dom_inspect` is now `extension_dom_snapshot`.** It is not a
|
|
216
|
+
duplicate of the live-state tool and it survives the rename with its
|
|
217
|
+
capabilities intact, but sharing the word "inspect" was most of why the two
|
|
218
|
+
were confusable. The descriptions now state the split outright:
|
|
219
|
+
`extension_dom_snapshot` is the surface picker (it is the only tool that
|
|
220
|
+
reads an OPEN extension surface by name, the only one that takes a numeric
|
|
221
|
+
`chrome.tabs` id, and the only one that enumerates what is open) and it
|
|
222
|
+
returns a shallow snapshot over the CDP-free agent bridge, which needs
|
|
223
|
+
`allowControl: true`. `extension_inspect` is the deep reader (it is the only
|
|
224
|
+
tool that pierces CLOSED shadow roots, runs CSS selector probes, and
|
|
225
|
+
navigates a tab before reading it) and it rides the debugger protocol.
|
|
226
|
+
|
|
227
|
+
## 7.0.0
|
|
228
|
+
|
|
229
|
+
`preview.extension.dev` is the only web door this package knows about. The
|
|
230
|
+
inspect door predates it and had stopped being reachable.
|
|
231
|
+
|
|
232
|
+
### Removed
|
|
233
|
+
|
|
234
|
+
- **`extension_preview_web` no longer takes `surface` or `inspectUrl`.**
|
|
235
|
+
`surface:"inspect"` pointed a local build at `inspect.extension.dev` over the
|
|
236
|
+
`inspect://path` scheme, which is what the tool did before
|
|
237
|
+
`preview.extension.dev` existed. Only the inspect dev server ever answered it:
|
|
238
|
+
the deployed origin serves store listings and has no `/__inspect/fetch`, so
|
|
239
|
+
the door resolved on one machine and nowhere else. Every build now renders in
|
|
240
|
+
`preview.extension.dev`, which is also the surface that carries the
|
|
241
|
+
Emulated/Real lane toggle and the Trace tab. The response no longer carries a
|
|
242
|
+
`surface` field, and `hostUrl` is the only origin override.
|
|
243
|
+
- **The carrier no longer allowlists `inspect.extension.dev`.** Pairing needs a
|
|
244
|
+
page that opens the bridge, and inspect never did: it traces the emulated lane
|
|
245
|
+
of the extension it fetched and has no lane toggle. `extension_dev`
|
|
246
|
+
`carrier: true` and the pairing notes now point at `preview.extension.dev`,
|
|
247
|
+
and the carrier's `externally_connectable` drops the origin that was never
|
|
248
|
+
going to connect.
|
|
249
|
+
- **`extension_login` no longer falls back to the GitHub device flow.**
|
|
250
|
+
extension.dev hosts the device flow itself and federates GitHub server-side, so
|
|
251
|
+
the only authorization surface is `extension.dev/device` and no GitHub token
|
|
252
|
+
ever lands on the caller's machine. The legacy path is gone entirely: the
|
|
253
|
+
GitHub device-code client, the `provider` fork (which existed twice, once in the
|
|
254
|
+
tool and once in the `extension-mcp login` bin), the
|
|
255
|
+
`/api/cli/login/exchange` hop, and the `EXTENSION_DEV_GITHUB_CLIENT_ID`
|
|
256
|
+
override. Stored credentials record `provider: "extensiondev"` and
|
|
257
|
+
`extension_whoami` reports that instead of defaulting to `"github"`. Nothing
|
|
258
|
+
changes for a caller who was already on the branded flow, which is every caller
|
|
259
|
+
the platform has served since it went live; a self-hosted platform pinned to
|
|
260
|
+
the old exchange endpoint is no longer supported.
|
|
261
|
+
|
|
3
262
|
## 6.6.0
|
|
4
263
|
|
|
5
264
|
A shared build belongs to the project that owns it, not to whoever happened to
|
package/README.md
CHANGED
|
@@ -5,11 +5,9 @@
|
|
|
5
5
|
[discord-image]: https://img.shields.io/discord/1253608412890271755?label=Discord&logo=discord&style=flat&color=26FFB8
|
|
6
6
|
[discord-url]: https://discord.gg/v9h2RgeTSN
|
|
7
7
|
|
|
8
|
-
<img alt="@extension.dev/mcp" src="https://media.extension.land/brand/repos/mcp/github-banner.png" />
|
|
9
|
-
|
|
10
8
|
# @extension.dev/mcp [![Version][npm-version-image]][npm-version-url] [![Downloads][npm-downloads-image]][npm-downloads-url] [![Discord][discord-image]][discord-url]
|
|
11
9
|
|
|
12
|
-
> Give your AI agent hands for browser extension development.
|
|
10
|
+
> Give your AI agent hands for browser extension development. 28 MCP tools that scaffold, run, inspect, debug, and publish cross-browser extensions.
|
|
13
11
|
|
|
14
12
|
<img alt="Logo" align="right" src="https://media.extension.land/brand/extension-dev/logo-dock.png" width="20.7%" />
|
|
15
13
|
|
|
@@ -104,19 +102,17 @@ cp node_modules/@extension.dev/mcp/claude/commands/*.md ~/my-extension/.claude/c
|
|
|
104
102
|
| Tier | Tool | Description |
|
|
105
103
|
| ---- | ---- | ----------- |
|
|
106
104
|
| build | `extension_create` | Scaffold from a template |
|
|
107
|
-
| build | `
|
|
108
|
-
| build | `extension_get_template_source` | Read template source files |
|
|
105
|
+
| build | `extension_templates` | Browse 60+ templates (`list`) and read one's source (`source`) |
|
|
109
106
|
| build | `extension_add_feature` | Add sidebar/popup/content script |
|
|
110
107
|
| build | `extension_build` | Build for production |
|
|
111
108
|
| run | `extension_dev` | Dev server with HMR |
|
|
112
|
-
| run | `extension_start` | Build +
|
|
113
|
-
| run | `extension_preview` | Preview the production build |
|
|
109
|
+
| run | `extension_start` | Build + launch the production build (`build: false` launches the existing dist) |
|
|
114
110
|
| run | `extension_wait` | Poll the dev-server ready contract |
|
|
115
111
|
| run | `extension_stop` | Stop a dev/start/preview session (server + browser) |
|
|
116
112
|
| see | `extension_manifest_validate` | Cross-browser manifest validation |
|
|
117
|
-
| see | `
|
|
118
|
-
| see | `
|
|
119
|
-
| see | `
|
|
113
|
+
| see | `extension_analyze` | Static analysis of the built extension on disk |
|
|
114
|
+
| see | `extension_inspect` | Deep live inspection of a running extension (closed shadow roots, probes) |
|
|
115
|
+
| see | `extension_dom_snapshot` | Shallow DOM snapshot of a chosen tab or extension surface, CDP-free |
|
|
120
116
|
| see | `extension_list_extensions` | List loaded extensions (Chromium) |
|
|
121
117
|
| see | `extension_logs` | Stream logs from every context |
|
|
122
118
|
| see | `extension_doctor` | Diagnose the dev session leg by leg (ready contract, ports, token, executor, browser) |
|
|
@@ -125,24 +121,20 @@ cp node_modules/@extension.dev/mcp/claude/commands/*.md ~/my-extension/.claude/c
|
|
|
125
121
|
| act | `extension_storage` | Read/write `chrome.storage` |
|
|
126
122
|
| act | `extension_reload` | Reload extension or tab |
|
|
127
123
|
| act | `extension_open` | Open a surface / trigger `action`, `command` |
|
|
128
|
-
| browsers | `
|
|
129
|
-
|
|
|
130
|
-
| browsers | `extension_list_browsers` | List managed browsers |
|
|
131
|
-
| browsers | `extension_detect_browsers` | Detect system browsers |
|
|
132
|
-
| platform | `extension_login` | GitHub device-code login, stored token |
|
|
133
|
-
| platform | `extension_whoami` | Show the stored login (never the token) |
|
|
134
|
-
| platform | `extension_logout` | Remove stored credentials |
|
|
124
|
+
| browsers | `extension_browsers` | Detect, list, install, and uninstall browsers |
|
|
125
|
+
| platform | `extension_auth` | Device login at extension.dev, plus login status and logout |
|
|
135
126
|
| platform | `extension_preview_web` | Render a build in the web emulator, and share it as a link |
|
|
136
127
|
| platform | `extension_shares` | List every link you have shared, and revoke one permanently |
|
|
137
128
|
| platform | `extension_publish` | Publish a shareable preview to extension.dev |
|
|
138
129
|
| platform | `extension_release_promote` | Promote a build to a release channel, headless |
|
|
139
|
-
| platform | `
|
|
130
|
+
| platform | `extension_submit` | Submit for store review: Chrome, Firefox, Edge, Safari, through extension.dev |
|
|
131
|
+
| platform | `extension_release_status` | Read release channels, recent builds, and store submission and review state |
|
|
140
132
|
|
|
141
|
-
Browser-launching tools (`dev`, `start
|
|
133
|
+
Browser-launching tools (`dev`, `start`) shell out to the `extension` CLI, the project's own `node_modules/.bin/extension` when present, otherwise `npx extension@<pinned>` at the version this package is verified against; everything else runs in-process.
|
|
142
134
|
|
|
143
135
|
## Sharing a build in progress
|
|
144
136
|
|
|
145
|
-
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. Sharing needs auth (`
|
|
137
|
+
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. Sharing needs auth (`extension_auth` or `EXTENSION_DEV_TOKEN`), the link expires, and `DELETE`ing the returned `revokeUrl` with the same token kills it early. Revocation is permanent and re-sharing mints a new link, so that `revokeUrl` is the only handle to the link you just made; every share is also appended to `.extension.dev/shared-previews.json` in the project (gitignored) so it survives losing the tool output. Without `share`, the tool returns a local-only deep link and uploads nothing.
|
|
146
138
|
|
|
147
139
|
`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.
|
|
148
140
|
|
|
@@ -150,7 +142,7 @@ That is a different job from shipping. Use `share` for the build you are holding
|
|
|
150
142
|
|
|
151
143
|
## From preview to store
|
|
152
144
|
|
|
153
|
-
The platform tools connect agents to [extension.dev](https://extension.dev): `
|
|
145
|
+
The platform tools connect agents to [extension.dev](https://extension.dev): `extension_auth` runs extension.dev's own device flow (you approve the code at [extension.dev/device](https://extension.dev/device), and GitHub is federated server-side, so no GitHub token ever reaches your machine) and stores a project-scoped token locally (never returned to the agent), `extension_publish` turns a build your project has already published into a shareable URL, and `extension_release_promote` promotes a tested build to a release channel from CI or an agent session, no browser required. `extension_submit` submits a built extension to the Chrome Web Store, Edge Add-ons, and Firefox AMO through extension.dev, which holds your store credentials and dispatches the release from your project's mirror CI, it defaults to a dry run and store credentials are never tool arguments. The two verbs are not interchangeable: `extension_publish` pushes to the extension.dev platform, `extension_submit` sends the build into a store's review queue, which is irreversible. After a real submission, `extension_release_status` reads the recorded outcome, per-store credential health, and review state from the project's public registry, so agents and CI can answer "was it approved?" without a console visit. Access tokens live at most 7 days; CI pipelines re-mint them from the console's Access tokens page.
|
|
154
146
|
|
|
155
147
|
## The extension.dev stack
|
|
156
148
|
|
package/claude/ARCHITECTURE.md
CHANGED
|
@@ -88,7 +88,7 @@ Claude now knows:
|
|
|
88
88
|
**Role in ecosystem:** Programmatic bridge between Claude and the extension.dev platform, sourced from the examples repo.
|
|
89
89
|
|
|
90
90
|
```
|
|
91
|
-
Claude (via MCP) calls
|
|
91
|
+
Claude (via MCP) calls extension_templates({ surface: "sidebar", tags: ["ai"] })
|
|
92
92
|
│
|
|
93
93
|
▼
|
|
94
94
|
MCP server fetches templates-meta.json (cached, 1hr TTL)
|
|
@@ -97,7 +97,7 @@ MCP server fetches templates-meta.json (cached, 1hr TTL)
|
|
|
97
97
|
Returns: [{ slug: "sidebar-claude", ... }, { slug: "sidebar-transformers-js", ... }]
|
|
98
98
|
│
|
|
99
99
|
▼
|
|
100
|
-
Claude calls
|
|
100
|
+
Claude calls extension_templates({ action: "source", slug: "sidebar-claude", files: ["src/manifest.json", "src/lib/claude.ts"] })
|
|
101
101
|
│
|
|
102
102
|
▼
|
|
103
103
|
MCP server fetches from https://raw.githubusercontent.com/extension-js/examples/main/examples/sidebar-claude/<file>
|
|
@@ -114,8 +114,8 @@ MCP server calls extensionCreate() → same go-git-it flow as CLI
|
|
|
114
114
|
|
|
115
115
|
**How it integrates with the examples repo:**
|
|
116
116
|
|
|
117
|
-
- `
|
|
118
|
-
- `
|
|
117
|
+
- `extension_templates` (`list`) → reads `templates-meta.json` release asset
|
|
118
|
+
- `extension_templates` (`source`) → reads raw files from the examples repo
|
|
119
119
|
- `extension_create` → clones from the examples repo (same as CLI)
|
|
120
120
|
- `extension_add_feature` → sources codegen patterns from example templates
|
|
121
121
|
- `extension_manifest_validate` → cross-references against known-good manifests in the catalog
|
package/claude/CLAUDE.md
CHANGED
|
@@ -195,9 +195,9 @@ extension inspect --tab 1 --include summary,html --with-console 20
|
|
|
195
195
|
| `--max-bytes <n>` | 262144 | Cap on returned HTML bytes |
|
|
196
196
|
| `--with-console [n]` | 20 | Also include the last n console lines for the target |
|
|
197
197
|
|
|
198
|
-
The `
|
|
198
|
+
The `extension_dom_snapshot` MCP tool wraps this verb one-to-one.
|
|
199
199
|
|
|
200
|
-
**Debugging protocol (Chromium CDP): `
|
|
200
|
+
**Debugging protocol (Chromium CDP): `extension_inspect` MCP tool.** Connects directly to the running session's debug port. Use it when the bridge is not enough: closed shadow roots (`deepDom`), selector probes, DOM snapshots, console summaries, or navigating the tab to a URL before inspecting. Returns structured events:
|
|
201
201
|
|
|
202
202
|
- `page_html` - full injected HTML (after content scripts run)
|
|
203
203
|
- `page_html_summary` - root/script/style/link counts
|
package/claude/README.md
CHANGED
|
@@ -62,7 +62,7 @@ Claude Code will automatically pick up the instructions and know how to:
|
|
|
62
62
|
The [examples repo](https://github.com/extension-js/examples) publishes `templates-meta.json` as a nightly release asset. This file is the single source of truth for:
|
|
63
63
|
|
|
64
64
|
- **CLAUDE.md**, references it so Claude knows all available templates
|
|
65
|
-
- **MCP tools**, `
|
|
65
|
+
- **MCP tools**, `extension_templates` fetches and queries it at runtime
|
|
66
66
|
- **`extension create`**, resolves template slugs to repo URLs via the same naming convention
|
|
67
67
|
|
|
68
68
|
When a new template is added to the examples repo, all three layers pick it up automatically.
|
|
@@ -20,7 +20,7 @@ Add a new feature surface to the current extension project. The user said: $ARGU
|
|
|
20
20
|
2. **Get the reference pattern**
|
|
21
21
|
If MCP tool `extension_add_feature` is available, use it. It returns the exact manifest additions, files to create, and reference template.
|
|
22
22
|
|
|
23
|
-
If MCP tool `
|
|
23
|
+
If MCP tool `extension_templates` (`action: "source"`) is available, read the reference template source to get real implementation patterns.
|
|
24
24
|
|
|
25
25
|
3. **Update manifest.json**
|
|
26
26
|
Add the required fields to `src/manifest.json`. Use the extension.dev cross-browser format:
|
|
@@ -13,7 +13,7 @@ Debug the currently running extension dev session. The user said: $ARGUMENTS
|
|
|
13
13
|
- If no session: tell the user to start one with `/extension dev` or `npm run dev`
|
|
14
14
|
|
|
15
15
|
2. **Inspect the live state**
|
|
16
|
-
If MCP tool `
|
|
16
|
+
If MCP tool `extension_inspect` is available:
|
|
17
17
|
- Pass `include: ["html", "summary", "meta", "console", "extension_roots"]`
|
|
18
18
|
- If the user provided a URL in `$ARGUMENTS`, pass it as `url`
|
|
19
19
|
- If the user provided CSS selectors (strings starting with `#`, `.`, or `[`), pass them as `probe`
|
|
@@ -27,7 +27,7 @@ Default to `both` (Chrome + Firefox). If the user specifies `chrome` or `firefox
|
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
3. **Inspect the builds**
|
|
30
|
-
If MCP tool `
|
|
30
|
+
If MCP tool `extension_analyze` is available, use it for each browser build.
|
|
31
31
|
Check:
|
|
32
32
|
- Total size under 10MB (store limit)
|
|
33
33
|
- No source maps in production build
|
|
@@ -11,7 +11,7 @@ Parse the user's intent from `$ARGUMENTS` and execute the matching action:
|
|
|
11
11
|
|
|
12
12
|
### "create <name>" or "new <name>", Scaffold a new extension
|
|
13
13
|
|
|
14
|
-
1. If MCP tool `
|
|
14
|
+
1. If MCP tool `extension_templates` is available, use it to find the best template matching the user's description (check for surface type, framework, and keywords)
|
|
15
15
|
2. If not, check the template catalog: `curl -sL https://github.com/extension-js/examples/releases/download/nightly/templates-meta.json | jq '.templates[] | {slug, description, uiFramework, surfaces}'`
|
|
16
16
|
3. Run `npx extension@latest create <name> --template=<best-match>`
|
|
17
17
|
4. Report what was created and suggest `npm run dev`
|
|
@@ -42,7 +42,7 @@ Parse the user's intent from `$ARGUMENTS` and execute the matching action:
|
|
|
42
42
|
|
|
43
43
|
### "debug" or "inspect", Debug a running extension
|
|
44
44
|
|
|
45
|
-
1. If MCP tool `
|
|
45
|
+
1. If MCP tool `extension_inspect` is available, use it with `include: ["html", "console", "extension_roots"]`
|
|
46
46
|
2. If there's a URL mentioned, pass it as the target
|
|
47
47
|
3. If there are CSS selectors mentioned, pass them as `probe`
|
|
48
48
|
4. Report: injected HTML, console errors, extension root state
|
|
@@ -58,7 +58,7 @@ Parse the user's intent from `$ARGUMENTS` and execute the matching action:
|
|
|
58
58
|
|
|
59
59
|
### "template <query>", Search for a template
|
|
60
60
|
|
|
61
|
-
1. If MCP tool `
|
|
61
|
+
1. If MCP tool `extension_templates` is available, use it with the query
|
|
62
62
|
2. Otherwise, search the catalog JSON
|
|
63
63
|
3. Show matching templates with slug, description, framework, and surfaces
|
|
64
64
|
|