@extension.dev/mcp 4.5.0 → 4.6.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.
@@ -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": "4.5.0",
13
+ "version": "4.6.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.5.0",
4
+ "version": "4.6.0",
5
5
  "author": {
6
6
  "name": "Cezar Augusto",
7
7
  "email": "boss@cezaraugusto.net",
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.6.0
4
+
5
+ New `extension_deploy` tool (31 tools total): submit a built extension to the
6
+ Chrome Web Store, Firefox AMO, and Edge Add-ons by driving the standalone
7
+ `@extension.dev/deploy` CLI. Store targets are inferred from the `.zip` paths
8
+ you pass. It defaults to a dry run, and store credentials are read from the
9
+ environment or a `.env.submit` file, never from tool arguments, so secrets
10
+ never enter the agent transcript.
11
+
3
12
  ## 4.5.0
4
13
 
5
14
  The platform client (GitHub device-code login, the credential store, and the
package/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  > Give your AI agent hands for browser extension development. 30 MCP tools that scaffold, run, inspect, debug, and publish cross-browser extensions.
11
11
 
12
- <img alt="Logo" align="right" src="https://media.extension.land/brand/extension-dev/logo-dock.png" width="15.5%" />
12
+ <img alt="Logo" align="right" src="https://media.extension.land/brand/extension-dev/logo-dock.png" width="20.7%" />
13
13
 
14
14
  ```bash
15
15
  claude mcp add extension-dev npx @extension.dev/mcp
@@ -121,12 +121,13 @@ cp node_modules/@extension.dev/mcp/claude/commands/*.md ~/my-extension/.claude/c
121
121
  | platform | `extension_logout` | Remove stored credentials |
122
122
  | platform | `extension_publish` | Publish a shareable preview to extension.dev |
123
123
  | platform | `extension_release_promote` | Promote a build to a release channel, headless |
124
+ | platform | `extension_deploy` | Submit to the Chrome, Firefox, and Edge stores (wraps `@extension.dev/deploy`) |
124
125
 
125
126
  Browser-launching tools (`dev`, `start`, `preview`) 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.
126
127
 
127
128
  ## From preview to store
128
129
 
129
- The four platform tools connect agents to [extension.dev](https://extension.dev): `extension_login` runs a GitHub device-code flow and stores a project-scoped token locally (never returned to the agent), `extension_publish` turns a build into a shareable preview URL, and `extension_release_promote` promotes a tested build to a release channel from CI or an agent session, no browser required. To automate store submission itself (Chrome Web Store, Edge Add-ons, Firefox AMO), pair with [`@extension.dev/deploy`](https://www.npmjs.com/package/@extension.dev/deploy).
130
+ The platform tools connect agents to [extension.dev](https://extension.dev): `extension_login` runs a GitHub device-code flow and stores a project-scoped token locally (never returned to the agent), `extension_publish` turns a build into a shareable preview URL, and `extension_release_promote` promotes a tested build to a release channel from CI or an agent session, no browser required. `extension_deploy` submits the built `.zip` to the Chrome Web Store, Edge Add-ons, and Firefox AMO by driving the standalone [`@extension.dev/deploy`](https://www.npmjs.com/package/@extension.dev/deploy) CLI — it defaults to a dry run and reads store credentials from the environment or a `.env.submit` file, never from tool arguments.
130
131
 
131
132
  ## The extension.dev stack
132
133
 
package/dist/module.js CHANGED
@@ -32,6 +32,13 @@ __webpack_require__.d(create_namespaceObject, {
32
32
  handler: ()=>create_handler,
33
33
  schema: ()=>create_schema
34
34
  });
35
+ var deploy_namespaceObject = {};
36
+ __webpack_require__.r(deploy_namespaceObject);
37
+ __webpack_require__.d(deploy_namespaceObject, {
38
+ buildDeployArgs: ()=>buildDeployArgs,
39
+ handler: ()=>deploy_handler,
40
+ schema: ()=>deploy_schema
41
+ });
35
42
  var detect_browsers_namespaceObject = {};
36
43
  __webpack_require__.r(detect_browsers_namespaceObject);
37
44
  __webpack_require__.d(detect_browsers_namespaceObject, {
@@ -3146,6 +3153,169 @@ async function release_promote_handler(args) {
3146
3153
  if (!res.ok) return fail("ReleaseError", `promote failed (${res.status}): ${data?.message || text || "unknown error"}`);
3147
3154
  return JSON.stringify(data);
3148
3155
  }
3156
+ const DEFAULT_DEPLOY_VERSION = "1.2.1";
3157
+ function pinnedDeployVersion() {
3158
+ return String(process.env.EXTENSION_DEPLOY_VERSION || "").trim() || DEFAULT_DEPLOY_VERSION;
3159
+ }
3160
+ function buildDeployArgs(args) {
3161
+ const argv = [];
3162
+ const pushValue = (flag, value)=>{
3163
+ if (void 0 === value || "" === value) return;
3164
+ argv.push(flag, String(value));
3165
+ };
3166
+ if (false !== args.dryRun) argv.push("--dry-run");
3167
+ pushValue("--chrome-zip", args.chromeZip);
3168
+ pushValue("--chrome-extension-id", args.chromeExtensionId);
3169
+ pushValue("--chrome-publisher-id", args.chromePublisherId);
3170
+ if (args.stagedPublish) argv.push("--chrome-staged-publish");
3171
+ pushValue("--chrome-deploy-percentage", args.chromeDeployPercentage);
3172
+ if (args.chromeSkipSubmitReview) argv.push("--chrome-skip-submit-review");
3173
+ pushValue("--firefox-zip", args.firefoxZip);
3174
+ pushValue("--firefox-sources-zip", args.firefoxSourcesZip);
3175
+ pushValue("--firefox-extension-id", args.firefoxExtensionId);
3176
+ pushValue("--firefox-channel", args.firefoxChannel);
3177
+ pushValue("--edge-zip", args.edgeZip);
3178
+ pushValue("--edge-product-id", args.edgeProductId);
3179
+ if (args.edgeSkipSubmitReview) argv.push("--edge-skip-submit-review");
3180
+ pushValue("--output-json", args.outputJson);
3181
+ return argv;
3182
+ }
3183
+ const deploy_schema = {
3184
+ name: "extension_deploy",
3185
+ description: "Submit a built extension to the Chrome Web Store, Firefox AMO, and/or Edge Add-ons by driving the standalone @extension.dev/deploy CLI. Provide the built .zip path(s); the target stores are inferred from which zips you pass. DEFAULTS TO A DRY RUN (verifies auth and inputs, uploads nothing) - pass dryRun:false to actually submit, which is irreversible and enters store review. Store CREDENTIALS are NOT arguments: set them in the environment or a .env.submit file in projectPath (CHROME_CLIENT_ID/CHROME_CLIENT_SECRET/CHROME_REFRESH_TOKEN or CHROME_SERVICE_ACCOUNT_JSON; FIREFOX_JWT_ISSUER/FIREFOX_JWT_SECRET; EDGE_CLIENT_ID/EDGE_API_KEY). Runs `npx @extension.dev/deploy`.",
3186
+ inputSchema: {
3187
+ type: "object",
3188
+ properties: {
3189
+ projectPath: {
3190
+ type: "string",
3191
+ description: "Working directory. Relative zip paths and a .env.submit credential file are resolved from here."
3192
+ },
3193
+ chromeZip: {
3194
+ type: "string",
3195
+ description: "Path to the built Chrome extension .zip"
3196
+ },
3197
+ chromeExtensionId: {
3198
+ type: "string",
3199
+ description: "Chrome extension ID (or set CHROME_EXTENSION_ID)"
3200
+ },
3201
+ chromePublisherId: {
3202
+ type: "string",
3203
+ description: "Chrome publisher UUID (or set CHROME_PUBLISHER_ID)"
3204
+ },
3205
+ firefoxZip: {
3206
+ type: "string",
3207
+ description: "Path to the built Firefox extension .zip"
3208
+ },
3209
+ firefoxSourcesZip: {
3210
+ type: "string",
3211
+ description: "Path to the Firefox sources .zip (optional)"
3212
+ },
3213
+ firefoxExtensionId: {
3214
+ type: "string",
3215
+ description: "Firefox add-on GUID or email-style ID"
3216
+ },
3217
+ firefoxChannel: {
3218
+ type: "string",
3219
+ enum: [
3220
+ "listed",
3221
+ "unlisted"
3222
+ ],
3223
+ description: "Firefox channel (unlisted is required for a first submission)"
3224
+ },
3225
+ edgeZip: {
3226
+ type: "string",
3227
+ description: "Path to the built Edge extension .zip"
3228
+ },
3229
+ edgeProductId: {
3230
+ type: "string",
3231
+ description: "Edge Partner Center product ID (or set EDGE_PRODUCT_ID)"
3232
+ },
3233
+ dryRun: {
3234
+ type: "boolean",
3235
+ default: true,
3236
+ description: "Verify auth and inputs without uploading or publishing. Pass false to actually submit (irreversible)."
3237
+ },
3238
+ stagedPublish: {
3239
+ type: "boolean",
3240
+ default: false,
3241
+ description: "Chrome: publish as STAGED_PUBLISH so the rollout can be raised review-free later."
3242
+ },
3243
+ chromeDeployPercentage: {
3244
+ type: "number",
3245
+ description: "Chrome staged rollout percentage (1-100)."
3246
+ },
3247
+ chromeSkipSubmitReview: {
3248
+ type: "boolean",
3249
+ default: false,
3250
+ description: "Chrome: upload only, skip the publish/submit-for-review step."
3251
+ },
3252
+ edgeSkipSubmitReview: {
3253
+ type: "boolean",
3254
+ default: false,
3255
+ description: "Edge: upload only, skip the publish/submit-for-review step."
3256
+ },
3257
+ outputJson: {
3258
+ type: "string",
3259
+ description: "Write the machine-readable DeployResult JSON to this path."
3260
+ }
3261
+ },
3262
+ required: [
3263
+ "projectPath"
3264
+ ]
3265
+ }
3266
+ };
3267
+ async function deploy_handler(args) {
3268
+ if (!args.chromeZip && !args.firefoxZip && !args.edgeZip) return JSON.stringify({
3269
+ ok: false,
3270
+ error: {
3271
+ name: "DeployInputError",
3272
+ message: "No store targets. Provide at least one of chromeZip, firefoxZip, or edgeZip."
3273
+ }
3274
+ });
3275
+ const version = pinnedDeployVersion();
3276
+ const argv = [
3277
+ "--yes",
3278
+ `@extension.dev/deploy@${version}`,
3279
+ ...buildDeployArgs(args)
3280
+ ];
3281
+ return new Promise((resolve)=>{
3282
+ const child = cross_spawn("npx", argv, {
3283
+ cwd: args.projectPath,
3284
+ stdio: [
3285
+ "ignore",
3286
+ "pipe",
3287
+ "pipe"
3288
+ ],
3289
+ env: {
3290
+ ...process.env,
3291
+ FORCE_COLOR: "0",
3292
+ NO_COLOR: "1"
3293
+ }
3294
+ });
3295
+ let stdout = "";
3296
+ let stderr = "";
3297
+ child.stdout?.on("data", (d)=>stdout += d.toString());
3298
+ child.stderr?.on("data", (d)=>stderr += d.toString());
3299
+ child.on("close", (code)=>{
3300
+ resolve(JSON.stringify({
3301
+ ok: 0 === code,
3302
+ dryRun: false !== args.dryRun,
3303
+ code,
3304
+ stdout: stdout.trim(),
3305
+ stderr: stderr.trim()
3306
+ }));
3307
+ });
3308
+ child.on("error", (err)=>{
3309
+ resolve(JSON.stringify({
3310
+ ok: false,
3311
+ error: {
3312
+ name: "DeploySpawnError",
3313
+ message: `Could not run extension-deploy: ${err instanceof Error ? err.message : String(err)}`
3314
+ }
3315
+ }));
3316
+ });
3317
+ });
3318
+ }
3149
3319
  const wait_schema = {
3150
3320
  name: "extension_wait",
3151
3321
  description: "Wait for a running dev or start session to be ready. Polls the ready.json contract file and returns structured status.",
@@ -4295,6 +4465,7 @@ const tools = [
4295
4465
  dom_inspect_namespaceObject,
4296
4466
  tools_publish_namespaceObject,
4297
4467
  release_promote_namespaceObject,
4468
+ deploy_namespaceObject,
4298
4469
  wait_namespaceObject,
4299
4470
  add_feature_namespaceObject,
4300
4471
  login_namespaceObject,
@@ -0,0 +1,104 @@
1
+ export interface DeployToolArgs {
2
+ projectPath: string;
3
+ chromeZip?: string;
4
+ chromeExtensionId?: string;
5
+ chromePublisherId?: string;
6
+ firefoxZip?: string;
7
+ firefoxSourcesZip?: string;
8
+ firefoxExtensionId?: string;
9
+ firefoxChannel?: "listed" | "unlisted";
10
+ edgeZip?: string;
11
+ edgeProductId?: string;
12
+ dryRun?: boolean;
13
+ stagedPublish?: boolean;
14
+ chromeDeployPercentage?: number;
15
+ chromeSkipSubmitReview?: boolean;
16
+ edgeSkipSubmitReview?: boolean;
17
+ outputJson?: string;
18
+ }
19
+ /**
20
+ * Build the extension-deploy argv from tool arguments. Pure and exported so the
21
+ * flag mapping is unit-tested without spawning a process. Never emits a
22
+ * credential flag - secrets come from the environment / .env.submit.
23
+ */
24
+ export declare function buildDeployArgs(args: DeployToolArgs): string[];
25
+ export declare const schema: {
26
+ name: string;
27
+ description: string;
28
+ inputSchema: {
29
+ type: "object";
30
+ properties: {
31
+ projectPath: {
32
+ type: string;
33
+ description: string;
34
+ };
35
+ chromeZip: {
36
+ type: string;
37
+ description: string;
38
+ };
39
+ chromeExtensionId: {
40
+ type: string;
41
+ description: string;
42
+ };
43
+ chromePublisherId: {
44
+ type: string;
45
+ description: string;
46
+ };
47
+ firefoxZip: {
48
+ type: string;
49
+ description: string;
50
+ };
51
+ firefoxSourcesZip: {
52
+ type: string;
53
+ description: string;
54
+ };
55
+ firefoxExtensionId: {
56
+ type: string;
57
+ description: string;
58
+ };
59
+ firefoxChannel: {
60
+ type: string;
61
+ enum: string[];
62
+ description: string;
63
+ };
64
+ edgeZip: {
65
+ type: string;
66
+ description: string;
67
+ };
68
+ edgeProductId: {
69
+ type: string;
70
+ description: string;
71
+ };
72
+ dryRun: {
73
+ type: string;
74
+ default: boolean;
75
+ description: string;
76
+ };
77
+ stagedPublish: {
78
+ type: string;
79
+ default: boolean;
80
+ description: string;
81
+ };
82
+ chromeDeployPercentage: {
83
+ type: string;
84
+ description: string;
85
+ };
86
+ chromeSkipSubmitReview: {
87
+ type: string;
88
+ default: boolean;
89
+ description: string;
90
+ };
91
+ edgeSkipSubmitReview: {
92
+ type: string;
93
+ default: boolean;
94
+ description: string;
95
+ };
96
+ outputJson: {
97
+ type: string;
98
+ description: string;
99
+ };
100
+ };
101
+ required: string[];
102
+ };
103
+ };
104
+ export declare function handler(args: DeployToolArgs): Promise<string>;
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@extension.dev/mcp",
3
3
  "type": "module",
4
- "version": "4.5.0",
5
- "description": "MCP server that lets AI agents (Claude Code, Claude Desktop, Cursor, Copilot, Codex) build, run, inspect, and publish browser extensions. 30 tools for scaffolding, live DOM inspection, log streaming, and store-ready builds across Chrome, Edge, Firefox, Safari, and every Chromium- or Gecko-based browser (Brave, Opera, Vivaldi, Yandex, Waterfox, LibreWolf). Powered by extension.dev and Extension.js.",
4
+ "version": "4.6.0",
5
+ "description": "MCP server that lets AI agents (Claude Code, Claude Desktop, Cursor, Copilot, Codex) build, run, inspect, and publish browser extensions. 31 tools for scaffolding, live DOM inspection, log streaming, and store-ready builds across Chrome, Edge, Firefox, Safari, and every Chromium- or Gecko-based browser (Brave, Opera, Vivaldi, Yandex, Waterfox, LibreWolf). Powered by extension.dev and Extension.js.",
6
6
  "mcpName": "io.github.extensiondev/mcp",
7
7
  "license": "MIT",
8
8
  "author": {
package/server.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json",
3
3
  "name": "io.github.extensiondev/mcp",
4
- "description": "Build, run, inspect, and publish browser extensions from any MCP client. 30 tools, 11 browsers.",
4
+ "description": "Build, run, inspect, and publish browser extensions from any MCP client. 31 tools, 11 browsers.",
5
5
  "repository": {
6
6
  "url": "https://github.com/extensiondev/mcp",
7
7
  "source": "github"
8
8
  },
9
9
  "websiteUrl": "https://extension.dev",
10
- "version": "4.5.0",
10
+ "version": "4.6.0",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "registryBaseUrl": "https://registry.npmjs.org",
15
15
  "identifier": "@extension.dev/mcp",
16
- "version": "4.5.0",
16
+ "version": "4.6.0",
17
17
  "runtimeHint": "npx",
18
18
  "transport": {
19
19
  "type": "stdio"