mcp-use 2.0.0-beta.11 → 2.0.0-beta.13

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.
Files changed (51) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/bin/main.d.ts.map +1 -1
  3. package/dist/bin.js +5 -2
  4. package/dist/bin.js.map +1 -1
  5. package/dist/branding.d.ts +7 -10
  6. package/dist/branding.d.ts.map +1 -1
  7. package/dist/{chunk-GTOOHAI2.js → chunk-JEVBOMCE.js} +4 -3
  8. package/dist/chunk-JEVBOMCE.js.map +1 -0
  9. package/dist/{chunk-5M5NVF36.js → chunk-RHITI5QM.js} +67 -8
  10. package/dist/chunk-RHITI5QM.js.map +1 -0
  11. package/dist/{chunk-DQ7LE4ZA.js → chunk-XKJP5S7C.js} +17 -14
  12. package/dist/chunk-XKJP5S7C.js.map +1 -0
  13. package/dist/cli/build.d.ts +1 -1
  14. package/dist/cli/dev.d.ts.map +1 -1
  15. package/dist/cli/mcp-env-declaration.d.ts +20 -0
  16. package/dist/cli/mcp-env-declaration.d.ts.map +1 -0
  17. package/dist/cli/tunnel.d.ts.map +1 -1
  18. package/dist/cli/views.d.ts +7 -5
  19. package/dist/cli/views.d.ts.map +1 -1
  20. package/dist/commands/build.js +6 -6
  21. package/dist/commands/build.js.map +1 -1
  22. package/dist/commands/client.d.ts.map +1 -1
  23. package/dist/commands/client.js +1 -1
  24. package/dist/commands/dev.js +79 -12
  25. package/dist/commands/dev.js.map +1 -1
  26. package/dist/commands/load-client.d.ts +2 -0
  27. package/dist/commands/load-client.d.ts.map +1 -1
  28. package/dist/commands/screenshot.js +1 -1
  29. package/dist/config.d.ts +8 -8
  30. package/dist/index.js +32 -51
  31. package/dist/index.js.map +1 -1
  32. package/dist/inspector-shell.d.ts +3 -0
  33. package/dist/inspector-shell.d.ts.map +1 -1
  34. package/dist/{landing-handler-3VN4BMR2.js → landing-handler-Z7WDR4S2.js} +6 -3
  35. package/dist/landing-handler-Z7WDR4S2.js.map +1 -0
  36. package/dist/landing-handler.d.ts +1 -1
  37. package/dist/landing-handler.d.ts.map +1 -1
  38. package/dist/landing.d.ts +2 -0
  39. package/dist/landing.d.ts.map +1 -1
  40. package/dist/landing.js +1 -1
  41. package/dist/react/types/register.d.ts +1 -1
  42. package/dist/react/types/register.d.ts.map +1 -1
  43. package/dist/server.d.ts +2 -3
  44. package/dist/server.d.ts.map +1 -1
  45. package/package.json +8 -8
  46. package/dist/chunk-5M5NVF36.js.map +0 -1
  47. package/dist/chunk-DQ7LE4ZA.js.map +0 -1
  48. package/dist/chunk-GTOOHAI2.js.map +0 -1
  49. package/dist/cli/tools-declaration.d.ts +0 -22
  50. package/dist/cli/tools-declaration.d.ts.map +0 -1
  51. package/dist/landing-handler-3VN4BMR2.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/bin/main.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,8DAA8D;IAC9D,GAAG,EAAE,MAAM,CAAC;IACZ,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,kFAAkF;IAClF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gFAAgF;IAChF,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AA+BD;;;;;;;;GAQG;AACH,wBAAsB,IAAI,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA0EnE"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/bin/main.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,8DAA8D;IAC9D,GAAG,EAAE,MAAM,CAAC;IACZ,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,kFAAkF;IAClF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gFAAgF;IAChF,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AA+BD;;;;;;;;GAQG;AACH,wBAAsB,IAAI,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA6EnE"}
package/dist/bin.js CHANGED
@@ -39,8 +39,11 @@ async function main(argv) {
39
39
  return 0;
40
40
  }
41
41
  if (argv.some((token) => token === "--help" || token === "-h")) {
42
- console.log(HELP);
43
- return 0;
42
+ const command2 = argv[0];
43
+ if (command2 === void 0 || command2 === "--help" || command2 === "-h") {
44
+ console.log(HELP);
45
+ return 0;
46
+ }
44
47
  }
45
48
  const command = argv[0];
46
49
  if (command === "login" || command === "logout" || command === "whoami") {
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/bin/main.ts","../src/bin.ts"],"sourcesContent":["/**\n * Command dispatch for the `mcp-use` bin (specs/CLI_SPEC.md).\n *\n * Every substantial command is dispatched through its own dynamic import.\n * The library entry, bin, and production `start` path therefore never\n * evaluate Vite or an unrelated command implementation.\n */\nimport { readFileSync } from \"node:fs\";\n\nimport { parseArgs, type ParsedArgs } from \"./args.js\";\n\n/**\n * Options this bin passes to the cli's `runDev`/`runBuild`.\n *\n * @internal\n */\nexport interface CliCommandOptions {\n /** Project root the command operates on (`process.cwd()`). */\n cwd: string;\n /** Server entry module override (`--entry`). */\n entry?: string;\n /** Port override (`--port`/`-p`). */\n port?: number;\n /** Host override (`--host`). */\n host?: string;\n /** Start a public tunnel at dev startup (`--tunnel`). */\n tunnel?: boolean;\n /** Auto-open the inspector in a browser at dev startup (`--no-open` disables). */\n open?: boolean;\n /** Record inspector availability in the build manifest (`--with-inspector`). */\n withInspector?: boolean;\n}\n\nconst HELP = `mcp-use — run MCP servers built with mcp-use\n\nUsage: mcp-use <command> [options]\n\nCommands:\n dev Start the dev server\n build Build the server into .mcp-use/build\n start Serve the production build from .mcp-use/build\n login Authenticate the cloud CLI\n logout Delete local cloud credentials\n whoami Show the authenticated cloud identity\n org Manage the active organization\n servers Manage cloud servers and environment variables\n deployments Manage cloud deployments and logs\n deploy Deploy the current GitHub project\n client Connect to and invoke MCP servers\n skills Install maintained coding-agent skills\n screenshot Capture an MCP Apps view\n\nOptions:\n -p, --port <n> Port to serve on (default: $PORT or 3000)\n --host <host> Host to bind (dev only)\n --entry <path> Server entry module (dev/build only)\n --with-inspector Record inspector availability in the build manifest (build only)\n --tunnel Expose the dev server through a public tunnel (dev only)\n --no-open Do not auto-open the inspector in a browser (dev only)\n -h, --help Show this help\n -v, --version Print the version`;\n\n/**\n * Run the `mcp-use` CLI.\n *\n * @param argv - Raw arguments, typically `process.argv.slice(2)`.\n * @returns The process exit code. A `0` from `start`/`dev` means the command\n * launched successfully and the process should stay alive serving.\n *\n * @internal\n */\nexport async function main(argv: readonly string[]): Promise<number> {\n if (argv.length === 1 && [\"--version\", \"-v\"].includes(argv[0] ?? \"\")) {\n console.log(readOwnVersion());\n return 0;\n }\n if (argv.some((token) => token === \"--help\" || token === \"-h\")) {\n console.log(HELP);\n return 0;\n }\n\n const command = argv[0];\n if (command === \"login\" || command === \"logout\" || command === \"whoami\") {\n const { runIdentity } = await import(\"../commands/identity.js\");\n return runIdentity(command, argv.slice(1));\n }\n if (command === \"org\") {\n const { runOrganizations } = await import(\"../commands/organizations.js\");\n return runOrganizations(argv.slice(1));\n }\n if (command === \"servers\") {\n const { runServers } = await import(\"../commands/servers.js\");\n return runServers(argv.slice(1));\n }\n if (command === \"deployments\") {\n const { runDeployments } = await import(\"../commands/deployments.js\");\n return runDeployments(argv.slice(1));\n }\n if (command === \"deploy\") {\n const { runDeploy } = await import(\"../commands/deploy.js\");\n return runDeploy(argv.slice(1));\n }\n if (command === \"client\") {\n const { runClient } = await import(\"../commands/client.js\");\n return runClient(argv.slice(1));\n }\n if (command === \"skills\") {\n const { runSkills } = await import(\"../commands/skills.js\");\n return runSkills(argv.slice(1));\n }\n if (command === \"screenshot\") {\n const { runScreenshot } = await import(\"../commands/screenshot.js\");\n return runScreenshot(argv.slice(1));\n }\n\n let args: ParsedArgs;\n try {\n args = parseArgs(argv);\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error));\n return 2;\n }\n\n if (args.version) {\n console.log(readOwnVersion());\n return 0;\n }\n if (args.help) {\n console.log(HELP);\n return 0;\n }\n\n switch (args.command) {\n case \"start\":\n return startCommand(args);\n case \"dev\":\n case \"build\":\n return cliCommand(args.command, args);\n case undefined:\n console.error(HELP);\n return 2;\n default:\n console.error(`Unknown command: ${args.command}\\n\\n${HELP}`);\n return 2;\n }\n}\n\n/** `mcp-use start`: serve the production build, wire shutdown signals. */\nasync function startCommand(args: ParsedArgs): Promise<number> {\n let started;\n try {\n const { runStart } = await import(\"../commands/start.js\");\n started = await runStart({ cwd: process.cwd(), port: args.port });\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error));\n return 1;\n }\n\n console.log(`mcp-use server running at ${started.url}`);\n\n const shutdown = (): void => {\n started.close().then(\n () => process.exit(0),\n (error: unknown) => {\n console.error(error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n );\n };\n process.once(\"SIGINT\", shutdown);\n process.once(\"SIGTERM\", shutdown);\n return 0;\n}\n\n/** `mcp-use dev` / `mcp-use build`: dispatch to dedicated command chunks. */\nasync function cliCommand(\n command: \"dev\" | \"build\",\n args: ParsedArgs\n): Promise<number> {\n const options: CliCommandOptions = {\n cwd: process.cwd(),\n ...(args.entry !== undefined && { entry: args.entry }),\n ...(args.port !== undefined && { port: args.port }),\n ...(args.host !== undefined && { host: args.host }),\n ...(args.tunnel && { tunnel: true }),\n ...(!args.open && { open: false }),\n ...(args.withInspector && { withInspector: true }),\n };\n\n try {\n if (command === \"dev\") {\n const { runDev } = await import(\"../commands/dev.js\");\n await runDev(options);\n } else {\n const { runBuild } = await import(\"../commands/build.js\");\n await runBuild(options);\n }\n return 0;\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error));\n return 1;\n }\n}\n\n/**\n * Read this package's own version for `--version`.\n *\n * Probes both layouts — `dist/bin.js` (bundled, package root is one level\n * up) and `src/bin/main.ts` (tests, package root is two levels up) — and\n * verifies the manifest's `name` so an unrelated package.json never wins.\n */\nfunction readOwnVersion(): string {\n for (const relative of [\"../package.json\", \"../../package.json\"]) {\n try {\n const raw = readFileSync(new URL(relative, import.meta.url), \"utf8\");\n const pkg = JSON.parse(raw) as { name?: unknown; version?: unknown };\n if (\n (pkg.name === \"mcp-use\" || pkg.name === \"mcp-use\") &&\n typeof pkg.version === \"string\"\n ) {\n return pkg.version;\n }\n } catch {\n // Not there or unreadable — try the next candidate.\n }\n }\n return \"unknown\";\n}\n","#!/usr/bin/env node\n/*\n * `mcp-use` bin entry point (specs/CLI_SPEC.md).\n *\n * Kept to a single call so all logic lives in testable modules under\n * src/bin/. On success the process is NOT exited: `start` (and `dev`) keep\n * serving, and `--help`/`--version` let the event loop drain naturally.\n */\nimport { main } from \"./bin/main.js\";\n\nmain(process.argv.slice(2)).then(\n (code) => {\n process.exitCode = code;\n },\n (error: unknown) => {\n console.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n);\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/bin/main.ts","../src/bin.ts"],"sourcesContent":["/**\n * Command dispatch for the `mcp-use` bin (specs/CLI_SPEC.md).\n *\n * Every substantial command is dispatched through its own dynamic import.\n * The library entry, bin, and production `start` path therefore never\n * evaluate Vite or an unrelated command implementation.\n */\nimport { readFileSync } from \"node:fs\";\n\nimport { parseArgs, type ParsedArgs } from \"./args.js\";\n\n/**\n * Options this bin passes to the cli's `runDev`/`runBuild`.\n *\n * @internal\n */\nexport interface CliCommandOptions {\n /** Project root the command operates on (`process.cwd()`). */\n cwd: string;\n /** Server entry module override (`--entry`). */\n entry?: string;\n /** Port override (`--port`/`-p`). */\n port?: number;\n /** Host override (`--host`). */\n host?: string;\n /** Start a public tunnel at dev startup (`--tunnel`). */\n tunnel?: boolean;\n /** Auto-open the inspector in a browser at dev startup (`--no-open` disables). */\n open?: boolean;\n /** Record inspector availability in the build manifest (`--with-inspector`). */\n withInspector?: boolean;\n}\n\nconst HELP = `mcp-use — run MCP servers built with mcp-use\n\nUsage: mcp-use <command> [options]\n\nCommands:\n dev Start the dev server\n build Build the server into .mcp-use/build\n start Serve the production build from .mcp-use/build\n login Authenticate the cloud CLI\n logout Delete local cloud credentials\n whoami Show the authenticated cloud identity\n org Manage the active organization\n servers Manage cloud servers and environment variables\n deployments Manage cloud deployments and logs\n deploy Deploy the current GitHub project\n client Connect to and invoke MCP servers\n skills Install maintained coding-agent skills\n screenshot Capture an MCP Apps view\n\nOptions:\n -p, --port <n> Port to serve on (default: $PORT or 3000)\n --host <host> Host to bind (dev only)\n --entry <path> Server entry module (dev/build only)\n --with-inspector Record inspector availability in the build manifest (build only)\n --tunnel Expose the dev server through a public tunnel (dev only)\n --no-open Do not auto-open the inspector in a browser (dev only)\n -h, --help Show this help\n -v, --version Print the version`;\n\n/**\n * Run the `mcp-use` CLI.\n *\n * @param argv - Raw arguments, typically `process.argv.slice(2)`.\n * @returns The process exit code. A `0` from `start`/`dev` means the command\n * launched successfully and the process should stay alive serving.\n *\n * @internal\n */\nexport async function main(argv: readonly string[]): Promise<number> {\n if (argv.length === 1 && [\"--version\", \"-v\"].includes(argv[0] ?? \"\")) {\n console.log(readOwnVersion());\n return 0;\n }\n if (argv.some((token) => token === \"--help\" || token === \"-h\")) {\n const command = argv[0];\n if (command === undefined || command === \"--help\" || command === \"-h\") {\n console.log(HELP);\n return 0;\n }\n }\n\n const command = argv[0];\n if (command === \"login\" || command === \"logout\" || command === \"whoami\") {\n const { runIdentity } = await import(\"../commands/identity.js\");\n return runIdentity(command, argv.slice(1));\n }\n if (command === \"org\") {\n const { runOrganizations } = await import(\"../commands/organizations.js\");\n return runOrganizations(argv.slice(1));\n }\n if (command === \"servers\") {\n const { runServers } = await import(\"../commands/servers.js\");\n return runServers(argv.slice(1));\n }\n if (command === \"deployments\") {\n const { runDeployments } = await import(\"../commands/deployments.js\");\n return runDeployments(argv.slice(1));\n }\n if (command === \"deploy\") {\n const { runDeploy } = await import(\"../commands/deploy.js\");\n return runDeploy(argv.slice(1));\n }\n if (command === \"client\") {\n const { runClient } = await import(\"../commands/client.js\");\n return runClient(argv.slice(1));\n }\n if (command === \"skills\") {\n const { runSkills } = await import(\"../commands/skills.js\");\n return runSkills(argv.slice(1));\n }\n if (command === \"screenshot\") {\n const { runScreenshot } = await import(\"../commands/screenshot.js\");\n return runScreenshot(argv.slice(1));\n }\n\n let args: ParsedArgs;\n try {\n args = parseArgs(argv);\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error));\n return 2;\n }\n\n if (args.version) {\n console.log(readOwnVersion());\n return 0;\n }\n if (args.help) {\n console.log(HELP);\n return 0;\n }\n\n switch (args.command) {\n case \"start\":\n return startCommand(args);\n case \"dev\":\n case \"build\":\n return cliCommand(args.command, args);\n case undefined:\n console.error(HELP);\n return 2;\n default:\n console.error(`Unknown command: ${args.command}\\n\\n${HELP}`);\n return 2;\n }\n}\n\n/** `mcp-use start`: serve the production build, wire shutdown signals. */\nasync function startCommand(args: ParsedArgs): Promise<number> {\n let started;\n try {\n const { runStart } = await import(\"../commands/start.js\");\n started = await runStart({ cwd: process.cwd(), port: args.port });\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error));\n return 1;\n }\n\n console.log(`mcp-use server running at ${started.url}`);\n\n const shutdown = (): void => {\n started.close().then(\n () => process.exit(0),\n (error: unknown) => {\n console.error(error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n );\n };\n process.once(\"SIGINT\", shutdown);\n process.once(\"SIGTERM\", shutdown);\n return 0;\n}\n\n/** `mcp-use dev` / `mcp-use build`: dispatch to dedicated command chunks. */\nasync function cliCommand(\n command: \"dev\" | \"build\",\n args: ParsedArgs\n): Promise<number> {\n const options: CliCommandOptions = {\n cwd: process.cwd(),\n ...(args.entry !== undefined && { entry: args.entry }),\n ...(args.port !== undefined && { port: args.port }),\n ...(args.host !== undefined && { host: args.host }),\n ...(args.tunnel && { tunnel: true }),\n ...(!args.open && { open: false }),\n ...(args.withInspector && { withInspector: true }),\n };\n\n try {\n if (command === \"dev\") {\n const { runDev } = await import(\"../commands/dev.js\");\n await runDev(options);\n } else {\n const { runBuild } = await import(\"../commands/build.js\");\n await runBuild(options);\n }\n return 0;\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error));\n return 1;\n }\n}\n\n/**\n * Read this package's own version for `--version`.\n *\n * Probes both layouts — `dist/bin.js` (bundled, package root is one level\n * up) and `src/bin/main.ts` (tests, package root is two levels up) — and\n * verifies the manifest's `name` so an unrelated package.json never wins.\n */\nfunction readOwnVersion(): string {\n for (const relative of [\"../package.json\", \"../../package.json\"]) {\n try {\n const raw = readFileSync(new URL(relative, import.meta.url), \"utf8\");\n const pkg = JSON.parse(raw) as { name?: unknown; version?: unknown };\n if (\n (pkg.name === \"mcp-use\" || pkg.name === \"mcp-use\") &&\n typeof pkg.version === \"string\"\n ) {\n return pkg.version;\n }\n } catch {\n // Not there or unreadable — try the next candidate.\n }\n }\n return \"unknown\";\n}\n","#!/usr/bin/env node\n/*\n * `mcp-use` bin entry point (specs/CLI_SPEC.md).\n *\n * Kept to a single call so all logic lives in testable modules under\n * src/bin/. On success the process is NOT exited: `start` (and `dev`) keep\n * serving, and `--help`/`--version` let the event loop drain naturally.\n */\nimport { main } from \"./bin/main.js\";\n\nmain(process.argv.slice(2)).then(\n (code) => {\n process.exitCode = code;\n },\n (error: unknown) => {\n console.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n);\n"],"mappings":"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","names":["command"]}
@@ -4,23 +4,21 @@ import type { FetchHandler } from "./fetch-app.js";
4
4
  export interface ServerBranding {
5
5
  /**
6
6
  * Source selected for `/favicon.ico`, after applying explicit-favicon and
7
- * icon-ranking precedence.
7
+ * first-icon inference.
8
8
  */
9
9
  readonly favicon?: string;
10
+ /** MIME type of the selected favicon when known. */
11
+ readonly faviconMimeType?: string;
10
12
  /** Icons reported in MCP implementation metadata, in author order. */
11
13
  readonly icons?: readonly Icon[];
12
14
  /** Server website reported in MCP implementation metadata. */
13
15
  readonly websiteUrl?: string;
14
16
  }
15
- interface NormalizedServerBranding extends ServerBranding {
16
- readonly faviconMimeType?: string;
17
- }
18
17
  /**
19
18
  * Select the browser favicon from an ordered set of MCP icons.
20
19
  *
21
- * Ranking is deterministic: ICO, 16x16/32x32 PNG, any PNG, then the first
22
- * icon. MIME declarations and URL pathnames participate alongside filename
23
- * suffixes, so absolute URLs with queries and data URLs rank correctly.
20
+ * Uses the first icon in author order. Put the preferred browser favicon
21
+ * first, or set {@link ServerConfig.favicon} explicitly.
24
22
  *
25
23
  * @param icons - Validated, non-empty icon list.
26
24
  * @returns The selected icon.
@@ -40,7 +38,7 @@ export declare function normalizeServerBranding(config: {
40
38
  favicon?: unknown;
41
39
  icons?: unknown;
42
40
  websiteUrl?: unknown;
43
- }): NormalizedServerBranding;
41
+ }): ServerBranding;
44
42
  /**
45
43
  * Resolve configured icons for MCP implementation metadata.
46
44
  *
@@ -76,10 +74,9 @@ export declare function hasLocalBrandingAsset(branding: ServerBranding): boolean
76
74
  *
77
75
  * @internal
78
76
  */
79
- export declare function createFaviconHandler(branding: NormalizedServerBranding, options: {
77
+ export declare function createFaviconHandler(branding: ServerBranding, options: {
80
78
  dev: boolean;
81
79
  projectRoot: string;
82
80
  deferCors?: boolean;
83
81
  }): FetchHandler | undefined;
84
- export {};
85
82
  //# sourceMappingURL=branding.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"branding.d.ts","sourceRoot":"","sources":["../src/branding.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAEzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAUnD,8EAA8E;AAC9E,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,sEAAsE;IACtE,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,IAAI,EAAE,CAAC;IACjC,8DAA8D;IAC9D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,UAAU,wBAAyB,SAAQ,cAAc;IACvD,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACnC;AA8DD;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,SAAS,IAAI,EAAE,GACrB,IAAI,GAAG,SAAS,CAWlB;AA4ED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,GAAG,wBAAwB,CAoG3B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,SAAS,EAClC,OAAO,EAAE,OAAO,GAAG,SAAS,EAC5B,QAAQ,EAAE,MAAM,GACf,IAAI,EAAE,GAAG,SAAS,CAYpB;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAKvE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,wBAAwB,EAClC,OAAO,EAAE;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAClE,YAAY,GAAG,SAAS,CAgE1B"}
1
+ {"version":3,"file":"branding.d.ts","sourceRoot":"","sources":["../src/branding.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAEzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAUnD,8EAA8E;AAC9E,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,oDAAoD;IACpD,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,sEAAsE;IACtE,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,IAAI,EAAE,CAAC;IACjC,8DAA8D;IAC9D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAmBD;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,SAAS,IAAI,EAAE,GACrB,IAAI,GAAG,SAAS,CAElB;AA4ED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,GAAG,cAAc,CAoGjB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,SAAS,EAClC,OAAO,EAAE,OAAO,GAAG,SAAS,EAC5B,QAAQ,EAAE,MAAM,GACf,IAAI,EAAE,GAAG,SAAS,CAYpB;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAKvE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAClE,YAAY,GAAG,SAAS,CAgE1B"}
@@ -208,7 +208,8 @@ function generateLandingPage(options) {
208
208
  tools,
209
209
  prompts,
210
210
  resources,
211
- iconUrl
211
+ iconUrl,
212
+ iconType
212
213
  } = options;
213
214
  const name = title ?? protocolName;
214
215
  const cursorDeepLink = generateCursorDeepLink(url, name);
@@ -257,7 +258,7 @@ function generateLandingPage(options) {
257
258
  <meta name="twitter:card" content="summary">
258
259
  <meta name="twitter:title" content="${pageTitle}">
259
260
  <meta name="twitter:description" content="${metaDescription}">
260
- ${iconUrl ? `<link rel="icon" href="${escapeHtml(iconUrl)}">` : ""}
261
+ ${iconUrl ? `<link rel="icon"${iconType ? ` type="${escapeHtml(iconType)}"` : ""} href="${escapeHtml(iconUrl)}">` : ""}
261
262
  <link rel="preconnect" href="https://fonts.googleapis.com">
262
263
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
263
264
  <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&display=swap" rel="stylesheet">
@@ -737,4 +738,4 @@ a:hover { text-decoration: underline; }
737
738
  export {
738
739
  generateLandingPage
739
740
  };
740
- //# sourceMappingURL=chunk-GTOOHAI2.js.map
741
+ //# sourceMappingURL=chunk-JEVBOMCE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/landing.ts"],"sourcesContent":["/**\n * Landing page generator for MCP server endpoints\n *\n * Generates SEO-friendly HTML with connection instructions for MCP servers\n * from Claude Code, Cursor, VS Code, ChatGPT, and Manufact Inspector (hosted).\n */\n\n/**\n * Escapes HTML special characters to prevent XSS in user-provided content.\n */\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n\n/** Serialize data for an inline JSON script without creating an HTML end tag. */\nfunction serializeScriptJson(value: unknown): string {\n return JSON.stringify(value)\n .replace(/</g, \"\\\\u003c\")\n .replace(/>/g, \"\\\\u003e\");\n}\n\n/**\n * Sanitizes a server name for use in filenames and URLs.\n * Replaces non-alphanumeric characters with underscores and converts to lowercase.\n */\nfunction sanitizeServerName(name: string): string {\n return name.replace(/[^a-zA-Z0-9-_]/g, \"_\").toLowerCase();\n}\n\n/**\n * Generates a Cursor deep link for installing an MCP server.\n * The config is base64-encoded JSON containing the server URL.\n */\nfunction generateCursorDeepLink(url: string, name: string): string {\n const config = { url };\n const configJson = JSON.stringify(config);\n\n // Use Buffer in Node.js or btoa in browser-like environments\n const base64Config =\n typeof Buffer !== \"undefined\"\n ? Buffer.from(configJson).toString(\"base64\")\n : btoa(configJson);\n\n const sanitizedName = sanitizeServerName(name);\n return `cursor://anysphere.cursor-deeplink/mcp/install?config=${encodeURIComponent(base64Config)}&name=${encodeURIComponent(sanitizedName)}`;\n}\n\n/**\n * Generates a VS Code deep link for installing an MCP server.\n * The config is URL-encoded JSON containing the server URL.\n */\nfunction generateVSCodeDeepLink(url: string, name: string): string {\n const config = {\n url,\n name: sanitizeServerName(name),\n type: \"http\",\n };\n const configJson = JSON.stringify(config);\n const urlEncodedConfig = encodeURIComponent(configJson);\n return `vscode:mcp/install?${urlEncodedConfig}`;\n}\n\n/**\n * Generates a VS Code Insiders deep link for installing an MCP server.\n * The config is URL-encoded JSON containing the server URL.\n */\nfunction generateVSCodeInsidersDeepLink(url: string, name: string): string {\n const config = {\n url,\n name: sanitizeServerName(name),\n type: \"http\",\n };\n const configJson = JSON.stringify(config);\n const urlEncodedConfig = encodeURIComponent(configJson);\n return `vscode-insiders:mcp/install?${urlEncodedConfig}`;\n}\n\n/**\n * Generates a Claude Code CLI command for adding an MCP server.\n */\nfunction generateClaudeCommand(url: string, name: string): string {\n const sanitizedName = sanitizeServerName(name);\n const quotedUrl = `'${url.replace(/'/g, \"'\\\\''\")}'`;\n return `claude mcp add --transport http \"${sanitizedName}\" ${quotedUrl}`;\n}\n\n/** Hosted Manufact Inspector base (same as cloud deploy “Open in new tab”). */\nconst MANUFACT_INSPECTOR_ORIGIN = \"https://inspector.manufact.com\";\n\n/**\n * Deep link to hosted Manufact Inspector with this MCP server URL pre-filled\n * and the Chat tab selected (`tab=chat`).\n */\nfunction getManufactInspectorUrl(serverUrl: string): string {\n const params = new URLSearchParams({\n autoConnect: serverUrl,\n tab: \"chat\",\n });\n return `${MANUFACT_INSPECTOR_ORIGIN}/inspector?${params.toString()}`;\n}\n\nconst LOGO_SVG_PATHS = {\n path1:\n \"M105.933 0C164.437 0.000115889 211.865 47.607 211.865 106.333C211.865 131.828 210.494 158.401 221.068 181.6L228.976 198.947C243.585 230.997 269.266 256.7 301.304 271.336L316.156 278.121C340.143 289.079 367.695 287.335 394.067 287.335C452.572 287.335 500 334.942 500 393.668C500 452.394 452.572 500.001 394.067 500.001C335.563 500.001 288.135 452.394 288.135 393.668C288.135 368.974 289.241 343.275 278.992 320.807L270.587 302.38C255.949 270.289 230.214 244.565 198.118 229.939L180.164 221.758C157.282 211.331 131.078 212.666 105.933 212.666C47.4278 212.666 4.92992e-05 165.059 0 106.333C0 47.607 47.4278 0 105.933 0Z\",\n circle: { cx: 100.426, cy: 399.575, r: 100.426 },\n path2:\n \"M500 100.426C500 155.889 455.037 200.851 399.574 200.851C344.11 200.851 299.148 155.889 299.148 100.426C299.148 44.962 344.11 0 399.574 0C455.037 0 500 44.962 500 100.426Z\",\n};\n\nconst LINE_INTERSECTION_PATH =\n \"M10.5 4C10.5 7.31371 7.81371 10 4.5 10H0.5V11H4.5C7.81371 11 10.5 13.6863 10.5 17V21H11.5V17C11.5 13.6863 14.1863 11 17.5 11H21.5V10H17.5C14.1863 10 11.5 7.31371 11.5 4V0H10.5V4Z\";\n\n/** Returns the inline WebGL mesh gradient script (no deps). */\nfunction getMeshGradientScript(): string {\n const VERT = `#version 300 es\nin vec4 a_position;\nout vec2 v_objectUV;\nvoid main(){\n gl_Position=a_position;\n v_objectUV=a_position.xy*0.5+0.5;\n}`;\n\n const FRAG = `#version 300 es\nprecision mediump float;\nuniform float u_time;\nuniform vec4 u_colors[4];\nuniform float u_colorsCount;\nuniform float u_distortion;\nuniform float u_swirl;\nuniform float u_grainMixer;\nuniform float u_grainOverlay;\nin vec2 v_objectUV;\nout vec4 fragColor;\n#define PI 3.14159265359\nvec2 rotate(vec2 uv,float th){return mat2(cos(th),sin(th),-sin(th),cos(th))*uv;}\nfloat hash21(vec2 p){\n p=fract(p*vec2(0.3183099,0.3678794))+0.1;\n p+=dot(p,p+19.19);\n return fract(p.x*p.y);\n}\nfloat valueNoise(vec2 st){\n vec2 i=floor(st);vec2 f=fract(st);\n float a=hash21(i),b=hash21(i+vec2(1.,0.)),c=hash21(i+vec2(0.,1.)),d=hash21(i+vec2(1.,1.));\n vec2 u=f*f*(3.-2.*f);\n return mix(mix(a,b,u.x),mix(c,d,u.x),u.y);\n}\nvec2 getPosition(int i,float t){\n float a=float(i)*.37,b=.6+fract(float(i)/3.)*.9,c=.8+fract(float(i+1)/4.);\n float x=sin(t*b+a),y=cos(t*c+a*1.5);\n return .5+.5*vec2(x,y);\n}\nvoid main(){\n vec2 uv=v_objectUV;uv+=.5;\n vec2 grainUV=uv*1000.;\n float grain=valueNoise(grainUV);\n float mixerGrain=.4*u_grainMixer*(grain-.5);\n float t=.5*(u_time+41.5);\n float radius=smoothstep(0.,1.,length(uv-.5));\n float center=1.-radius;\n for(float i=1.;i<=2.;i++){\n uv.x+=u_distortion*center/i*sin(t+i*.4*smoothstep(0.,1.,uv.y))*cos(.2*t+i*2.4*smoothstep(0.,1.,uv.y));\n uv.y+=u_distortion*center/i*cos(t+i*2.*smoothstep(0.,1.,uv.x));\n }\n vec2 uvR=uv-vec2(.5);\n float angle=3.*u_swirl*radius;\n uvR=rotate(uvR,-angle);uvR+=vec2(.5);\n vec3 color=vec3(0.);float opacity=0.,totalWeight=0.;\n for(int i=0;i<4;i++){\n if(i>=int(u_colorsCount))break;\n vec2 pos=getPosition(i,t)+mixerGrain;\n vec3 cf=u_colors[i].rgb*u_colors[i].a;\n float opacityF=u_colors[i].a;\n float dist=length(uvR-pos);\n dist=pow(dist,3.5);\n float w=1./(dist+1e-3);\n color+=cf*w;opacity+=opacityF*w;totalWeight+=w;\n }\n color/=max(1e-4,totalWeight);\n opacity/=max(1e-4,totalWeight);\n float grainO=valueNoise(rotate(grainUV,1.)+vec2(3.));\n grainO=mix(grainO,valueNoise(rotate(grainUV,2.)+vec2(-1.)),.5);\n grainO=pow(grainO,1.3);\n float grainOV=grainO*2.-1.;\n vec3 grainOC=vec3(step(0.,grainOV));\n float grainOS=u_grainOverlay*abs(grainOV);\n grainOS=pow(grainOS,.8);\n color=mix(color,grainOC,.35*grainOS);\n opacity+=.5*grainOS;\n fragColor=vec4(color,clamp(opacity,0.,1.));\n}`;\n\n return `(function(){\nvar c=document.getElementById('mesh-bg');\nif(!c)return;\nvar wrap=c.parentElement;\nif(!wrap)return;\nvar gl=c.getContext('webgl2');\nif(!gl)return;\nfunction compileShader(typ,src){\n var s=gl.createShader(typ);\n gl.shaderSource(s,src);\n gl.compileShader(s);\n if(!gl.getShaderParameter(s,gl.COMPILE_STATUS)){console.error(gl.getShaderInfoLog(s));return null;}\n return s;\n}\nvar vs=compileShader(gl.VERTEX_SHADER,${JSON.stringify(VERT)});\nvar fs=compileShader(gl.FRAGMENT_SHADER,${JSON.stringify(FRAG)});\nif(!vs||!fs)return;\nvar prog=gl.createProgram();\ngl.attachShader(prog,vs);\ngl.attachShader(prog,fs);\ngl.linkProgram(prog);\nif(!gl.getProgramParameter(prog,gl.LINK_STATUS)){console.error(gl.getProgramInfoLog(prog));return;}\ngl.useProgram(prog);\nvar posLoc=gl.getAttribLocation(prog,'a_position');\nvar buf=gl.createBuffer();\ngl.bindBuffer(gl.ARRAY_BUFFER,buf);\ngl.bufferData(gl.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,-1,1,1,-1,1,1]),gl.STATIC_DRAW);\ngl.enableVertexAttribArray(posLoc);\ngl.vertexAttribPointer(posLoc,2,gl.FLOAT,false,0,0);\nfunction hexToRgba(hex){\n var r=(parseInt(hex.slice(1,3),16))/255;\n var g=(parseInt(hex.slice(3,5),16))/255;\n var b=(parseInt(hex.slice(5,7),16))/255;\n return[r,g,b,1];\n}\nvar colors=[hexToRgba('#e0eaff'),hexToRgba('#f9ffbd'),hexToRgba('#dedede'),hexToRgba('#ffffff')];\nvar uTime=gl.getUniformLocation(prog,'u_time');\nvar uColors=[gl.getUniformLocation(prog,'u_colors[0]'),gl.getUniformLocation(prog,'u_colors[1]'),gl.getUniformLocation(prog,'u_colors[2]'),gl.getUniformLocation(prog,'u_colors[3]')];\nvar uColorsCount=gl.getUniformLocation(prog,'u_colorsCount');\nvar uDistortion=gl.getUniformLocation(prog,'u_distortion');\nvar uSwirl=gl.getUniformLocation(prog,'u_swirl');\nvar uGrainMixer=gl.getUniformLocation(prog,'u_grainMixer');\nvar uGrainOverlay=gl.getUniformLocation(prog,'u_grainOverlay');\nvar time=0,speed=1,raf;\nfunction resize(){\n var dpr=Math.min(2,window.devicePixelRatio||1);\n c.width=Math.floor(wrap.clientWidth*dpr);\n c.height=Math.floor(wrap.clientHeight*dpr);\n gl.viewport(0,0,c.width,c.height);\n}\nfunction draw(){\n if(document.hidden){raf=requestAnimationFrame(draw);return;}\n time+=0.016*speed;\n gl.uniform1f(uTime,time);\n for(var i=0;i<4;i++)gl.uniform4fv(uColors[i],colors[i]);\n gl.uniform1f(uColorsCount,4);\n gl.uniform1f(uDistortion,0.8);\n gl.uniform1f(uSwirl,0.1);\n gl.uniform1f(uGrainMixer,0);\n gl.uniform1f(uGrainOverlay,0.3);\n gl.drawArrays(gl.TRIANGLES,0,6);\n raf=requestAnimationFrame(draw);\n}\nresize();\nnew ResizeObserver(resize).observe(wrap);\ndraw();\n})();`;\n}\n\n/** A tool shown in the landing page's primitives list. */\nexport interface LandingPageTool {\n /** Protocol-facing tool name. */\n name: string;\n\n /** Optional human-readable tool title. */\n title?: string;\n\n /** Optional tool description. */\n description?: string;\n}\n\n/** A prompt shown in the landing page's primitives list. */\nexport interface LandingPagePrompt {\n /** Protocol-facing prompt name. */\n name: string;\n\n /** Optional human-readable prompt title. */\n title?: string;\n\n /** Optional prompt description. */\n description?: string;\n}\n\n/** A static resource shown in the landing page's primitives list. */\nexport interface LandingPageResource {\n /** Resource URI. */\n uri: string;\n\n /** Optional protocol-facing resource name. */\n name?: string;\n\n /** Optional human-readable resource title. */\n title?: string;\n\n /** Optional resource description. */\n description?: string;\n}\n\n/** Inputs used to render the v1-compatible MCP server landing page. */\nexport interface LandingPageOptions {\n /** Protocol-facing server name. */\n name: string;\n\n /** Optional human-readable server title used as the page heading. */\n title?: string;\n\n /** Server version shown beside the heading. */\n version: string;\n\n /** Absolute public URL of the MCP endpoint. */\n url: string;\n\n /** Optional server description. */\n description?: string;\n\n /** Optional tools shown in the primitives list. */\n tools?: readonly LandingPageTool[];\n\n /** Optional prompts shown in the primitives list. */\n prompts?: readonly LandingPagePrompt[];\n\n /** Optional static resources shown in the primitives list. */\n resources?: readonly LandingPageResource[];\n\n /** Optional absolute URL for the icon displayed above the server heading. */\n iconUrl?: string;\n /** MIME type for the favicon link tag when known. */\n iconType?: string;\n}\n\n/**\n * Generates an HTML landing page with connection instructions\n * for Claude Code, Cursor, VS Code, ChatGPT, and Manufact Inspector.\n *\n * @param options - Server identity, endpoint, icon, and primitive metadata.\n * @returns HTML landing page with connection instructions\n */\nexport function generateLandingPage(options: LandingPageOptions): string {\n const {\n name: protocolName,\n title,\n version,\n url,\n description,\n tools,\n prompts,\n resources,\n iconUrl,\n iconType,\n } = options;\n const name = title ?? protocolName;\n const cursorDeepLink = generateCursorDeepLink(url, name);\n const vscodeDeepLink = generateVSCodeDeepLink(url, name);\n const vscodeInsidersDeepLink = generateVSCodeInsidersDeepLink(url, name);\n const claudeCommand = generateClaudeCommand(url, name);\n const manufactInspectorUrl = getManufactInspectorUrl(url);\n\n const safeName = escapeHtml(name);\n const safeDescription = description ? escapeHtml(description) : \"\";\n const rawMetaDescription =\n description ||\n `${name} MCP Server — Connect with Claude Code, Cursor, and VS Code. Model Context Protocol server.`;\n const metaDescription = escapeHtml(rawMetaDescription);\n const pageTitle = `${safeName} MCP Server — Connect with Claude Code, Cursor & VS Code`;\n\n const jsonLd = serializeScriptJson({\n \"@context\": \"https://schema.org\",\n \"@type\": \"SoftwareApplication\",\n name: name,\n softwareVersion: version,\n description: rawMetaDescription,\n applicationCategory: \"DeveloperApplication\",\n });\n\n const normalizedTools: LandingPageTool[] =\n tools && tools.length > 0\n ? tools.map((tool) => ({\n name: tool.title ?? tool.name,\n ...(tool.description !== undefined && {\n description: tool.description,\n }),\n }))\n : [];\n\n const toolsListHtml =\n normalizedTools.length > 0\n ? normalizedTools\n .map(\n (t) =>\n `<div class=\"spec-item\"><code class=\"spec-name\">${escapeHtml(t.name)}</code>${t.description ? `<p class=\"spec-desc\">${escapeHtml(t.description)}</p>` : \"\"}</div>`\n )\n .join(\"\\n\")\n : \"\";\n\n const promptsListHtml =\n prompts && prompts.length > 0\n ? prompts\n .map(\n (p) =>\n `<div class=\"spec-item\"><code class=\"spec-name\">${escapeHtml(p.title ?? p.name)}</code>${p.description ? `<p class=\"spec-desc\">${escapeHtml(p.description)}</p>` : \"\"}</div>`\n )\n .join(\"\\n\")\n : \"\";\n\n const resourcesListHtml =\n resources && resources.length > 0\n ? resources\n .map(\n (r) =>\n `<div class=\"spec-item\"><code class=\"spec-uri\">${escapeHtml(r.uri)}</code>${r.description ? `<p class=\"spec-desc\">${escapeHtml(r.description)}</p>` : \"\"}</div>`\n )\n .join(\"\\n\")\n : \"\";\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>${pageTitle}</title>\n<meta name=\"description\" content=\"${metaDescription}\">\n<meta property=\"og:title\" content=\"${pageTitle}\">\n<meta property=\"og:description\" content=\"${metaDescription}\">\n<meta property=\"og:type\" content=\"website\">\n<meta name=\"twitter:card\" content=\"summary\">\n<meta name=\"twitter:title\" content=\"${pageTitle}\">\n<meta name=\"twitter:description\" content=\"${metaDescription}\">\n${iconUrl ? `<link rel=\"icon\"${iconType ? ` type=\"${escapeHtml(iconType)}\"` : \"\"} href=\"${escapeHtml(iconUrl)}\">` : \"\"}\n<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n<link href=\"https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&display=swap\" rel=\"stylesheet\">\n<script type=\"application/ld+json\">${jsonLd}</script>\n<style>\n* { box-sizing: border-box; }\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n font-size: 16px;\n line-height: 1.6;\n color: #1e293b;\n background-color: #fdfcfc;\n min-height: 100vh;\n}\n.layout {\n max-width: 48rem;\n margin: 0 auto;\n padding: 2rem 1.5rem;\n position: relative;\n}\n.rail-left, .rail-right {\n position: absolute;\n top: 0;\n bottom: 0;\n width: 1px;\n background: rgba(0,0,0,0.08);\n}\n.rail-left { left: 1.5rem; }\n.rail-right { right: 1.5rem; }\n.rail-top, .rail-bottom {\n height: 1px;\n background: rgba(0,0,0,0.08);\n position: absolute;\n left: 1.5rem;\n right: 1.5rem;\n}\n.rail-top { top: 0; }\n.rail-bottom { bottom: 0; }\n.corner {\n position: absolute;\n width: 22px;\n height: 21px;\n color: rgba(0,0,0,0.08);\n}\n.corner-tl { left: 1.5rem; top: 0; transform: translate(-50%, -50%); }\n.corner-tr { right: 1.5rem; top: 0; transform: translate(50%, -50%); left: auto; }\n.corner-bl { left: 1.5rem; bottom: 0; transform: translate(-50%, 50%); top: auto; }\n.corner-br { right: 1.5rem; bottom: 0; transform: translate(50%, 50%); left: auto; top: auto; }\n.card {\n background: #fff;\n border-top: 1px solid rgba(0,0,0,0.08);\n border-bottom: 1px solid rgba(0,0,0,0.08);\n margin-bottom: 1.5rem;\n overflow: hidden;\n}\n.card-header {\n padding: 1.5rem 1.5rem 0.5rem;\n}\n.card-content { padding: 0 1.5rem 1.5rem; }\n.hero-card .card-header {\n text-align: center;\n padding: 0 1.5rem 1.25rem;\n}\n.hero-card .card-header.has-icon {\n padding-top: 1.5rem;\n}\n.hero-icon {\n width: 64px;\n height: 64px;\n border-radius: 14px;\n object-fit: contain;\n margin-bottom: 0.75rem;\n}\n.hero-row {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.75rem;\n margin-bottom: 0.35rem;\n}\n.hero h1 {\n font-size: 1.75rem;\n font-weight: 700;\n color: #172037;\n margin: 0.75rem 0 0;\n}\n.hero-card .card-header.has-icon .hero h1 { margin-top: 0; }\n.hero .version { font-size: 0.95rem; color: #64748b; font-weight: 500; }\n.hero-description {\n color: rgba(23,32,55,0.8);\n font-size: 1rem;\n margin: 0.35rem 0 0;\n max-width: 36rem;\n margin-left: auto;\n margin-right: auto;\n}\n.logo-symbol {\n display: inline-block;\n cursor: default;\n flex-shrink: 0;\n}\n.logo-symbol svg {\n width: 32px;\n height: 32px;\n color: #172037;\n}\n.logo-fill { transition: opacity 0.2s ease; }\n.logo-stroke path,\n.logo-stroke circle {\n fill: none;\n stroke: currentColor;\n stroke-width: 6;\n stroke-linecap: round;\n stroke-linejoin: round;\n stroke-dasharray: 2000;\n stroke-dashoffset: 2000;\n opacity: 0;\n}\n.logo-symbol:hover .logo-fill {\n animation: logo-fill-out 0.2s forwards, logo-fill-in 0.6s 0.9s forwards;\n}\n.logo-symbol:hover .logo-stroke path,\n.logo-symbol:hover .logo-stroke circle {\n opacity: 1;\n animation: logo-draw 0.7s 0.2s ease-in-out forwards;\n}\n@keyframes logo-fill-out { to { opacity: 0; } }\n@keyframes logo-fill-in { to { opacity: 1; } }\n@keyframes logo-draw { to { stroke-dashoffset: 0; } }\n.footer-content { text-align: center; padding: 2.5rem 1.5rem; border-top: 1px solid rgba(0,0,0,0.08); display: flex; justify-content: center; align-items: center; }\n.footer-brand-link { justify-content: center; }\n.footer-brand-link .logo-symbol svg { width: 22px; height: 22px; }\n.hero-powered { display: inline-flex; align-items: center; justify-content: center; gap: 0.35rem; margin-top: 0.75rem; font-family: \"Outfit\", -apple-system, BlinkMacSystemFont, sans-serif; font-size: 0.875rem; font-weight: 500; color: rgba(23,32,55,0.6); }\n.hero-powered a { color: #000; text-decoration: none; display: inline-flex; align-items: center; }\n.hero-powered a:hover { text-decoration: underline; }\n.footer-brand-link { display: inline-flex; align-items: center; gap: 0.5rem; font-family: \"Outfit\", -apple-system, BlinkMacSystemFont, sans-serif; font-size: 1.5rem; font-weight: 600; color: #172037; text-decoration: none; }\n.footer-brand-link:hover { color: #0f172a; }\n.hero-url-block { display: flex; justify-content: center; margin: 0.75rem 0; }\n.hero-cta-row {\n display: flex;\n justify-content: center;\n margin: 0.35rem 0 0.5rem;\n}\n.hero-primary-btn {\n display: inline-block;\n padding: 0.625rem 1.25rem;\n background: linear-gradient(180deg, #1e293b 0%, #0f172a 100%);\n color: #fff;\n border-radius: 9999px;\n text-decoration: none;\n font-weight: 600;\n font-size: 0.9375rem;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 2px 8px rgba(15,23,42,0.15);\n transition: background 0.15s;\n border: 1px solid rgba(0,0,0,0.12);\n}\n.hero-primary-btn:hover {\n background: linear-gradient(180deg, #334155 0%, #1e293b 100%);\n text-decoration: none;\n color: #fff;\n}\n.hero-url-block .url-block { max-width: 100%; }\n.hero-url-block .url-box {\n font-size: 0.938rem;\n background: #fff;\n border: 1px solid rgba(0,0,0,0.12);\n border-radius: 9999px;\n padding: 0.75rem 3rem 0.75rem 1rem;\n margin: 1rem 0;\n}\n.hero-powered .gh-icon { width: 18px; height: 18px; margin-right: 0.25rem; vertical-align: -0.2em; }\n.hero-powered .gh-shield { height: 18px; width: auto; margin-left: 0.4rem; vertical-align: -0.2em; }\n.card-title { font-size: 1.25rem; font-weight: 600; color: #172037; margin: 0 0 0.25rem; }\n.card-desc { font-size: 0.875rem; color: rgba(23,32,55,0.8); margin: 0 0 1rem; }\n.url-block {\n position: relative;\n margin: 1rem 0;\n}\n.url-block .url-box {\n margin: 0;\n padding-right: 2.75rem;\n}\n.url-block .copy-btn { top: 50%; right: 0.5rem; transform: translateY(-50%); }\n.url-box {\n font-family: ui-monospace, monospace;\n font-size: 0.813rem;\n background: #f8fafc;\n padding: 0.5rem 0.75rem;\n border-radius: 6px;\n color: #475569;\n margin: 1rem 0;\n}\n.spec-section { margin-top: 1.5rem; }\n.spec-section h3 { font-size: 1rem; font-weight: 600; color: #172037; margin: 0 0 0.75rem; }\n.spec-item { margin-bottom: 1rem; padding-bottom: 1rem; border-bottom: 1px solid #f1f5f9; }\n.spec-item:last-child { margin-bottom: 0; padding-bottom: 0; border-bottom: none; }\n.spec-name, .spec-uri { font-family: ui-monospace, monospace; font-size: 0.813rem; background: #f1f5f9; padding: 0.2rem 0.4rem; border-radius: 4px; }\n.spec-uri { word-break: break-all; }\n.spec-desc { margin: 0.5rem 0 0; font-size: 0.875rem; color: #64748b; line-height: 1.5; }\n.tabs-row {\n display: flex;\n gap: 2px;\n background: rgba(23,32,55,0.05);\n padding: 3px;\n border-radius: 8px;\n margin-bottom: 1.5rem;\n flex-wrap: wrap;\n}\n.tab {\n flex: 1;\n min-width: 80px;\n padding: 0.5rem 0.75rem;\n font-size: 0.813rem;\n font-weight: 500;\n border: none;\n border-radius: 6px;\n background: transparent;\n color: #64748b;\n cursor: pointer;\n transition: background 0.15s, color 0.15s;\n}\n.tab:hover { color: #172037; background: rgba(255,255,255,0.6); }\n.tab.active { background: #fff; color: #172037; border: 1px solid rgba(0,0,0,0.1); box-shadow: 0 1px 2px rgba(0,0,0,0.04); }\n.tab-panel { display: none; }\n.tab-panel.active { display: block; }\n.tab-panel h3 { font-size: 1.125rem; font-weight: 600; color: #172037; margin: 0 0 1rem; }\n.install-btn {\n display: inline-block;\n padding: 0.375rem 0.875rem;\n background: #0f172a;\n color: #fff;\n border-radius: 9999px;\n text-decoration: none;\n font-weight: 500;\n font-size: 0.813rem;\n margin-bottom: 1rem;\n transition: background 0.15s;\n}\n.install-btn:hover { background: #1e293b; }\n.code-block {\n position: relative;\n margin: 1rem 0;\n}\n.code-block pre {\n margin: 0;\n padding: 0.5rem 0.75rem;\n background: #f8fafc;\n color: #475569;\n border-radius: 8px;\n font-family: ui-monospace, monospace;\n font-size: 0.875rem;\n overflow-x: auto;\n border: 1px solid rgba(0,0,0,0.08);\n}\n.code-block .copy-btn { top: 50%; right: 0.375rem; transform: translateY(-50%); }\n.copy-btn {\n position: absolute;\n top: 0.5rem;\n right: 0.5rem;\n width: 2rem;\n height: 2rem;\n padding: 0;\n border: none;\n border-radius: 6px;\n background: #fff;\n color: #172037;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.15s;\n}\n.copy-btn:hover { background: #f1f5f9; }\n.copy-btn.copied { background: #fff; color: #172037; }\n.copy-btn svg { width: 14px; height: 14px; }\nol.steps { margin: 0; padding-left: 1.25rem; }\nol.steps li { margin: 0.5rem 0; color: #475569; }\na { color: #0522a5; text-decoration: none; }\na:hover { text-decoration: underline; }\n.hero-gradient-wrap {\n position: relative;\n padding: 1.5rem;\n overflow: hidden;\n}\n.hero-gradient-wrap canvas {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n display: block;\n}\n.hero-inner {\n position: relative;\n z-index: 1;\n background: rgba(253,252,252,0.9);\n -webkit-backdrop-filter: blur(12px);\n backdrop-filter: blur(12px);\n padding: 1.25rem 1.5rem;\n border: 1px solid rgba(0,0,0,0.06);\n}\n.hero-inner .card-header { padding: 0; }\n.hero-inner .card-header.has-icon { padding-top: 0.5rem; }\n</style>\n</head>\n<body>\n<div class=\"layout\">\n <div class=\"rail-left\"></div>\n <div class=\"rail-right\"></div>\n <div class=\"rail-top\"></div>\n <div class=\"rail-bottom\"></div>\n <svg class=\"corner corner-tl\" viewBox=\"0 0 22 21\" fill=\"none\"><path d=\"${LINE_INTERSECTION_PATH}\" fill=\"currentColor\"/></svg>\n <svg class=\"corner corner-tr\" viewBox=\"0 0 22 21\" fill=\"none\"><path d=\"${LINE_INTERSECTION_PATH}\" fill=\"currentColor\"/></svg>\n <svg class=\"corner corner-bl\" viewBox=\"0 0 22 21\" fill=\"none\"><path d=\"${LINE_INTERSECTION_PATH}\" fill=\"currentColor\"/></svg>\n <svg class=\"corner corner-br\" viewBox=\"0 0 22 21\" fill=\"none\"><path d=\"${LINE_INTERSECTION_PATH}\" fill=\"currentColor\"/></svg>\n\n <div class=\"card hero-card\">\n <div class=\"hero-gradient-wrap\" id=\"hero-gradient-wrap\">\n <canvas id=\"mesh-bg\" aria-hidden=\"true\"></canvas>\n <div class=\"hero-inner\">\n <div class=\"card-header ${iconUrl ? \"has-icon\" : \"\"}\">\n ${iconUrl ? `<img src=\"${escapeHtml(iconUrl)}\" alt=\"\" class=\"hero-icon\" width=\"64\" height=\"64\" />` : \"\"}\n <div class=\"hero-row\">\n <h1>${safeName} <span class=\"version\">(v${escapeHtml(version)})</span></h1>\n </div>\n ${safeDescription ? `<p class=\"hero-description\">${safeDescription}</p>` : \"\"}\n <div class=\"hero-url-block\">\n <div class=\"url-block\">\n <div class=\"url-box\" data-copy=\"${escapeHtml(url)}\">${escapeHtml(url)}</div>\n <button type=\"button\" class=\"copy-btn\" data-copy=\"${escapeHtml(url)}\" aria-label=\"Copy URL\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg></button>\n </div>\n </div>\n <div class=\"hero-cta-row\">\n <a href=\"${escapeHtml(manufactInspectorUrl)}\" class=\"hero-primary-btn\" target=\"_blank\" rel=\"noopener noreferrer\">Open in Inspector</a>\n </div>\n <div class=\"hero-powered\">\n <span>Powered by</span>\n <a href=\"https://github.com/mcp-use/mcp-use\" target=\"_blank\" rel=\"noopener noreferrer\">\n <svg class=\"gh-icon\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z\"/></svg>\n github.com/mcp-use/mcp-use\n <img src=\"https://img.shields.io/github/stars/mcp-use/mcp-use\" alt=\"GitHub stars\" class=\"gh-shield\" width=\"90\" height=\"18\" loading=\"lazy\" />\n </a>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"card\">\n <div class=\"card-header\">\n <h2 class=\"card-title\">Installation Guide</h2>\n <p class=\"card-desc\">Choose your preferred MCP client</p>\n </div>\n <div class=\"card-content\">\n <div class=\"tabs-row\" role=\"tablist\">\n <button type=\"button\" class=\"tab active\" role=\"tab\" data-tab=\"claude-code\" aria-selected=\"true\">Claude Code</button>\n <button type=\"button\" class=\"tab\" role=\"tab\" data-tab=\"cursor\" aria-selected=\"false\">Cursor</button>\n <button type=\"button\" class=\"tab\" role=\"tab\" data-tab=\"vscode\" aria-selected=\"false\">VS Code</button>\n <button type=\"button\" class=\"tab\" role=\"tab\" data-tab=\"vscode-insiders\" aria-selected=\"false\">VS Code Insiders</button>\n <button type=\"button\" class=\"tab\" role=\"tab\" data-tab=\"chatgpt\" aria-selected=\"false\">ChatGPT</button>\n </div>\n\n <div id=\"panel-claude-code\" class=\"tab-panel active\">\n <h3>Install in Claude Code</h3>\n <p>Run this command in your terminal:</p>\n <div class=\"code-block\">\n <pre data-copy=\"${escapeHtml(claudeCommand)}\">${escapeHtml(claudeCommand)}</pre>\n <button type=\"button\" class=\"copy-btn\" aria-label=\"Copy\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg></button>\n </div>\n </div>\n\n <div id=\"panel-cursor\" class=\"tab-panel\">\n <h3>Install in Cursor</h3>\n <p>Click the button below to add this MCP server to Cursor:</p>\n <a href=\"${cursorDeepLink}\" class=\"install-btn\">Open in Cursor</a>\n <p>Or add manually: Settings → MCP → Add server</p>\n </div>\n\n <div id=\"panel-vscode\" class=\"tab-panel\">\n <h3>Install in VS Code</h3>\n <p>Click the button below to add this MCP server to VS Code:</p>\n <a href=\"${vscodeDeepLink}\" class=\"install-btn\">Open in VS Code</a>\n <p>Or add manually: Settings → MCP → Add server</p>\n </div>\n\n <div id=\"panel-vscode-insiders\" class=\"tab-panel\">\n <h3>Install in VS Code Insiders</h3>\n <p>Click the button below to add this MCP server to VS Code Insiders:</p>\n <a href=\"${vscodeInsidersDeepLink}\" class=\"install-btn\">Open in VS Code Insiders</a>\n <p>Or add manually: Settings → MCP → Add server</p>\n </div>\n\n <div id=\"panel-chatgpt\" class=\"tab-panel\">\n <h3>Connect with ChatGPT</h3>\n <ol class=\"steps\">\n <li><strong>Enable Developer Mode:</strong> Settings → Connectors → Advanced → Developer mode</li>\n <li><strong>Import this MCP server:</strong> Go to Connectors tab and add: ${escapeHtml(url)}</li>\n <li><strong>Use in conversations:</strong> Choose the MCP server from the Plus menu</li>\n </ol>\n </div>\n </div>\n </div>\n\n ${\n toolsListHtml || promptsListHtml || resourcesListHtml\n ? `\n <div class=\"card\">\n <div class=\"card-header\">\n <h2 class=\"card-title\">Primitives</h2>\n ${toolsListHtml ? `<div class=\"spec-section\"><h3>Tools (${normalizedTools.length})</h3>${toolsListHtml}</div>` : \"\"}\n ${promptsListHtml ? `<div class=\"spec-section\"><h3>Prompts (${prompts!.length})</h3>${promptsListHtml}</div>` : \"\"}\n ${resourcesListHtml ? `<div class=\"spec-section\"><h3>Resources (${resources!.length})</h3>${resourcesListHtml}</div>` : \"\"}\n </div>\n </div>\n `\n : \"\"\n }\n\n <footer class=\"footer-content\">\n <a href=\"https://manufact.com\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"footer-brand-link\" aria-label=\"Manufact\">\n <span class=\"logo-symbol\">\n <svg viewBox=\"0 0 500 500\" xmlns=\"http://www.w3.org/2000/svg\">\n <g class=\"logo-fill\" fill=\"currentColor\" fill-rule=\"nonzero\">\n <path d=\"${LOGO_SVG_PATHS.path1}\"/>\n <circle cx=\"${LOGO_SVG_PATHS.circle.cx}\" cy=\"${LOGO_SVG_PATHS.circle.cy}\" r=\"${LOGO_SVG_PATHS.circle.r}\"/>\n <path d=\"${LOGO_SVG_PATHS.path2}\"/>\n </g>\n <g class=\"logo-stroke\">\n <path d=\"${LOGO_SVG_PATHS.path1}\"/>\n <circle cx=\"${LOGO_SVG_PATHS.circle.cx}\" cy=\"${LOGO_SVG_PATHS.circle.cy}\" r=\"${LOGO_SVG_PATHS.circle.r}\"/>\n <path d=\"${LOGO_SVG_PATHS.path2}\"/>\n </g>\n </svg>\n </span>\n <span>Manufact</span>\n </a>\n </footer>\n</div>\n\n<script>${getMeshGradientScript()}</script>\n<script>\n(function(){\n var tabs = document.querySelectorAll('.tab');\n var panels = document.querySelectorAll('.tab-panel');\n tabs.forEach(function(tab){\n tab.addEventListener('click', function(){\n var target = tab.getAttribute('data-tab');\n tabs.forEach(function(t){ t.classList.remove('active'); t.setAttribute('aria-selected','false'); });\n panels.forEach(function(p){\n var match = p.id === 'panel-' + target;\n p.classList.toggle('active', match);\n p.hidden = !match;\n });\n tab.classList.add('active');\n tab.setAttribute('aria-selected','true');\n });\n });\n var copySvg = '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg>';\n var checkSvg = '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20 6L9 17l-5-5\"/></svg>';\n document.querySelectorAll('.copy-btn').forEach(function(btn){\n btn.addEventListener('click', function(){\n var text = btn.getAttribute('data-copy');\n if (!text) {\n var pre = btn.parentElement.querySelector('pre');\n text = pre ? (pre.getAttribute('data-copy') || pre.textContent) : '';\n }\n if (text) navigator.clipboard.writeText(text).then(function(){\n btn.classList.add('copied');\n btn.innerHTML = checkSvg;\n setTimeout(function(){ btn.classList.remove('copied'); btn.innerHTML = copySvg; }, 2000);\n });\n });\n });\n panels.forEach(function(p){ if(!p.classList.contains('active')) p.hidden = true; });\n})();\n</script>\n</body>\n</html>`;\n}\n"],"mappings":"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","names":[]}
@@ -52,9 +52,9 @@ async function loadClientPackage() {
52
52
  return await importClientModule();
53
53
  } catch (error) {
54
54
  if (!isClientPackageMissing(error)) throw error;
55
- const location = await installClientPackage();
55
+ const installed = await installClientPackage();
56
56
  try {
57
- return location === "sandbox" ? await importSandboxClientModule() : await importClientModule();
57
+ return installed.location === "sandbox" ? await importSandboxClientModule() : await importProjectClientModule(installed.projectRoot);
58
58
  } catch (retryError) {
59
59
  if (isClientPackageMissing(retryError)) {
60
60
  throw new UsageError(INSTALL_HINT);
@@ -78,7 +78,7 @@ async function installClientPackage() {
78
78
  `Failed to install ${CLIENT_PACKAGE}.`
79
79
  );
80
80
  }
81
- return "project";
81
+ return { location: "project", projectRoot };
82
82
  }
83
83
  await mkdir(CLIENT_SDK_DIR, { recursive: true, mode: 448 });
84
84
  await chmod(CLIENT_SDK_DIR, 448);
@@ -102,7 +102,7 @@ async function installClientPackage() {
102
102
  `Failed to install ${CLIENT_PACKAGE}.`
103
103
  );
104
104
  }
105
- return "sandbox";
105
+ return { location: "sandbox" };
106
106
  }
107
107
  function packageManagerInstallArgs(dependency) {
108
108
  const userAgent = process.env["npm_config_user_agent"] ?? "";
@@ -130,6 +130,11 @@ function readClientPeerRange() {
130
130
  async function importClientModule() {
131
131
  return import("@mcp-use/client");
132
132
  }
133
+ async function importProjectClientModule(projectRoot) {
134
+ const parent = pathToFileURL(join(projectRoot, "package.json")).href;
135
+ const resolved = await import.meta.resolve(CLIENT_PACKAGE, parent);
136
+ return import(resolved);
137
+ }
133
138
  async function importSandboxClientModule() {
134
139
  const entry = join(
135
140
  CLIENT_SDK_DIR,
@@ -166,7 +171,38 @@ function spawnAndWait(command, args, cwd) {
166
171
  // src/commands/client.ts
167
172
  var CLIENT_DIR = join2(GLOBAL_STATE_DIR, "client");
168
173
  var SERVERS_PATH = join2(CLIENT_DIR, "servers.json");
174
+ var CLIENT_HELP = `Usage: mcp-use client <command> [options]
175
+
176
+ Commands:
177
+ connect <name> <url> Connect and save an HTTP(S) MCP server
178
+ list List saved servers
179
+ remove <name> Remove a saved server
180
+ <name> Invoke tools/resources/prompts on a saved server
181
+
182
+ Connect options:
183
+ -H, --header <"Key: Value"> Static header (repeatable)
184
+ --no-oauth Skip OAuth on authorization challenges
185
+ --auth-timeout <ms> OAuth wait timeout (default: 300000)
186
+ --protocol <auto|2026-07-28|2025-11-25>
187
+ --open Open the OAuth URL in a browser without prompting
188
+ --no-open Print the OAuth URL only
189
+ --json Emit machine-readable output
190
+
191
+ Saved server commands:
192
+ mcp-use client <name> tools list|describe|call ...
193
+ mcp-use client <name> resources list|read ...
194
+ mcp-use client <name> prompts list|get ...
195
+ mcp-use client <name> auth status|logout
196
+
197
+ Examples:
198
+ mcp-use client connect linear https://mcp.linear.app/mcp
199
+ mcp-use client linear tools list
200
+ mcp-use client linear tools call search_issues query="open bugs"`;
169
201
  async function runClient(argv) {
202
+ if (argv.includes("--help") || argv.includes("-h")) {
203
+ console.log(CLIENT_HELP);
204
+ return 0;
205
+ }
170
206
  const json = wantsJson(argv);
171
207
  try {
172
208
  const first = argv[0];
@@ -194,9 +230,14 @@ async function connect(argv, json) {
194
230
  "no-oauth": { type: "boolean" },
195
231
  "auth-timeout": { type: "string" },
196
232
  protocol: { type: "string", default: "auto" },
233
+ open: { type: "boolean" },
234
+ "no-open": { type: "boolean" },
197
235
  json: { type: "boolean" }
198
236
  }
199
237
  });
238
+ if (values.open === true && values["no-open"] === true) {
239
+ throw new UsageError("Cannot combine --open and --no-open.");
240
+ }
200
241
  if (positionals.length !== 2) {
201
242
  throw new UsageError("Usage: mcp-use client connect <name> <url>");
202
243
  }
@@ -225,7 +266,12 @@ async function connect(argv, json) {
225
266
  name,
226
267
  definition,
227
268
  credentials,
228
- timeout
269
+ timeout,
270
+ resolveBrowserMode({
271
+ open: values.open === true,
272
+ noOpen: values["no-open"] === true,
273
+ json
274
+ })
229
275
  );
230
276
  await connection.disconnect();
231
277
  saved.servers[name] = definition;
@@ -427,17 +473,25 @@ async function callTool(connection, serverName, argv, json) {
427
473
  printResult(result, json);
428
474
  return 0;
429
475
  }
430
- async function openConnection(name, definition, credentials, authTimeoutMs) {
476
+ async function openConnection(name, definition, credentials, authTimeoutMs, browserMode = process.stdin.isTTY ? "ask" : "never") {
431
477
  const { createOAuthProvider, MCPClient } = await loadClientPackage();
432
478
  const oauthBase = oauthDirectory(name);
433
479
  const authProvider = definition.oauth ? await createOAuthProvider(definition.url, {
434
480
  baseDir: oauthBase,
435
481
  authTimeoutMs,
436
482
  storageKeyPrefix: `mcp-use-cli:${name}`,
437
- openBrowser: (url) => {
483
+ openBrowser: async (url) => {
438
484
  process.stderr.write(`Open this URL to authenticate:
439
485
  ${url}
440
486
  `);
487
+ if (browserMode === "never") return;
488
+ if (browserMode === "ask") {
489
+ const accepted = await confirm("Open in browser?", {
490
+ yes: false,
491
+ json: false
492
+ });
493
+ if (!accepted) return;
494
+ }
441
495
  openBrowser(url);
442
496
  }
443
497
  // Conditional exports select NodeOAuthOptions at runtime. TypeScript
@@ -502,6 +556,11 @@ function parseMcpArguments(argv) {
502
556
  }
503
557
  return result;
504
558
  }
559
+ function resolveBrowserMode(options) {
560
+ if (options.json || options.noOpen || !process.stdin.isTTY) return "never";
561
+ if (options.open) return "always";
562
+ return "ask";
563
+ }
505
564
  function parseHeaders(values) {
506
565
  const headers = {};
507
566
  for (const value of values) {
@@ -566,4 +625,4 @@ export {
566
625
  openDirectConnection,
567
626
  parseMcpArguments
568
627
  };
569
- //# sourceMappingURL=chunk-5M5NVF36.js.map
628
+ //# sourceMappingURL=chunk-RHITI5QM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/client.ts","../src/commands/load-client.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { parseArgs } from \"node:util\";\n\nimport type { MCPConnection } from \"@mcp-use/client\";\n\nimport { loadClientPackage } from \"./load-client.js\";\nimport {\n confirm,\n GLOBAL_STATE_DIR,\n openBrowser,\n pathExists,\n printResult,\n readJson,\n reportError,\n UsageError,\n wantsJson,\n writePrivateJson,\n} from \"./shared.js\";\n\ninterface SavedServer {\n url: string;\n oauth: boolean;\n protocol: \"auto\" | \"2026-07-28\" | \"2025-11-25\";\n}\n\ninterface SavedServers {\n servers: Record<string, SavedServer>;\n}\n\ninterface SavedCredentials {\n headers?: Record<string, string>;\n}\n\nconst CLIENT_DIR = join(GLOBAL_STATE_DIR, \"client\");\nconst SERVERS_PATH = join(CLIENT_DIR, \"servers.json\");\n\nconst CLIENT_HELP = `Usage: mcp-use client <command> [options]\n\nCommands:\n connect <name> <url> Connect and save an HTTP(S) MCP server\n list List saved servers\n remove <name> Remove a saved server\n <name> Invoke tools/resources/prompts on a saved server\n\nConnect options:\n -H, --header <\"Key: Value\"> Static header (repeatable)\n --no-oauth Skip OAuth on authorization challenges\n --auth-timeout <ms> OAuth wait timeout (default: 300000)\n --protocol <auto|2026-07-28|2025-11-25>\n --open Open the OAuth URL in a browser without prompting\n --no-open Print the OAuth URL only\n --json Emit machine-readable output\n\nSaved server commands:\n mcp-use client <name> tools list|describe|call ...\n mcp-use client <name> resources list|read ...\n mcp-use client <name> prompts list|get ...\n mcp-use client <name> auth status|logout\n\nExamples:\n mcp-use client connect linear https://mcp.linear.app/mcp\n mcp-use client linear tools list\n mcp-use client linear tools call search_issues query=\"open bugs\"`;\n\ntype BrowserMode = \"ask\" | \"always\" | \"never\";\n\n/** Run the `mcp-use client` command family. */\nexport async function runClient(argv: readonly string[]): Promise<number> {\n if (argv.includes(\"--help\") || argv.includes(\"-h\")) {\n console.log(CLIENT_HELP);\n return 0;\n }\n const json = wantsJson(argv);\n try {\n const first = argv[0];\n if (first === \"connect\") return await connect(argv.slice(1), json);\n if (first === \"list\") return await list(argv.slice(1), json);\n if (first === \"remove\") return await remove(argv.slice(1), json);\n if (first === undefined) {\n throw new UsageError(\"Usage: mcp-use client <connect|list|remove|name>\");\n }\n return await savedServerCommand(first, argv.slice(1), json);\n } catch (error) {\n return reportError(\n error instanceof TypeError ? new UsageError(error.message) : error,\n json\n );\n }\n}\n\nasync function connect(\n argv: readonly string[],\n json: boolean\n): Promise<number> {\n const { values, positionals } = parseArgs({\n args: [...argv],\n allowPositionals: true,\n strict: true,\n options: {\n header: { type: \"string\", short: \"H\", multiple: true },\n \"no-oauth\": { type: \"boolean\" },\n \"auth-timeout\": { type: \"string\" },\n protocol: { type: \"string\", default: \"auto\" },\n open: { type: \"boolean\" },\n \"no-open\": { type: \"boolean\" },\n json: { type: \"boolean\" },\n },\n });\n if (values.open === true && values[\"no-open\"] === true) {\n throw new UsageError(\"Cannot combine --open and --no-open.\");\n }\n if (positionals.length !== 2) {\n throw new UsageError(\"Usage: mcp-use client connect <name> <url>\");\n }\n const [name, rawUrl] = positionals as [string, string];\n validateName(name);\n const url = new URL(rawUrl);\n if (![\"http:\", \"https:\"].includes(url.protocol)) {\n throw new UsageError(\"Client URLs must use http or https.\");\n }\n const protocol = parseProtocol(values.protocol);\n const timeout = parsePositiveInteger(\n values[\"auth-timeout\"] ?? \"300000\",\n \"--auth-timeout\"\n );\n const saved = await readServers();\n if (saved.servers[name] !== undefined) {\n throw new UsageError(`Saved server already exists: ${name}`);\n }\n const credentials = { headers: parseHeaders(values.header ?? []) };\n const definition: SavedServer = {\n url: url.href,\n oauth: values[\"no-oauth\"] !== true,\n protocol,\n };\n const connection = await openConnection(\n name,\n definition,\n credentials,\n timeout,\n resolveBrowserMode({\n open: values.open === true,\n noOpen: values[\"no-open\"] === true,\n json,\n })\n );\n await connection.disconnect();\n saved.servers[name] = definition;\n await writePrivateJson(SERVERS_PATH, saved);\n await writePrivateJson(credentialsPath(name), credentials);\n printResult(\n { name, url: definition.url, protocol },\n json,\n `Connected and saved ${name}.`\n );\n return 0;\n}\n\nasync function list(argv: readonly string[], json: boolean): Promise<number> {\n parseJsonOnly(argv);\n const saved = await readServers();\n const result = Object.entries(saved.servers).map(([name, server]) => ({\n name,\n ...server,\n }));\n printResult(\n result,\n json,\n result.map((server) => `${server.name}\\t${server.url}`).join(\"\\n\") ||\n \"No saved servers.\"\n );\n return 0;\n}\n\nasync function remove(argv: readonly string[], json: boolean): Promise<number> {\n const { values, positionals } = parseArgs({\n args: [...argv],\n allowPositionals: true,\n strict: true,\n options: { yes: { type: \"boolean\" }, json: { type: \"boolean\" } },\n });\n const name = one(positionals, \"mcp-use client remove <name>\");\n if (\n !(await confirm(`Remove saved server ${name}?`, {\n yes: values.yes === true,\n json,\n }))\n ) {\n return 0;\n }\n const saved = await readServers();\n delete saved.servers[name];\n await writePrivateJson(SERVERS_PATH, saved);\n await rm(credentialsDirectory(name), { recursive: true, force: true });\n printResult({ removed: name }, json, `Removed ${name}.`);\n return 0;\n}\n\nasync function savedServerCommand(\n name: string,\n argv: readonly string[],\n json: boolean\n): Promise<number> {\n const saved = await readServers();\n const definition = saved.servers[name];\n if (definition === undefined) {\n throw new UsageError(\n `Unknown saved server: ${name}. Run \\`mcp-use client connect ${name} <url>\\`.`\n );\n }\n const family = argv[0];\n const operation = argv[1];\n if (family === \"auth\") {\n if (operation === \"status\") {\n parseJsonOnly(argv.slice(2));\n const authenticated = await pathExists(oauthDirectory(name));\n printResult(\n { name, oauth: definition.oauth, authenticated },\n json,\n authenticated ? \"Authenticated.\" : \"No saved OAuth session.\"\n );\n return 0;\n }\n if (operation === \"logout\") {\n const { values, positionals } = parseArgs({\n args: [...argv.slice(2)],\n allowPositionals: true,\n strict: true,\n options: { yes: { type: \"boolean\" }, json: { type: \"boolean\" } },\n });\n if (positionals.length !== 0) {\n throw new UsageError(`Usage: mcp-use client ${name} auth logout`);\n }\n if (\n !(await confirm(`Delete OAuth credentials for ${name}?`, {\n yes: values.yes === true,\n json,\n }))\n ) {\n return 0;\n }\n await rm(oauthDirectory(name), { recursive: true, force: true });\n printResult({ loggedOut: name }, json, `Logged out ${name}.`);\n return 0;\n }\n }\n\n const credentials = await readJson<SavedCredentials>(\n credentialsPath(name),\n {}\n );\n const connection = await openConnection(\n name,\n definition,\n credentials,\n 300_000\n );\n try {\n if (family === \"tools\") {\n if (operation === \"list\") {\n parseJsonOnly(argv.slice(2));\n const tools = await connection.listTools();\n printResult(\n tools,\n json,\n tools\n .map((tool) => `${tool.name}\\t${tool.description ?? \"\"}`)\n .join(\"\\n\")\n );\n return 0;\n }\n if (operation === \"describe\") {\n const toolName = one(\n argv.slice(2),\n `mcp-use client ${name} tools describe <tool>`\n );\n const tool = (await connection.listTools()).find(\n (candidate) => candidate.name === toolName\n );\n if (tool === undefined)\n throw new UsageError(`Tool not found: ${toolName}`);\n printResult(tool, json);\n return 0;\n }\n if (operation === \"call\") {\n return await callTool(connection, name, argv.slice(2), json);\n }\n }\n if (family === \"resources\") {\n if (operation === \"list\") {\n parseJsonOnly(argv.slice(2));\n const resources = await connection.listResources();\n printResult(resources, json);\n return 0;\n }\n if (operation === \"read\") {\n const uri = one(\n argv.slice(2),\n `mcp-use client ${name} resources read <uri>`\n );\n printResult(await connection.readResource(uri), json);\n return 0;\n }\n }\n if (family === \"prompts\") {\n if (operation === \"list\") {\n parseJsonOnly(argv.slice(2));\n printResult(await connection.listPrompts(), json);\n return 0;\n }\n if (operation === \"get\") {\n const prompt = argv[2];\n if (prompt === undefined) {\n throw new UsageError(\n `Usage: mcp-use client ${name} prompts get <prompt> [args]`\n );\n }\n printResult(\n await connection.getPrompt(prompt, parseMcpArguments(argv.slice(3))),\n json\n );\n return 0;\n }\n }\n throw new UsageError(\n `Usage: mcp-use client ${name} <tools|resources|prompts|auth> ...`\n );\n } finally {\n await connection.disconnect();\n }\n}\n\nasync function callTool(\n connection: MCPConnection,\n serverName: string,\n argv: readonly string[],\n json: boolean\n): Promise<number> {\n const tool = argv[0];\n if (tool === undefined) {\n throw new UsageError(\n `Usage: mcp-use client ${serverName} tools call <tool> [args]`\n );\n }\n const { values, positionals } = parseArgs({\n args: [...argv.slice(1)],\n allowPositionals: true,\n strict: true,\n options: {\n timeout: { type: \"string\", default: \"30000\" },\n json: { type: \"boolean\" },\n },\n });\n const timeout = parsePositiveInteger(values.timeout, \"--timeout\");\n const result = await connection.callTool(\n tool,\n parseMcpArguments(positionals),\n { timeout }\n );\n if (result.isError === true) {\n throw new Error(\n `Tool ${tool} returned an error: ${JSON.stringify(result)}`\n );\n }\n printResult(result, json);\n return 0;\n}\n\nasync function openConnection(\n name: string,\n definition: SavedServer,\n credentials: SavedCredentials,\n authTimeoutMs: number,\n browserMode: BrowserMode = process.stdin.isTTY ? \"ask\" : \"never\"\n): Promise<MCPConnection> {\n const { createOAuthProvider, MCPClient } = await loadClientPackage();\n const oauthBase = oauthDirectory(name);\n const authProvider = definition.oauth\n ? await createOAuthProvider(definition.url, {\n baseDir: oauthBase,\n authTimeoutMs,\n storageKeyPrefix: `mcp-use-cli:${name}`,\n openBrowser: async (url: string) => {\n process.stderr.write(`Open this URL to authenticate:\\n${url}\\n`);\n if (browserMode === \"never\") return;\n if (browserMode === \"ask\") {\n const accepted = await confirm(\"Open in browser?\", {\n yes: false,\n json: false,\n });\n if (!accepted) return;\n }\n openBrowser(url);\n },\n // Conditional exports select NodeOAuthOptions at runtime. TypeScript\n // resolves the package's browser-default declaration in this build.\n } as unknown as Parameters<typeof createOAuthProvider>[1])\n : undefined;\n const protocolNegotiation =\n definition.protocol === \"auto\" ? \"auto\" : { pin: definition.protocol };\n const client = new MCPClient({\n mcpServers: {\n [name]: {\n url: definition.url,\n ...(credentials.headers !== undefined\n ? { headers: credentials.headers }\n : {}),\n ...(authProvider !== undefined ? { authProvider } : { oauth: false }),\n protocolNegotiation,\n },\n },\n });\n return client.connect(name);\n}\n\n/**\n * Open a saved server for another CLI command.\n *\n * @internal\n */\nexport async function openSavedConnection(\n name: string,\n authTimeoutMs = 300_000\n): Promise<MCPConnection> {\n const saved = await readServers();\n const definition = saved.servers[name];\n if (definition === undefined) {\n throw new UsageError(`Unknown saved server: ${name}`);\n }\n const credentials = await readJson<SavedCredentials>(\n credentialsPath(name),\n {}\n );\n return openConnection(name, definition, credentials, authTimeoutMs);\n}\n\n/**\n * Open an ad-hoc HTTP MCP connection.\n *\n * @internal\n */\nexport async function openDirectConnection(\n url: string,\n headers: Record<string, string>\n): Promise<MCPConnection> {\n return openConnection(\n \"screenshot\",\n { url, oauth: false, protocol: \"auto\" },\n { headers },\n 300_000\n );\n}\n\n/**\n * Parse the CLI's JSON/key-value MCP argument grammar.\n *\n * @internal\n */\nexport function parseMcpArguments(\n argv: readonly string[]\n): Record<string, unknown> {\n if (argv.length === 0) return {};\n if (argv.length === 1 && argv[0]?.trimStart().startsWith(\"{\")) {\n const value = JSON.parse(argv[0]) as unknown;\n if (value === null || Array.isArray(value) || typeof value !== \"object\") {\n throw new UsageError(\"The JSON argument must be an object.\");\n }\n return value as Record<string, unknown>;\n }\n const result: Record<string, unknown> = {};\n for (const token of argv) {\n const typed = token.indexOf(\":=\");\n const plain = token.indexOf(\"=\");\n const separator = typed >= 0 ? typed : plain;\n const width = typed >= 0 ? 2 : 1;\n if (separator <= 0) {\n throw new UsageError(\n `Expected key=value or key:=<json>, received: ${token}`\n );\n }\n const key = token.slice(0, separator).replace(/^--/, \"\");\n const raw = token.slice(separator + width);\n result[key] = typed >= 0 ? (JSON.parse(raw) as unknown) : raw;\n }\n return result;\n}\n\nfunction resolveBrowserMode(options: {\n open: boolean;\n noOpen: boolean;\n json: boolean;\n}): BrowserMode {\n if (options.json || options.noOpen || !process.stdin.isTTY) return \"never\";\n if (options.open) return \"always\";\n return \"ask\";\n}\n\nfunction parseHeaders(values: readonly string[]): Record<string, string> {\n const headers: Record<string, string> = {};\n for (const value of values) {\n const separator = value.indexOf(\":\");\n if (separator <= 0) throw new UsageError(`Invalid header: ${value}`);\n headers[value.slice(0, separator).trim()] = value\n .slice(separator + 1)\n .trim();\n }\n return headers;\n}\n\nfunction parseProtocol(value: string | undefined): SavedServer[\"protocol\"] {\n if (value !== \"auto\" && value !== \"2026-07-28\" && value !== \"2025-11-25\") {\n throw new UsageError(`Invalid protocol: ${value}`);\n }\n return value;\n}\n\nfunction parsePositiveInteger(value: string | undefined, name: string): number {\n const result = Number(value);\n if (!Number.isInteger(result) || result <= 0) {\n throw new UsageError(`${name} must be a positive integer.`);\n }\n return result;\n}\n\nfunction validateName(name: string): void {\n if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(name)) {\n throw new UsageError(\n \"Server names must be 1-64 filesystem-safe letters, numbers, dots, dashes, or underscores.\"\n );\n }\n}\n\nasync function readServers(): Promise<SavedServers> {\n return readJson(SERVERS_PATH, { servers: {} });\n}\n\nfunction credentialsDirectory(name: string): string {\n return join(\n CLIENT_DIR,\n \"credentials\",\n createHash(\"sha256\").update(name).digest(\"hex\")\n );\n}\n\nfunction credentialsPath(name: string): string {\n return join(credentialsDirectory(name), \"credentials.json\");\n}\n\nfunction oauthDirectory(name: string): string {\n return join(credentialsDirectory(name), \"oauth\");\n}\n\nfunction parseJsonOnly(argv: readonly string[]): void {\n parseArgs({\n args: [...argv],\n allowPositionals: false,\n strict: true,\n options: { json: { type: \"boolean\" } },\n });\n}\n\nfunction one(positionals: readonly string[], usage: string): string {\n if (positionals.length !== 1) throw new UsageError(`Usage: ${usage}`);\n return positionals[0]!;\n}\n","import { spawn } from \"node:child_process\";\nimport { readFileSync } from \"node:fs\";\nimport { chmod, mkdir } from \"node:fs/promises\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nimport {\n CommandError,\n GLOBAL_STATE_DIR,\n pathExists,\n UsageError,\n writePrivateJson,\n} from \"./shared.js\";\n\n/** Runtime surface loaded from the independently published client SDK. */\nexport type ClientPackage = typeof import(\"@mcp-use/client\");\n\nconst CLIENT_SDK_DIR = join(GLOBAL_STATE_DIR, \"client-sdk\");\nconst CLIENT_PACKAGE = \"@mcp-use/client\";\nconst DEFAULT_PEER_RANGE = \"^2.0.0-alpha.0\";\n\nconst INSTALL_HINT = [\n `[mcp-use] ${CLIENT_PACKAGE} is not installed.`,\n \"The `mcp-use client` and `mcp-use screenshot` commands require it.\",\n \"Install it in your project:\",\n \"\",\n \" npm install @mcp-use/client\",\n \"\",\n \" pnpm add @mcp-use/client\",\n \"\",\n \" bun add @mcp-use/client\",\n].join(\"\\n\");\n\n/**\n * Walk upward from `startDir` for the nearest directory containing\n * `package.json`.\n */\nexport async function findProjectRoot(\n startDir: string\n): Promise<string | undefined> {\n let current = resolve(startDir);\n for (;;) {\n if (await pathExists(join(current, \"package.json\"))) return current;\n const parent = dirname(current);\n if (parent === current) return undefined;\n current = parent;\n }\n}\n\n/** Where `@mcp-use/client` was auto-installed. */\ninterface InstallLocation {\n location: \"project\" | \"sandbox\";\n projectRoot?: string;\n}\n\n/**\n * Load `@mcp-use/client` on demand so the framework library entry does not\n * pull the client SDK (or legacy v1 transitive deps) into every install.\n *\n * @throws {@link UsageError} When the package is not installed and auto-install\n * fails or the retry import still cannot resolve it.\n */\nexport async function loadClientPackage(): Promise<ClientPackage> {\n try {\n return await importClientModule();\n } catch (error) {\n if (!isClientPackageMissing(error)) throw error;\n\n const installed = await installClientPackage();\n try {\n return installed.location === \"sandbox\"\n ? await importSandboxClientModule()\n : await importProjectClientModule(installed.projectRoot!);\n } catch (retryError) {\n if (isClientPackageMissing(retryError)) {\n throw new UsageError(INSTALL_HINT);\n }\n throw retryError;\n }\n }\n}\n\nasync function installClientPackage(): Promise<InstallLocation> {\n const versionSpec = readClientPeerRange();\n const dependency = `${CLIENT_PACKAGE}@${versionSpec}`;\n const projectRoot = await findProjectRoot(process.cwd());\n\n process.stderr.write(`[mcp-use] installing ${CLIENT_PACKAGE}…\\n`);\n\n if (projectRoot !== undefined) {\n const [command, args] = packageManagerInstallArgs(dependency);\n const code = await spawnAndWait(command, args, projectRoot);\n if (code !== 0) {\n throw new CommandError(\n \"client_install_failed\",\n `Failed to install ${CLIENT_PACKAGE}.`\n );\n }\n return { location: \"project\", projectRoot };\n }\n\n await mkdir(CLIENT_SDK_DIR, { recursive: true, mode: 0o700 });\n await chmod(CLIENT_SDK_DIR, 0o700);\n const manifestPath = join(CLIENT_SDK_DIR, \"package.json\");\n if (!(await pathExists(manifestPath))) {\n await writePrivateJson(manifestPath, {\n private: true,\n dependencies: {\n [CLIENT_PACKAGE]: versionSpec,\n },\n });\n }\n const code = await spawnAndWait(\n \"npm\",\n [\"install\", dependency],\n CLIENT_SDK_DIR\n );\n if (code !== 0) {\n throw new CommandError(\n \"client_install_failed\",\n `Failed to install ${CLIENT_PACKAGE}.`\n );\n }\n return { location: \"sandbox\" };\n}\n\nfunction packageManagerInstallArgs(dependency: string): [string, string[]] {\n const userAgent = process.env[\"npm_config_user_agent\"] ?? \"\";\n if (userAgent.startsWith(\"pnpm/\")) {\n return [\"pnpm\", [\"add\", dependency]];\n }\n if (userAgent.startsWith(\"bun/\")) {\n return [\"bun\", [\"add\", dependency]];\n }\n return [\"npm\", [\"install\", dependency]];\n}\n\nfunction readClientPeerRange(): string {\n for (const relative of [\"../package.json\", \"../../package.json\"]) {\n try {\n const raw = readFileSync(new URL(relative, import.meta.url), \"utf8\");\n const pkg = JSON.parse(raw) as {\n name?: unknown;\n peerDependencies?: Record<string, string>;\n };\n if (pkg.name !== \"mcp-use\") continue;\n const range = pkg.peerDependencies?.[CLIENT_PACKAGE];\n if (typeof range === \"string\" && range.length > 0) return range;\n } catch {\n // Try the next candidate layout.\n }\n }\n return DEFAULT_PEER_RANGE;\n}\n\nasync function importClientModule(): Promise<ClientPackage> {\n return import(\"@mcp-use/client\");\n}\n\n/** @internal Imported from project `node_modules` after auto-install. */\nexport async function importProjectClientModule(\n projectRoot: string\n): Promise<ClientPackage> {\n const parent = pathToFileURL(join(projectRoot, \"package.json\")).href;\n const resolved = await import.meta.resolve(CLIENT_PACKAGE, parent);\n return import(resolved) as Promise<ClientPackage>;\n}\n\nasync function importSandboxClientModule(): Promise<ClientPackage> {\n const entry = join(\n CLIENT_SDK_DIR,\n \"node_modules\",\n CLIENT_PACKAGE,\n \"dist\",\n \"index.js\"\n );\n const mod = (await import(pathToFileURL(entry).href)) as ClientPackage;\n return mod;\n}\n\nfunction isClientPackageMissing(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ERR_MODULE_NOT_FOUND\" || code === \"MODULE_NOT_FOUND\") {\n return (\n error.message.includes(CLIENT_PACKAGE) ||\n error.message.includes(\"Cannot find package\")\n );\n }\n return false;\n}\n\nfunction spawnAndWait(\n command: string,\n args: string[],\n cwd: string\n): Promise<number> {\n return new Promise((resolveCode, reject) => {\n const child = spawn(command, args, {\n cwd,\n stdio: \"inherit\",\n shell: process.platform === \"win32\",\n });\n child.once(\"error\", reject);\n child.once(\"exit\", (code, signal) => {\n resolveCode(signal === \"SIGINT\" ? 130 : (code ?? 1));\n });\n });\n}\n"],"mappings":"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","names":["join","code","join"]}
@@ -47,10 +47,10 @@ function resolveTailwindCss() {
47
47
  return fileURLToPath(import.meta.resolve("tailwindcss/index.css"));
48
48
  }
49
49
 
50
- // src/cli/tools-declaration.ts
50
+ // src/cli/mcp-env-declaration.ts
51
51
  import { writeFile } from "fs/promises";
52
52
  import { extname, join as join3, relative, sep } from "path";
53
- var TOOLS_DECLARATION_NAME = "tools.d.ts";
53
+ var MCP_ENV_DECLARATION_NAME = "mcp-env.d.ts";
54
54
  function declarationImportPath(cwd, entry) {
55
55
  let importPath = relative(cwd, entry).split(sep).join("/");
56
56
  const extension = extname(importPath);
@@ -60,10 +60,12 @@ function declarationImportPath(cwd, entry) {
60
60
  }
61
61
  return importPath.startsWith(".") ? importPath : `./${importPath}`;
62
62
  }
63
- function renderToolsDeclaration(cwd, entry) {
63
+ function renderMcpEnvDeclaration(cwd, entry) {
64
64
  const importPath = declarationImportPath(cwd, entry);
65
65
  return [
66
- "// Created by mcp-use when missing. Existing files are never overwritten.",
66
+ "// mcp-use generated env declaration",
67
+ 'declare module "*.css";',
68
+ "",
67
69
  'declare module "mcp-use/react" {',
68
70
  " interface Register {",
69
71
  ` tools: typeof import(${JSON.stringify(importPath)});`,
@@ -74,10 +76,10 @@ function renderToolsDeclaration(cwd, entry) {
74
76
  ""
75
77
  ].join("\n");
76
78
  }
77
- async function ensureToolsDeclaration(cwd, entry) {
78
- const declarationPath = join3(cwd, TOOLS_DECLARATION_NAME);
79
+ async function ensureMcpEnvDeclaration(cwd, entry) {
80
+ const declarationPath = join3(cwd, MCP_ENV_DECLARATION_NAME);
79
81
  try {
80
- await writeFile(declarationPath, renderToolsDeclaration(cwd, entry), {
82
+ await writeFile(declarationPath, renderMcpEnvDeclaration(cwd, entry), {
81
83
  encoding: "utf8",
82
84
  flag: "wx"
83
85
  });
@@ -113,19 +115,20 @@ function resolveWorkspacePaths(projectRoot) {
113
115
  // src/cli/views.ts
114
116
  import { existsSync as existsSync3, readdirSync } from "fs";
115
117
  import { join as join5 } from "path";
118
+ var VIEWS_SOURCE_DIR = "views";
116
119
  var VIRTUAL_VIEW_PREFIX = "virtual:mcp-use/views/";
117
120
  var VIRTUAL_VIEW_RESOLVED_PREFIX = `\0${VIRTUAL_VIEW_PREFIX}`;
118
121
  function discoverViews(cwd) {
119
- const resourcesDir = join5(cwd, "resources");
120
- if (!existsSync3(resourcesDir)) {
122
+ const viewsDir = join5(cwd, VIEWS_SOURCE_DIR);
123
+ if (!existsSync3(viewsDir)) {
121
124
  return [];
122
125
  }
123
126
  const views = [];
124
- for (const entry of readdirSync(resourcesDir, { withFileTypes: true })) {
127
+ for (const entry of readdirSync(viewsDir, { withFileTypes: true })) {
125
128
  if (!entry.isDirectory()) {
126
129
  continue;
127
130
  }
128
- const entryPath = join5(resourcesDir, entry.name, "view.tsx");
131
+ const entryPath = join5(viewsDir, entry.name, "view.tsx");
129
132
  if (existsSync3(entryPath)) {
130
133
  views.push({ name: entry.name, entryPath });
131
134
  }
@@ -141,7 +144,7 @@ function devVirtualEntryPath(name) {
141
144
  }
142
145
  function isViewPath(file, cwd) {
143
146
  const rel = file.startsWith(cwd) ? file.slice(cwd.length + 1) : file;
144
- return /^resources\/[^/]+\//.test(rel) || /^resources\/[^/]+\/view\.tsx$/.test(rel);
147
+ return /^views\/[^/]+\//.test(rel) || /^views\/[^/]+\/view\.tsx$/.test(rel);
145
148
  }
146
149
  function buildDevViewsManifest(views) {
147
150
  const manifest = {};
@@ -225,7 +228,7 @@ export {
225
228
  discoverEntry,
226
229
  resolveUserViteConfig,
227
230
  resolveTailwindCss,
228
- ensureToolsDeclaration,
231
+ ensureMcpEnvDeclaration,
229
232
  resolveWorkspacePaths,
230
233
  discoverViews,
231
234
  virtualViewId,
@@ -234,4 +237,4 @@ export {
234
237
  createBindingValidationServer,
235
238
  mcpUseViewsPlugin
236
239
  };
237
- //# sourceMappingURL=chunk-DQ7LE4ZA.js.map
240
+ //# sourceMappingURL=chunk-XKJP5S7C.js.map