@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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +9 -0
- package/README.md +3 -2
- package/dist/module.js +171 -0
- package/dist/src/tools/deploy.d.ts +104 -0
- package/package.json +2 -2
- 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 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.
|
|
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.
|
|
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="
|
|
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
|
|
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
|
-
"description": "MCP server that lets AI agents (Claude Code, Claude Desktop, Cursor, Copilot, Codex) build, run, inspect, and publish browser extensions.
|
|
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.
|
|
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.
|
|
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.
|
|
16
|
+
"version": "4.6.0",
|
|
17
17
|
"runtimeHint": "npx",
|
|
18
18
|
"transport": {
|
|
19
19
|
"type": "stdio"
|