@extension.dev/mcp 10.10.3 → 10.10.4

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 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.3",
13
+ "version": "10.10.4",
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.3",
4
+ "version": "10.10.4",
5
5
  "author": {
6
6
  "name": "Cezar Augusto",
7
7
  "email": "hello@extension.dev",
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## 10.10.4
4
+
5
+ - `--project <workspace>/<project>` (env `EXTENSION_DEV_PROJECT`) pins a
6
+ server to one project. Every unnamed credential read takes that
7
+ project's login instead of the most recent one, an agent signed in to
8
+ several projects can no longer act on the wrong one, and a call that
9
+ names a different project is refused with `status: "project-pinned"`.
10
+ A pinned project with no stored login falls back to
11
+ `EXTENSION_DEV_TOKEN`, so CI keeps working.
12
+ - New `@extension.dev/mcp/clients` export: `CLIENTS` and
13
+ `buildRecipe({ client, reach, strictApproval, project })` build the
14
+ exact setup for Claude Code, Cursor, VS Code, Codex and any
15
+ `mcpServers` client. The README's Setup section is generated from it
16
+ (`pnpm readme:clients`, checked by a spec), and the extension.dev
17
+ console's Connect dialog renders the same recipes, so the instructions
18
+ cannot drift. It never emits a setting that turns approvals off.
19
+
3
20
  ## 10.10.3
4
21
 
5
22
  - The engine pin moves off the canary to Extension.js `4.1.31` stable:
package/README.md CHANGED
@@ -45,10 +45,12 @@ Built on [Extension.js](https://extension.js.org), the open-source cross-browser
45
45
 
46
46
  ## Setup
47
47
 
48
+ <!-- setup:start (generated from src/clients, run pnpm readme:clients) -->
49
+
48
50
  ### Claude Code
49
51
 
50
52
  ```bash
51
- claude mcp add extension-dev npx @extension.dev/mcp
53
+ claude mcp add extension-dev -- npx @extension.dev/mcp
52
54
  ```
53
55
 
54
56
  Or install it as a plugin, the MCP server plus the `/extension`, `/extension-add`, `/extension-debug`, and `/extension-publish` commands in one step:
@@ -62,19 +64,84 @@ Or install it as a plugin, the MCP server plus the `/extension`, `/extension-add
62
64
 
63
65
  [![Install MCP Server](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en/install-mcp?name=extension-dev&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyJAZXh0ZW5zaW9uLmRldi9tY3AiXX0%3D)
64
66
 
65
- ### Claude Desktop / `.mcp.json`
67
+ `.cursor/mcp.json`:
66
68
 
67
69
  ```json
68
70
  {
69
71
  "mcpServers": {
70
72
  "extension-dev": {
71
73
  "command": "npx",
72
- "args": ["@extension.dev/mcp"]
74
+ "args": [
75
+ "@extension.dev/mcp"
76
+ ]
73
77
  }
74
78
  }
75
79
  }
76
80
  ```
77
81
 
82
+ ### VS Code (Also GitHub Copilot)
83
+
84
+ ```bash
85
+ code --add-mcp '{"name":"extension-dev","command":"npx","args":["@extension.dev/mcp"]}'
86
+ ```
87
+
88
+ `.vscode/mcp.json`:
89
+
90
+ ```json
91
+ {
92
+ "servers": {
93
+ "extension-dev": {
94
+ "type": "stdio",
95
+ "command": "npx",
96
+ "args": [
97
+ "@extension.dev/mcp"
98
+ ]
99
+ }
100
+ }
101
+ }
102
+ ```
103
+
104
+ ### Codex
105
+
106
+ ```bash
107
+ codex mcp add extension-dev -- npx @extension.dev/mcp
108
+ ```
109
+
110
+ `~/.codex/config.toml`:
111
+
112
+ ```toml
113
+ [mcp_servers.extension-dev]
114
+ command = "npx"
115
+ args = ["@extension.dev/mcp"]
116
+ ```
117
+
118
+ ### Other clients (Claude Desktop and .mcp.json)
119
+
120
+ `.mcp.json`:
121
+
122
+ ```json
123
+ {
124
+ "mcpServers": {
125
+ "extension-dev": {
126
+ "command": "npx",
127
+ "args": [
128
+ "@extension.dev/mcp"
129
+ ]
130
+ }
131
+ }
132
+ }
133
+ ```
134
+
135
+ ### Signing in and pinning a project
136
+
137
+ The platform tools need a login. Sign in once per project, then add `--project <workspace>/<project>` to the server's arguments (or set `EXTENSION_DEV_PROJECT`) so that server only ever acts on that project, however many logins this machine holds. The console's Connect dialog fills both in for your project.
138
+
139
+ ```bash
140
+ npx @extension.dev/mcp login --project <workspace>/<project>
141
+ ```
142
+
143
+ <!-- setup:end -->
144
+
78
145
  ### Choosing what the agent can reach
79
146
 
80
147
  Two flags (or environment variables) narrow the server before an agent sees it:
@@ -27,6 +27,7 @@ Server flags:
27
27
  --features=local,platform Tool groups to expose (default: both)
28
28
  --no-ship Refuse publish, promote, real submits,
29
29
  share links and share revokes
30
+ --project <workspace>/<proj> Use only this project's login
30
31
  `
31
32
 
32
33
  const [, , cmd, ...rest] = process.argv
@@ -0,0 +1,157 @@
1
+ const CLIENTS = [
2
+ {
3
+ id: "claude-code",
4
+ label: "Claude Code"
5
+ },
6
+ {
7
+ id: "cursor",
8
+ label: "Cursor"
9
+ },
10
+ {
11
+ id: "vscode",
12
+ label: "VS Code",
13
+ subtitle: "Also GitHub Copilot"
14
+ },
15
+ {
16
+ id: "codex",
17
+ label: "Codex"
18
+ },
19
+ {
20
+ id: "json",
21
+ label: "Other clients",
22
+ subtitle: "Claude Desktop and .mcp.json"
23
+ }
24
+ ];
25
+ const SERVER_NAME = "extension-dev";
26
+ const PACKAGE = "@extension.dev/mcp";
27
+ function serverArgs(input) {
28
+ const args = [
29
+ PACKAGE
30
+ ];
31
+ if ("local" !== input.reach && input.project) args.push("--project", input.project);
32
+ if ("no-ship" === input.reach) args.push("--no-ship");
33
+ if ("local" === input.reach) args.push("--features=local");
34
+ return args;
35
+ }
36
+ function serverEnv(input) {
37
+ return "everything" === input.reach && input.strictApproval ? {
38
+ EXTENSION_DEV_APPROVAL_GATE: "1"
39
+ } : {};
40
+ }
41
+ const shellQuote = (value)=>/^[A-Za-z0-9_@%+=:,./-]+$/.test(value) ? value : `'${value.replace(/'/g, "'\\''")}'`;
42
+ const base64 = (text)=>"function" == typeof btoa ? btoa(text) : globalThis.Buffer.from(text).toString("base64");
43
+ const tomlString = (value)=>JSON.stringify(value);
44
+ function loginCommand(project) {
45
+ return `npx ${PACKAGE} login --project ${shellQuote(project)}`;
46
+ }
47
+ function buildRecipe(input) {
48
+ const args = serverArgs(input);
49
+ const env = serverEnv(input);
50
+ const envEntries = Object.entries(env);
51
+ const stdio = {
52
+ command: "npx",
53
+ args,
54
+ ...envEntries.length ? {
55
+ env
56
+ } : {}
57
+ };
58
+ const login = loginCommand(input.project);
59
+ const argLine = args.map(shellQuote).join(" ");
60
+ switch(input.client){
61
+ case "claude-code":
62
+ return {
63
+ client: "claude-code",
64
+ command: [
65
+ "claude mcp add",
66
+ SERVER_NAME,
67
+ ...envEntries.map(([k, v])=>`-e ${k}=${shellQuote(v)}`),
68
+ "-- npx",
69
+ argLine
70
+ ].join(" "),
71
+ login
72
+ };
73
+ case "cursor":
74
+ return {
75
+ client: "cursor",
76
+ deeplink: `https://cursor.com/en/install-mcp?name=${SERVER_NAME}&config=${encodeURIComponent(base64(JSON.stringify(stdio)))}`,
77
+ config: {
78
+ language: "json",
79
+ path: ".cursor/mcp.json",
80
+ text: JSON.stringify({
81
+ mcpServers: {
82
+ [SERVER_NAME]: stdio
83
+ }
84
+ }, null, 2)
85
+ },
86
+ login
87
+ };
88
+ case "vscode":
89
+ {
90
+ const named = {
91
+ name: SERVER_NAME,
92
+ ...stdio
93
+ };
94
+ return {
95
+ client: "vscode",
96
+ command: `code --add-mcp ${shellQuote(JSON.stringify(named))}`,
97
+ deeplink: `vscode:mcp/install?${encodeURIComponent(JSON.stringify(named))}`,
98
+ config: {
99
+ language: "json",
100
+ path: ".vscode/mcp.json",
101
+ text: JSON.stringify({
102
+ servers: {
103
+ [SERVER_NAME]: {
104
+ type: "stdio",
105
+ ...stdio
106
+ }
107
+ }
108
+ }, null, 2)
109
+ },
110
+ login
111
+ };
112
+ }
113
+ case "codex":
114
+ {
115
+ const lines = [
116
+ `[mcp_servers.${SERVER_NAME}]`,
117
+ 'command = "npx"',
118
+ `args = [${args.map(tomlString).join(", ")}]`
119
+ ];
120
+ if (envEntries.length) {
121
+ lines.push("", `[mcp_servers.${SERVER_NAME}.env]`);
122
+ for (const [k, v] of envEntries)lines.push(`${k} = ${tomlString(v)}`);
123
+ }
124
+ return {
125
+ client: "codex",
126
+ command: [
127
+ "codex mcp add",
128
+ SERVER_NAME,
129
+ ...envEntries.map(([k, v])=>`--env ${k}=${shellQuote(v)}`),
130
+ "-- npx",
131
+ argLine
132
+ ].join(" "),
133
+ config: {
134
+ language: "toml",
135
+ path: "~/.codex/config.toml",
136
+ text: lines.join("\n")
137
+ },
138
+ login
139
+ };
140
+ }
141
+ case "json":
142
+ return {
143
+ client: "json",
144
+ config: {
145
+ language: "json",
146
+ path: ".mcp.json",
147
+ text: JSON.stringify({
148
+ mcpServers: {
149
+ [SERVER_NAME]: stdio
150
+ }
151
+ }, null, 2)
152
+ },
153
+ login
154
+ };
155
+ }
156
+ }
157
+ export { CLIENTS, PACKAGE, SERVER_NAME, buildRecipe, loginCommand, serverArgs, serverEnv };
package/dist/module.js CHANGED
@@ -236,7 +236,7 @@ __webpack_require__.d(workspace_create_namespaceObject, {
236
236
  handler: ()=>workspace_create_handler,
237
237
  schema: ()=>workspace_create_schema
238
238
  });
239
- var package_namespaceObject = JSON.parse('{"rE":"10.10.3","El":{"OP":"4.1.31"}}');
239
+ var package_namespaceObject = JSON.parse('{"rE":"10.10.4","El":{"OP":"4.1.31"}}');
240
240
  const ENVELOPE_SCHEMA = 1;
241
241
  const collectWarnings = (warnings)=>{
242
242
  if (!warnings) return [];
@@ -509,8 +509,20 @@ function readCredentialStore() {
509
509
  entries
510
510
  };
511
511
  }
512
+ const PROJECT_PIN_ENV = "EXTENSION_DEV_PROJECT";
513
+ function pinnedProject() {
514
+ return String(process.env[PROJECT_PIN_ENV] || "").trim().toLowerCase();
515
+ }
516
+ function isProjectRef(value) {
517
+ return /^[a-z0-9][a-z0-9-_.]*\/[a-z0-9][a-z0-9-_.]*$/i.test(value);
518
+ }
519
+ function sameProject(named, pinned) {
520
+ const a = named.trim().toLowerCase();
521
+ if (!a || !pinned) return true;
522
+ return a.includes("/") ? a === pinned : a === pinned.split("/")[1];
523
+ }
512
524
  function selectEntry(store, selector) {
513
- const wanted = String(selector?.project ?? "").trim().toLowerCase();
525
+ const wanted = (String(selector?.project ?? "").trim() || pinnedProject()).toLowerCase();
514
526
  if (!wanted) return store.active && store.entries[store.active] || Object.values(store.entries)[0] || null;
515
527
  if (wanted.includes("/")) return store.entries[wanted] ?? null;
516
528
  const bySlug = Object.values(store.entries).filter((entry)=>entry.projectSlug.toLowerCase() === wanted);
@@ -7921,12 +7933,15 @@ async function openSidebarThroughGesture(projectPath, browser, refusal) {
7921
7933
  return actFrameJson(refusal);
7922
7934
  }
7923
7935
  function resolveToken(options = {}) {
7924
- const project = String(options.project ?? "").trim();
7936
+ const named = String(options.project ?? "").trim();
7937
+ const project = named || pinnedProject();
7925
7938
  if (project) {
7926
7939
  const creds = readValidCredentials(void 0, {
7927
7940
  project
7928
7941
  });
7929
- return creds?.token ? String(creds.token).trim() : "";
7942
+ if (creds?.token) return String(creds.token).trim();
7943
+ if (named) return "";
7944
+ return String(process.env.EXTENSION_DEV_TOKEN || "").trim();
7930
7945
  }
7931
7946
  const fromEnv = String(process.env.EXTENSION_DEV_TOKEN || "").trim();
7932
7947
  if (fromEnv) return fromEnv;
@@ -18058,30 +18073,41 @@ const truthy = (raw)=>{
18058
18073
  return "" !== value && "0" !== value && "false" !== value && "off" !== value;
18059
18074
  };
18060
18075
  function isServerFlag(arg) {
18061
- return "--no-ship" === arg || "--features" === arg || arg.startsWith("--features=");
18076
+ return "--no-ship" === arg || "--features" === arg || arg.startsWith("--features=") || "--project" === arg || arg.startsWith("--project=");
18062
18077
  }
18063
18078
  function resolveServerOptions(argv, env) {
18064
18079
  let rawFeatures = env[FEATURES_ENV];
18065
18080
  let noShip = truthy(env[NO_SHIP_ENV]);
18081
+ let project = String(env[PROJECT_PIN_ENV] || "").trim().toLowerCase();
18066
18082
  for(let i = 0; i < argv.length; i++){
18067
18083
  const arg = argv[i];
18068
18084
  if ("--no-ship" === arg) noShip = true;
18069
18085
  else if ("--features" === arg) rawFeatures = argv[++i] ?? "";
18086
+ else if (arg.startsWith("--features=")) rawFeatures = arg.slice(11);
18087
+ else if ("--project" === arg) project = String(argv[++i] ?? "").trim().toLowerCase();
18070
18088
  else {
18071
- if (!arg.startsWith("--features=")) return {
18089
+ if (!arg.startsWith("--project=")) return {
18072
18090
  ok: false,
18073
18091
  message: `Unknown flag "${arg}".`
18074
18092
  };
18075
- rawFeatures = arg.slice(11);
18093
+ project = arg.slice(10).trim().toLowerCase();
18076
18094
  }
18077
18095
  }
18096
+ if (project && !isProjectRef(project)) return {
18097
+ ok: false,
18098
+ message: `--project takes "<workspace>/<project>", got "${project}".`
18099
+ };
18100
+ const pin = project ? {
18101
+ project
18102
+ } : {};
18078
18103
  if (void 0 === rawFeatures || "" === rawFeatures.trim()) return {
18079
18104
  ok: true,
18080
18105
  options: {
18081
18106
  features: [
18082
18107
  ...FEATURE_GROUPS
18083
18108
  ],
18084
- noShip
18109
+ noShip,
18110
+ ...pin
18085
18111
  }
18086
18112
  };
18087
18113
  const names = rawFeatures.split(",").map((name)=>name.trim().toLowerCase()).filter(Boolean);
@@ -18095,7 +18121,8 @@ function resolveServerOptions(argv, env) {
18095
18121
  ok: true,
18096
18122
  options: {
18097
18123
  features,
18098
- noShip
18124
+ noShip,
18125
+ ...pin
18099
18126
  }
18100
18127
  };
18101
18128
  }
@@ -18138,6 +18165,40 @@ function disabledToolEnvelope(name, args, options) {
18138
18165
  });
18139
18166
  return null;
18140
18167
  }
18168
+ function pinProjectArgs(name, args, inputSchema, options) {
18169
+ const pinned = options.project;
18170
+ if (!pinned) return {
18171
+ args
18172
+ };
18173
+ const named = "string" == typeof args.project ? args.project : "";
18174
+ if (named && !sameProject(named, pinned)) return {
18175
+ refused: envelope_envelope({
18176
+ ok: false,
18177
+ command: name,
18178
+ status: "project-pinned",
18179
+ error: {
18180
+ code: "E_TOOL_DISABLED",
18181
+ message: `This server is pinned to ${pinned} and was asked to act on ${named}.`
18182
+ },
18183
+ value: {
18184
+ pinned,
18185
+ named
18186
+ },
18187
+ hint: `Work on ${named} through an MCP server configured with --project ${named}, or change this server's --project (or ${PROJECT_PIN_ENV}).`
18188
+ })
18189
+ };
18190
+ const properties = inputSchema.properties ?? {};
18191
+ const statusOnly = "extension_auth" === name && "status" === args.action;
18192
+ if (named || statusOnly || !("project" in properties)) return {
18193
+ args
18194
+ };
18195
+ return {
18196
+ args: {
18197
+ ...args,
18198
+ project: pinned
18199
+ }
18200
+ };
18201
+ }
18141
18202
  const tools = [
18142
18203
  create_namespaceObject,
18143
18204
  templates_namespaceObject,
@@ -18235,8 +18296,8 @@ function createServer(options = DEFAULT_SERVER_OPTIONS) {
18235
18296
  ],
18236
18297
  isError: true
18237
18298
  };
18238
- const normalizedArgs = normalizeArgAliases(tool.schema.inputSchema, args ?? {});
18239
- const disabled = disabledToolEnvelope(name, normalizedArgs, options);
18299
+ const aliasedArgs = normalizeArgAliases(tool.schema.inputSchema, args ?? {});
18300
+ const disabled = disabledToolEnvelope(name, aliasedArgs, options);
18240
18301
  if (disabled) return {
18241
18302
  content: [
18242
18303
  {
@@ -18246,6 +18307,17 @@ function createServer(options = DEFAULT_SERVER_OPTIONS) {
18246
18307
  ],
18247
18308
  isError: true
18248
18309
  };
18310
+ const pinned = pinProjectArgs(name, aliasedArgs, tool.schema.inputSchema, options);
18311
+ if ("refused" in pinned) return {
18312
+ content: [
18313
+ {
18314
+ type: "text",
18315
+ text: pinned.refused
18316
+ }
18317
+ ],
18318
+ isError: true
18319
+ };
18320
+ const normalizedArgs = pinned.args;
18249
18321
  const issues = validateToolInput(tool.schema.inputSchema, normalizedArgs);
18250
18322
  if (issues.length) return {
18251
18323
  content: [
@@ -18284,6 +18356,7 @@ function createServer(options = DEFAULT_SERVER_OPTIONS) {
18284
18356
  }
18285
18357
  async function startServer(options = DEFAULT_SERVER_OPTIONS) {
18286
18358
  installCarrierExitCleanup();
18359
+ if (options.project) process.env.EXTENSION_DEV_PROJECT = options.project;
18287
18360
  const server = createServer(options);
18288
18361
  const transport = new StdioServerTransport();
18289
18362
  await server.connect(transport);
@@ -0,0 +1,31 @@
1
+ export type ClientId = "claude-code" | "cursor" | "vscode" | "codex" | "json";
2
+ export type Reach = "everything" | "no-ship" | "local";
3
+ export interface ClientInfo {
4
+ id: ClientId;
5
+ label: string;
6
+ subtitle?: string;
7
+ }
8
+ export declare const CLIENTS: readonly ClientInfo[];
9
+ export interface Recipe {
10
+ client: ClientId;
11
+ command?: string;
12
+ config?: {
13
+ language: "json" | "toml";
14
+ path: string;
15
+ text: string;
16
+ };
17
+ deeplink?: string;
18
+ login: string;
19
+ }
20
+ export interface RecipeInput {
21
+ client: ClientId;
22
+ reach: Reach;
23
+ strictApproval: boolean;
24
+ project: string;
25
+ }
26
+ export declare const SERVER_NAME = "extension-dev";
27
+ export declare const PACKAGE = "@extension.dev/mcp";
28
+ export declare function serverArgs(input: Omit<RecipeInput, "client">): string[];
29
+ export declare function serverEnv(input: Omit<RecipeInput, "client">): Record<string, string>;
30
+ export declare function loginCommand(project: string): string;
31
+ export declare function buildRecipe(input: RecipeInput): Recipe;
@@ -0,0 +1,4 @@
1
+ export declare const README_SETUP_START = "<!-- setup:start (generated from src/clients, run pnpm readme:clients) -->";
2
+ export declare const README_SETUP_END = "<!-- setup:end -->";
3
+ export declare function renderReadmeSetup(): string;
4
+ export declare function spliceReadmeSetup(readme: string): string;
@@ -18,6 +18,10 @@ export interface CredentialSelector {
18
18
  }
19
19
  export declare function credentialKey(workspaceSlug: string, projectSlug: string): string;
20
20
  export declare function readCredentialStore(): CredentialStore | null;
21
+ export declare const PROJECT_PIN_ENV = "EXTENSION_DEV_PROJECT";
22
+ export declare function pinnedProject(): string;
23
+ export declare function isProjectRef(value: string): boolean;
24
+ export declare function sameProject(named: string, pinned: string): boolean;
21
25
  export declare function readCredentials(selector?: CredentialSelector): StoredCredentials | null;
22
26
  export declare function listCredentials(): Array<StoredCredentials & {
23
27
  key: string;
@@ -18,6 +18,7 @@ export declare const TOOL_POLICY: Record<string, ToolPolicy>;
18
18
  export interface ServerOptions {
19
19
  features: FeatureGroup[];
20
20
  noShip: boolean;
21
+ project?: string;
21
22
  }
22
23
  export declare const DEFAULT_SERVER_OPTIONS: ServerOptions;
23
24
  export declare function isServerFlag(arg: string): boolean;
@@ -30,4 +31,9 @@ export declare function resolveServerOptions(argv: string[], env: Record<string,
30
31
  };
31
32
  export declare function isToolListed(name: string, options: ServerOptions): boolean;
32
33
  export declare function disabledToolEnvelope(name: string, args: Args, options: ServerOptions): string | null;
34
+ export declare function pinProjectArgs(name: string, args: Args, inputSchema: Record<string, unknown>, options: ServerOptions): {
35
+ args: Args;
36
+ } | {
37
+ refused: string;
38
+ };
33
39
  export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@extension.dev/mcp",
3
3
  "type": "module",
4
- "version": "10.10.3",
4
+ "version": "10.10.4",
5
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": "Apache-2.0",
@@ -26,6 +26,10 @@
26
26
  ".": {
27
27
  "types": "./dist/module.d.ts",
28
28
  "import": "./dist/module.js"
29
+ },
30
+ "./clients": {
31
+ "types": "./dist/src/clients/index.d.ts",
32
+ "import": "./dist/clients.js"
29
33
  }
30
34
  },
31
35
  "main": "./dist/module.js",
@@ -46,6 +50,7 @@
46
50
  ],
47
51
  "scripts": {
48
52
  "clean": "rm -rf dist",
53
+ "readme:clients": "UPDATE_README=1 vitest run src/__tests__/readme-clients.test.ts",
49
54
  "watch": "rslib build --watch",
50
55
  "compile": "rslib build",
51
56
  "build": "pnpm run compile",
package/server.json CHANGED
@@ -7,13 +7,13 @@
7
7
  "source": "github"
8
8
  },
9
9
  "websiteUrl": "https://extension.dev",
10
- "version": "10.10.3",
10
+ "version": "10.10.4",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "registryBaseUrl": "https://registry.npmjs.org",
15
15
  "identifier": "@extension.dev/mcp",
16
- "version": "10.10.3",
16
+ "version": "10.10.4",
17
17
  "runtimeHint": "npx",
18
18
  "transport": {
19
19
  "type": "stdio"