@extension.dev/mcp 6.1.0 → 6.3.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.
@@ -1,3 +1,4 @@
1
+ var __webpack_modules__ = {};
1
2
  var __webpack_module_cache__ = {};
2
3
  function __webpack_require__(moduleId) {
3
4
  var cachedModule = __webpack_module_cache__[moduleId];
@@ -8,6 +9,7 @@ function __webpack_require__(moduleId) {
8
9
  __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
9
10
  return module.exports;
10
11
  }
12
+ __webpack_require__.m = __webpack_modules__;
11
13
  (()=>{
12
14
  __webpack_require__.add = function(modules) {
13
15
  Object.assign(__webpack_require__.m, modules);
@@ -0,0 +1,45 @@
1
+ import type { ProjectRef } from "./registry";
2
+ export type AccessGrant = {
3
+ status: "ok";
4
+ token: string;
5
+ expiresAt: number;
6
+ }
7
+ /** Project is public; no token is needed and none was minted. */
8
+ | {
9
+ status: "public";
10
+ }
11
+ /** No stored credential, or it does not cover the requested project. */
12
+ | {
13
+ status: "no-credential";
14
+ }
15
+ /** Reached the platform and it refused (401/403/5xx, network, bad body). */
16
+ | {
17
+ status: "denied";
18
+ httpStatus?: number;
19
+ message: string;
20
+ };
21
+ export interface AccessTokenCacheOptions {
22
+ fetchImpl?: typeof fetch;
23
+ /** Test-only clock override, unix epoch seconds. */
24
+ nowSeconds?: () => number;
25
+ }
26
+ /**
27
+ * Per-process cache of minted tokens. Concurrent readers of the same project
28
+ * share one in-flight mint: a single tool call fans out over meta.json,
29
+ * channels.json and builds/index.json, and three cold 401s must not become
30
+ * three mint round-trips.
31
+ */
32
+ export declare class RegistryAccessTokens {
33
+ private readonly cache;
34
+ private readonly fetchImpl;
35
+ private readonly nowSeconds;
36
+ constructor(options?: AccessTokenCacheOptions);
37
+ /** A cached, still-valid token, or "" if none. Never mints. */
38
+ peek(ref: ProjectRef): string;
39
+ get(ref: ProjectRef, apiHint?: string): Promise<AccessGrant>;
40
+ private mint;
41
+ }
42
+ /** Process-wide default, so one tool call's fan-out shares one mint. */
43
+ export declare const defaultRegistryAccessTokens: RegistryAccessTokens;
44
+ /** Append `?t=<token>` to a registry URL. */
45
+ export declare function withAccessToken(url: string, token: string): string;
@@ -1,4 +1,5 @@
1
- import { type Origins } from "./urls-origins";
1
+ import { type RegistryAccessTokens } from "./registry-access";
2
+ import { type Origins } from "@extension.dev/urls/origins";
2
3
  export declare const REGISTRY_BASE_DEFAULT: string;
3
4
  /**
4
5
  * Resolve the fleet origins from the MCP's env vars, once per call. Console,
@@ -7,7 +8,7 @@ export declare const REGISTRY_BASE_DEFAULT: string;
7
8
  * MCP hands back follows to the dev host (`console.extension.localhost`) instead
8
9
  * of silently pointing at prod. Explicit per-host env vars still win. Falls back
9
10
  * to production when nothing is set. The dev-derivation lives in
10
- * `@extensiondev/urls` so it stays identical to what the apps resolve.
11
+ * `@extension.dev/urls` so it stays identical to what the apps resolve.
11
12
  */
12
13
  export declare function mcpOrigins(apiHint?: string): Origins;
13
14
  /** Base origin of the console dashboard, dev-aware (no trailing slash). */
@@ -37,6 +38,20 @@ export declare function registryFileUrl(ref: ProjectRef, file: string): string;
37
38
  * `EXTENSION_DEV_API_URL`/`EXTENSION_DEV_CONSOLE_URL`.
38
39
  */
39
40
  export declare function consoleProjectUrl(ref: ProjectRef | null, page: string, apiHint?: string): string;
41
+ /**
42
+ * The PUBLIC page for a project, a build, or a channel on userland.
43
+ *
44
+ * The sibling of consoleProjectUrl, and the one to hand to a human who is not
45
+ * the operator: the console links every tool already returns require a login
46
+ * and workspace membership, so they are dead ends for a teammate, a reviewer,
47
+ * or anyone reading a PR. These carry the per-browser downloads, the run
48
+ * locally and integrity dialogs, and the what's new tab.
49
+ *
50
+ * A PRIVATE project's page still needs a `?share=` token, which only
51
+ * extension_publish can mint; callers should say so rather than imply the bare
52
+ * URL will open for anyone.
53
+ */
54
+ export declare function userlandProjectUrl(ref: ProjectRef | null, page?: string, apiHint?: string): string;
40
55
  export type RegistryFetchResult<T> = {
41
56
  ok: true;
42
57
  json: T;
@@ -46,11 +61,23 @@ export type RegistryFetchResult<T> = {
46
61
  message: string;
47
62
  };
48
63
  /**
49
- * Fetch a registry JSON file. Never throws: 404s (private or never-built
50
- * projects), network failures, and non-JSON bodies all come back as
51
- * `{ok:false}` so callers can degrade honestly instead of crashing the verb.
64
+ * Fetch a registry JSON file. Never throws: 404s (never-built projects),
65
+ * network failures, and non-JSON bodies all come back as `{ok:false}` so
66
+ * callers can degrade honestly instead of crashing the verb.
67
+ *
68
+ * PRIVATE PROJECTS: a private project answers 401 here. When `ref` is given and
69
+ * the caller holds a credential for that project, the 401 triggers one mint of
70
+ * a short-lived access token and a single retry with `?t=`. Without `ref` the
71
+ * behaviour is exactly as before, so this stays a drop-in for public reads:
72
+ * public projects still complete in one round trip and never touch the
73
+ * platform. See registry-access.ts for why the stored token is traded rather
74
+ * than sent as `?t=` directly.
52
75
  */
53
- export declare function fetchRegistryJson<T = unknown>(url: string, fetchImpl?: typeof fetch): Promise<RegistryFetchResult<T>>;
76
+ export declare function fetchRegistryJson<T = unknown>(url: string, fetchImpl?: typeof fetch, options?: {
77
+ ref?: ProjectRef | null;
78
+ api?: string;
79
+ tokens?: RegistryAccessTokens;
80
+ }): Promise<RegistryFetchResult<T>>;
54
81
  export interface ChannelEntry {
55
82
  channel: string;
56
83
  sha: string;
@@ -12,6 +12,10 @@ export declare const schema: {
12
12
  type: string;
13
13
  description: string;
14
14
  };
15
+ api: {
16
+ type: string;
17
+ description: string;
18
+ };
15
19
  };
16
20
  required: never[];
17
21
  };
@@ -19,4 +23,5 @@ export declare const schema: {
19
23
  export declare function handler(args: {
20
24
  workspace?: string;
21
25
  project?: string;
26
+ api?: string;
22
27
  }): Promise<string>;
@@ -12,6 +12,10 @@ export declare const schema: {
12
12
  type: string;
13
13
  description: string;
14
14
  };
15
+ api: {
16
+ type: string;
17
+ description: string;
18
+ };
15
19
  };
16
20
  required: never[];
17
21
  };
@@ -52,5 +56,6 @@ export declare function normalizeStoresStatus(json: unknown): NormalizedStoresSt
52
56
  export declare function handler(args: {
53
57
  workspace?: string;
54
58
  project?: string;
59
+ api?: string;
55
60
  }): Promise<string>;
56
61
  export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@extension.dev/mcp",
3
3
  "type": "module",
4
- "version": "6.1.0",
4
+ "version": "6.3.0",
5
5
  "description": "MCP server that lets AI agents (Claude Code, Claude Desktop, Cursor, Copilot, Codex) build, run, inspect, and publish browser extensions. 33 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",
@@ -97,6 +97,7 @@
97
97
  "ws": "^8.20.0"
98
98
  },
99
99
  "devDependencies": {
100
+ "@extension.dev/urls": "^0.3.0",
100
101
  "@rslib/core": "^0.19.4",
101
102
  "@types/cross-spawn": "^6.0.6",
102
103
  "@types/node": "^25.2.0",
package/server.json CHANGED
@@ -7,13 +7,13 @@
7
7
  "source": "github"
8
8
  },
9
9
  "websiteUrl": "https://extension.dev",
10
- "version": "6.1.0",
10
+ "version": "6.3.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": "6.1.0",
16
+ "version": "6.3.0",
17
17
  "runtimeHint": "npx",
18
18
  "transport": {
19
19
  "type": "stdio"
@@ -1,34 +0,0 @@
1
- /** The set of app/service origins the fleet links between. */
2
- export interface Origins {
3
- www: string;
4
- console: string;
5
- inspect: string;
6
- templates: string;
7
- intelligence: string;
8
- /** Public release-state JSON host (registry.extension.land). */
9
- registry: string;
10
- /** Content-addressed template corpus host (media.extension.land). */
11
- media: string;
12
- }
13
- /** Production origins. The prod fallback for every resolver in the fleet. */
14
- export declare const PROD_ORIGINS: Origins;
15
- export declare const DEV_LOCALHOST_ORIGINS: Origins;
16
- /**
17
- * True for `localhost`, `127.0.0.1`, `[::1]`, or any `*.extension.localhost`
18
- * host -- the shapes the dev proxy serves. Anything unparseable is treated as
19
- * not-local so an odd value falls back to prod rather than leaking a dev host.
20
- */
21
- export declare function isLocalOrigin(url: string | undefined | null): boolean;
22
- /**
23
- * Resolve the full origin set from a caller's overrides.
24
- *
25
- * Precedence per origin: explicit override -> derived base (dev vs prod) ->
26
- * prod. The base is chosen by whether the environment looks local: if any of
27
- * `www`/`console`/`hint` points at a local host, unset origins derive from the
28
- * Caddy dev map instead of prod. This is what lets an operator set only
29
- * `EXTENSION_DEV_API_URL=http://localhost:3100` and still get a console link at
30
- * `console.extension.localhost` rather than one that silently points at prod.
31
- */
32
- export declare function resolveOrigins(overrides?: Partial<Origins>, opts?: {
33
- hint?: string;
34
- }): Origins;
@@ -1,56 +0,0 @@
1
- /** A project is addressed by its workspace slug + project slug across the fleet. */
2
- export interface ProjectRef {
3
- workspace: string;
4
- project: string;
5
- }
6
- /** `/:workspace` (or a sub-page like `settings` / `settings/:section`). */
7
- export declare function consoleWorkspacePath(workspace: string, page?: string): string;
8
- /**
9
- * `/:workspace/:project/<page>`. Pass a page tail from `ConsoleProjectPage`
10
- * (e.g. `ConsoleProjectPage.builds`) rather than hand-typing it, so a route
11
- * rename is a one-line change here instead of a scattered string edit.
12
- */
13
- export declare function consoleProjectPath(ref: ProjectRef, page?: string): string;
14
- /**
15
- * Named project-page tails. Values are the exact segments under
16
- * `/:username/:reponame/` in console's route table; deep pages take ids.
17
- */
18
- export declare const ConsoleProjectPage: {
19
- readonly overview: "";
20
- readonly onboard: "onboard";
21
- readonly activity: "activity";
22
- readonly builds: "builds";
23
- readonly build: (buildId: string, browser?: string) => string;
24
- readonly releases: "releases";
25
- readonly releasesNew: "releases/new";
26
- readonly release: (releaseId: string) => string;
27
- readonly stores: "stores";
28
- readonly storesNew: "stores/new";
29
- readonly store: (store: string) => string;
30
- readonly storeSubmissions: (store: string) => string;
31
- readonly storeSubmissionNew: (store: string) => string;
32
- readonly storeSubmission: (store: string, submissionId: string) => string;
33
- readonly projectSettings: "project-settings";
34
- readonly projectSettingsSection: (section: string) => string;
35
- /** Where CLI/MCP tokens are minted and revoked. */
36
- readonly accessTokens: "settings/access-tokens";
37
- };
38
- export type QueryValue = string | number | boolean | null | undefined;
39
- /**
40
- * `/new?...` -- project creation. The public deep-link contract: external
41
- * READMEs use `extension.dev/new?template=<slug>`, which www normalizes to
42
- * `/import` preserving every param. Do not change the `template` key.
43
- */
44
- export declare function wwwNewPath(query?: Record<string, QueryValue>): string;
45
- /** `/import?...` -- the ported import/deploy flow templates' Deploy buttons target. */
46
- export declare function wwwImportPath(query?: Record<string, QueryValue>): string;
47
- /** `/device` -- CLI/MCP device-code consent. Lives on www, never console. */
48
- export declare function wwwDevicePath(): string;
49
- /** `/templates` and `/templates/:slug` -- externally linkable gallery entry on www. */
50
- export declare function wwwTemplatesPath(slug?: string): string;
51
- export type TemplateTab = "preview" | "instructions" | "source";
52
- /** `/:slug` for the default `preview` tab, else `/:slug/<tab>`. */
53
- export declare function templateTabPath(slug: string, tab?: TemplateTab): string;
54
- export type InspectTab = "preview" | "details" | "source" | "trace";
55
- /** `/` for the default `preview` tab, else `/details` / `/source` / `/trace`. */
56
- export declare function inspectTabPath(tab?: InspectTab): string;