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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/bin/main.d.ts.map +1 -1
- package/dist/bin.js +5 -2
- package/dist/bin.js.map +1 -1
- package/dist/branding.d.ts +7 -10
- package/dist/branding.d.ts.map +1 -1
- package/dist/{chunk-GTOOHAI2.js → chunk-JEVBOMCE.js} +4 -3
- package/dist/chunk-JEVBOMCE.js.map +1 -0
- package/dist/{chunk-5M5NVF36.js → chunk-RHITI5QM.js} +67 -8
- package/dist/chunk-RHITI5QM.js.map +1 -0
- package/dist/{chunk-DQ7LE4ZA.js → chunk-XKJP5S7C.js} +17 -14
- package/dist/chunk-XKJP5S7C.js.map +1 -0
- package/dist/cli/build.d.ts +1 -1
- package/dist/cli/dev.d.ts.map +1 -1
- package/dist/cli/mcp-env-declaration.d.ts +20 -0
- package/dist/cli/mcp-env-declaration.d.ts.map +1 -0
- package/dist/cli/tunnel.d.ts.map +1 -1
- package/dist/cli/views.d.ts +7 -5
- package/dist/cli/views.d.ts.map +1 -1
- package/dist/commands/build.js +6 -6
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/client.d.ts.map +1 -1
- package/dist/commands/client.js +1 -1
- package/dist/commands/dev.js +79 -12
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/load-client.d.ts +2 -0
- package/dist/commands/load-client.d.ts.map +1 -1
- package/dist/commands/screenshot.js +1 -1
- package/dist/config.d.ts +8 -8
- package/dist/index.js +32 -51
- package/dist/index.js.map +1 -1
- package/dist/inspector-shell.d.ts +3 -0
- package/dist/inspector-shell.d.ts.map +1 -1
- package/dist/{landing-handler-3VN4BMR2.js → landing-handler-Z7WDR4S2.js} +6 -3
- package/dist/landing-handler-Z7WDR4S2.js.map +1 -0
- package/dist/landing-handler.d.ts +1 -1
- package/dist/landing-handler.d.ts.map +1 -1
- package/dist/landing.d.ts +2 -0
- package/dist/landing.d.ts.map +1 -1
- package/dist/landing.js +1 -1
- package/dist/react/types/register.d.ts +1 -1
- package/dist/react/types/register.d.ts.map +1 -1
- package/dist/server.d.ts +2 -3
- package/dist/server.d.ts.map +1 -1
- package/package.json +8 -8
- package/dist/chunk-5M5NVF36.js.map +0 -1
- package/dist/chunk-DQ7LE4ZA.js.map +0 -1
- package/dist/chunk-GTOOHAI2.js.map +0 -1
- package/dist/cli/tools-declaration.d.ts +0 -22
- package/dist/cli/tools-declaration.d.ts.map +0 -1
- package/dist/landing-handler-3VN4BMR2.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/entry.ts","../src/cli/vite-config.ts","../src/cli/mcp-env-declaration.ts","../src/cli/workspace.ts","../src/cli/views.ts","../src/cli/views-plugin.ts"],"sourcesContent":["/**\n * Server-entry discovery for `mcp-use build` and `mcp-use dev`.\n *\n * The entry contract (CLI_SPEC.md): the user's entry module default-exports\n * the `MCPServer` instance and never calls `listen()` itself — the CLI owns\n * the socket.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { isAbsolute, join, resolve } from \"node:path\";\n\n/**\n * Conventional entry locations, checked in order relative to the project\n * root; the first existing file wins.\n *\n * @internal\n */\nexport const ENTRY_CANDIDATES = [\n \"src/index.ts\",\n \"src/server.ts\",\n \"index.ts\",\n \"server.ts\",\n] as const;\n\n/**\n * Locate the server entry for a project.\n *\n * With `override` set (the `--entry` flag), the path is resolved against\n * `cwd` and must exist. Otherwise the {@link ENTRY_CANDIDATES} are probed in\n * order and the first hit wins.\n *\n * @param cwd - Absolute path to the project root.\n * @param override - Explicit entry path (`--entry`), absolute or relative to `cwd`.\n * @returns Absolute path to the entry file.\n * @throws If the override does not exist, or no conventional candidate is\n * found — the error lists every location that was checked.\n *\n * @internal\n */\nexport function discoverEntry(cwd: string, override?: string): string {\n if (override !== undefined) {\n const entry = isAbsolute(override) ? override : resolve(cwd, override);\n if (!existsSync(entry)) {\n throw new Error(`Entry not found: ${entry} (from --entry \"${override}\")`);\n }\n return entry;\n }\n for (const candidate of ENTRY_CANDIDATES) {\n const entry = join(cwd, candidate);\n if (existsSync(entry)) {\n return entry;\n }\n }\n throw new Error(\n `No server entry found in ${cwd}. Looked for: ` +\n `${ENTRY_CANDIDATES.join(\", \")}. ` +\n `Create one of these (default-exporting your MCPServer instance) ` +\n `or pass --entry <path>.`\n );\n}\n","/**\n * Resolve the project-level Vite config used only by the views client build.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst VITE_CONFIG_CANDIDATES = [\n \"vite.config.ts\",\n \"vite.config.js\",\n \"vite.config.mts\",\n \"vite.config.cjs\",\n] as const;\n\n/**\n * Locate a project Vite config, or disable config loading when absent.\n *\n * @param cwd - Absolute project root.\n * @returns Absolute config path or `false`.\n *\n * @internal\n */\nexport function resolveUserViteConfig(cwd: string): string | false {\n for (const name of VITE_CONFIG_CANDIDATES) {\n const path = join(cwd, name);\n if (existsSync(path)) return path;\n }\n return false;\n}\n\n/**\n * Resolve the framework-owned Tailwind stylesheet for project CSS imports.\n *\n * @returns Absolute path exported by the installed `tailwindcss` dependency.\n *\n * @internal\n */\nexport function resolveTailwindCss(): string {\n return fileURLToPath(import.meta.resolve(\"tailwindcss/index.css\"));\n}\n","/**\n * Root-level MCP env declaration shared by `mcp-use dev` and `mcp-use build`.\n *\n * Combines CSS module typing and a live type-only edge to the server entry so\n * exported `ToolRef`s update in TypeScript without rerunning the CLI.\n */\n\nimport { writeFile } from \"node:fs/promises\";\nimport { extname, join, relative, sep } from \"node:path\";\n\n/** Filename of the project-owned MCP env declaration. */\nexport const MCP_ENV_DECLARATION_NAME = \"mcp-env.d.ts\";\n\nfunction declarationImportPath(cwd: string, entry: string): string {\n let importPath = relative(cwd, entry).split(sep).join(\"/\");\n const extension = extname(importPath);\n const runtimeExtension =\n extension === \".mts\"\n ? \".mjs\"\n : extension === \".cts\"\n ? \".cjs\"\n : extension === \".ts\" || extension === \".tsx\"\n ? \".js\"\n : extension;\n\n if (extension !== runtimeExtension) {\n importPath = `${importPath.slice(0, -extension.length)}${runtimeExtension}`;\n }\n return importPath.startsWith(\".\") ? importPath : `./${importPath}`;\n}\n\n/** Build the stable declaration contents for a discovered server entry. */\nexport function renderMcpEnvDeclaration(cwd: string, entry: string): string {\n const importPath = declarationImportPath(cwd, entry);\n return [\n \"// mcp-use generated env declaration\",\n 'declare module \"*.css\";',\n \"\",\n 'declare module \"mcp-use/react\" {',\n \" interface Register {\",\n ` tools: typeof import(${JSON.stringify(importPath)});`,\n \" }\",\n \"}\",\n \"\",\n \"export {};\",\n \"\",\n ].join(\"\\n\");\n}\n\n/**\n * Create the root `mcp-env.d.ts` if absent.\n *\n * Exclusive-create mode makes this safe when dev and build start together and\n * guarantees that a user-authored declaration is never truncated or replaced.\n *\n * @returns `true` when this invocation created the file.\n */\nexport async function ensureMcpEnvDeclaration(\n cwd: string,\n entry: string\n): Promise<boolean> {\n const declarationPath = join(cwd, MCP_ENV_DECLARATION_NAME);\n try {\n await writeFile(declarationPath, renderMcpEnvDeclaration(cwd, entry), {\n encoding: \"utf8\",\n flag: \"wx\",\n });\n return true;\n } catch (error) {\n if (\n error !== null &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === \"EEXIST\"\n ) {\n return false;\n }\n throw error;\n }\n}\n","/**\n * The per-project `.mcp-use/` workspace convention — the Next.js `.next`\n * analog. Everything tooling writes for a project lives under this single,\n * gitignored directory so a checkout stays clean and `rm -rf .mcp-use` is\n * always safe.\n *\n * The layout is a fixed convention, not configuration: there is deliberately\n * no config file and no `outDir` knob (runtime/project configuration lives on\n * the `MCPServer` constructor).\n *\n * This module is PURE: it only derives path strings (no filesystem access).\n *\n * Layout (relative to the project root):\n *\n * ```text\n * .mcp-use/\n * ├─ build/ ← compiled server + manifest.json (this package)\n * ├─ generated/ ← output of the typegen escape-hatch command — reserved (VIEWS_SPEC.md)\n * ├─ cache/ ← disposable dev/build scratch\n * ├─ state/ ← mutable runtime state (e.g. tunnel.json)\n * └─ cloud/ ← cloud linkage (link.json)\n * ```\n *\n * `build/` must contain NO mutable runtime state (that is `state/`'s job) so\n * build output stays reproducible and disposable. This is the per-project\n * workspace, distinct from the global `~/.mcp-use/` store (CLI auth,\n * credentials, per-user caches).\n */\n\nimport { join } from \"node:path\";\n\n/**\n * Fixed name of the per-project workspace directory.\n *\n * @internal\n */\nexport const WORKSPACE_DIR_NAME = \".mcp-use\";\n\n/**\n * Basename of the build manifest written inside the build output directory.\n *\n * @internal\n */\nexport const BUILD_MANIFEST_NAME = \"manifest.json\";\n\n/**\n * Manifest written to `.mcp-use/build/manifest.json` by {@link runBuild} and\n * read back by `mcp-use start`.\n *\n * @internal\n */\nexport interface BuildManifest {\n /** Unique identifier for this build (random hex, regenerated per build). */\n buildId: string;\n /**\n * Filename of the emitted server entry, relative to the build directory\n * (e.g. `\"index.js\"`). `mcp-use start` imports `<build>/<entryPoint>` and\n * serves its default export.\n */\n entryPoint: string;\n /** ISO-8601 timestamp of when the build finished. */\n createdAt: string;\n /**\n * Whether the build was created with `mcp-use build --with-inspector`.\n * Consumed by `mcp-use start` to decide whether to mount the inspector shell.\n */\n inspector: boolean;\n}\n\n/**\n * Every resolved path for a project's `.mcp-use/` workspace.\n *\n * @internal\n */\nexport interface WorkspacePaths {\n /** The project root (the directory containing `.mcp-use/`). */\n projectRoot: string;\n /** The `.mcp-use/` workspace directory. */\n workspace: string;\n /** Build output directory: `.mcp-use/build`. */\n build: string;\n /**\n * Generated `.d.ts` artifacts directory — reserved for the typegen\n * escape-hatch command (VIEWS_SPEC.md § Typegen, demoted).\n */\n generated: string;\n /** Disposable dev/build scratch directory. */\n cache: string;\n /** Mutable runtime state directory. */\n state: string;\n /** Cloud linkage directory — reserved. */\n cloud: string;\n /** Build manifest: `<build>/manifest.json`. */\n buildManifest: string;\n /** Tunnel subdomain persistence: `<state>/tunnel.json`. */\n tunnel: string;\n}\n\n/**\n * Derive every workspace path for a project from its root. Pure — no\n * filesystem access.\n *\n * @param projectRoot - Absolute path to the project root.\n *\n * @example\n * ```ts\n * const paths = resolveWorkspacePaths(process.cwd());\n * console.log(paths.build); // <cwd>/.mcp-use/build\n * ```\n *\n * @internal\n */\nexport function resolveWorkspacePaths(projectRoot: string): WorkspacePaths {\n const workspace = join(projectRoot, WORKSPACE_DIR_NAME);\n const build = join(workspace, \"build\");\n return {\n projectRoot,\n workspace,\n build,\n generated: join(workspace, \"generated\"),\n cache: join(workspace, \"cache\"),\n state: join(workspace, \"state\"),\n cloud: join(workspace, \"cloud\"),\n buildManifest: join(build, BUILD_MANIFEST_NAME),\n tunnel: join(workspace, \"state\", \"tunnel.json\"),\n };\n}\n","/**\n * View discovery for `mcp-use build` / `mcp-use dev`.\n *\n * Views live under `views/<name>/view.tsx` (VIEWS_SPEC.md § File-based views).\n */\n\nimport { existsSync, readdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { ViteDevServer } from \"vite\";\n\nimport type { ViewsManifest } from \"../views/types.js\";\n\n/** Author-facing view source directory at the project root. */\nexport const VIEWS_SOURCE_DIR = \"views\" as const;\n\n/** Prefix for per-view virtual entry modules (`virtual:mcp-use/views/<name>`). */\nexport const VIRTUAL_VIEW_PREFIX = \"virtual:mcp-use/views/\";\n\n/** Resolved virtual id prefix (Rollup null-prefixed module id). */\nexport const VIRTUAL_VIEW_RESOLVED_PREFIX = `\\0${VIRTUAL_VIEW_PREFIX}`;\n\n/**\n * One discovered view directory.\n *\n * @internal\n */\nexport interface DiscoveredView {\n /** View directory name (the `views/<name>` segment). */\n name: string;\n /** Absolute path to `views/<name>/view.tsx`. */\n entryPath: string;\n}\n\n/**\n * Scan `views/<name>/view.tsx` under the project root.\n *\n * A missing or empty `views/` directory yields an empty list — tool-only\n * projects keep byte-identical CLI behavior.\n *\n * @param cwd - Absolute project root.\n * @returns Discovered views sorted by name.\n *\n * @internal\n */\nexport function discoverViews(cwd: string): DiscoveredView[] {\n const viewsDir = join(cwd, VIEWS_SOURCE_DIR);\n if (!existsSync(viewsDir)) {\n return [];\n }\n\n const views: DiscoveredView[] = [];\n for (const entry of readdirSync(viewsDir, { withFileTypes: true })) {\n if (!entry.isDirectory()) {\n continue;\n }\n const entryPath = join(viewsDir, entry.name, \"view.tsx\");\n if (existsSync(entryPath)) {\n views.push({ name: entry.name, entryPath });\n }\n }\n views.sort((a, b) => a.name.localeCompare(b.name));\n return views;\n}\n\n/**\n * Virtual module id for a view entry (`virtual:mcp-use/views/<name>`).\n *\n * @param name - View directory name.\n *\n * @internal\n */\nexport function virtualViewId(name: string): string {\n return `${VIRTUAL_VIEW_PREFIX}${name}`;\n}\n\n/**\n * Dev URL path Vite serves a resolved virtual module at (browser-loadable).\n *\n * @param name - View directory name.\n *\n * @internal\n */\nexport function devVirtualEntryPath(name: string): string {\n return `/@id/__x00__${VIRTUAL_VIEW_PREFIX}${name}`;\n}\n\n/**\n * Whether a filesystem path is a view component file or lives under a view dir.\n *\n * @internal\n */\nexport function isViewPath(file: string, cwd: string): boolean {\n const rel = file.startsWith(cwd) ? file.slice(cwd.length + 1) : file;\n return /^views\\/[^/]+\\//.test(rel) || /^views\\/[^/]+\\/view\\.tsx$/.test(rel);\n}\n\n/**\n * Whether a path is a view's `view.tsx` entry.\n *\n * @internal\n */\nexport function isViewEntryPath(file: string, cwd: string): boolean {\n const rel = file.startsWith(cwd) ? file.slice(cwd.length + 1) : file;\n return /^views\\/[^/]+\\/view\\.tsx$/.test(rel);\n}\n\n/**\n * Build a dev-shaped views manifest (Vite URLs, `/@vite/client` script hook).\n *\n * @internal\n */\nexport function buildDevViewsManifest(views: DiscoveredView[]): ViewsManifest {\n const manifest: ViewsManifest = {};\n for (const view of views) {\n manifest[view.name] = {\n kind: \"external\",\n entry: devVirtualEntryPath(view.name),\n css: [],\n scripts: [\"/@vite/client\"],\n };\n }\n return manifest;\n}\n\n/**\n * Create a temporary Vite dev server for build-time binding validation.\n *\n * @internal\n */\nexport async function createBindingValidationServer(\n cwd: string,\n cacheDir: string,\n configFile: string | false\n): Promise<ViteDevServer> {\n const { createServer } = await import(\"vite\");\n return createServer({\n root: cwd,\n configFile,\n envFile: false,\n logLevel: \"warn\",\n cacheDir,\n server: { middlewareMode: true, hmr: false },\n ssr: { external: true },\n });\n}\n","/**\n * Vite plugin: virtual view entry modules and optional SSR wrapper entry.\n */\n\nimport type { Plugin } from \"vite\";\n\nimport type { DiscoveredView } from \"./views.js\";\nimport {\n VIRTUAL_VIEW_PREFIX,\n VIRTUAL_VIEW_RESOLVED_PREFIX,\n virtualViewId,\n} from \"./views.js\";\n\nconst VIRTUAL_TAILWIND_ID = \"virtual:mcp-use/tailwind.css\";\nconst VIRTUAL_TAILWIND_RESOLVED_ID = `\\0${VIRTUAL_TAILWIND_ID}`;\n\n/**\n * Options for {@link mcpUseViewsPlugin}.\n *\n * @internal\n */\nexport interface McpUseViewsPluginOptions {\n /** Static list or live getter (dev rediscovery). */\n getViews: () => DiscoveredView[];\n /**\n * Dev-mode entry shape. When present, every virtual entry self-accepts HMR\n * updates (`import.meta.hot.accept()`) so an update that propagates past the\n * view module re-runs the bootstrap instead of full-reloading the iframe\n * document (which would wipe bridge state). Absent for builds — entries stay\n * byte-identical to the production contract.\n */\n dev?: {\n /**\n * Whether React Fast Refresh is active (`@vitejs/plugin-react` resolved).\n * When `true`, entries import the plugin's virtual refresh preamble\n * (`@vitejs/plugin-react/preamble`) before any component module so the\n * refresh runtime hooks the document — the role `transformIndexHtml`\n * plays for Vite-served HTML, which synthesized srcdoc documents never\n * pass through.\n */\n reactRefresh: boolean;\n };\n}\n\n/**\n * Vite plugin that resolves `virtual:mcp-use/views/<name>` to bootstrap code.\n *\n * Applies only to the **client** environment.\n *\n * @internal\n */\nexport function mcpUseViewsPlugin(options: McpUseViewsPluginOptions): Plugin {\n return {\n name: \"mcp-use-views\",\n applyToEnvironment(environment) {\n return environment.name === \"client\";\n },\n resolveId(id) {\n if (id === VIRTUAL_TAILWIND_ID) {\n return VIRTUAL_TAILWIND_RESOLVED_ID;\n }\n if (!id.startsWith(VIRTUAL_VIEW_PREFIX)) {\n return undefined;\n }\n return `\\0${id}`;\n },\n load(id) {\n if (id === VIRTUAL_TAILWIND_RESOLVED_ID) {\n return `@import \"tailwindcss\";`;\n }\n if (!id.startsWith(VIRTUAL_VIEW_RESOLVED_PREFIX)) {\n return undefined;\n }\n const name = id.slice(VIRTUAL_VIEW_RESOLVED_PREFIX.length);\n const view = options.getViews().find((v) => v.name === name);\n if (view === undefined) {\n return undefined;\n }\n const lines: string[] = [];\n if (options.dev?.reactRefresh === true) {\n // Must be the first import: the preamble hooks the refresh runtime\n // into the window before react-dom (via the bootstrap import below)\n // or any refresh-wrapped view module evaluates.\n lines.push(`import \"@vitejs/plugin-react/preamble\";`);\n }\n lines.push(`import ${JSON.stringify(VIRTUAL_TAILWIND_ID)};`);\n lines.push(\n `import { bootstrapView } from \"mcp-use/react\";`,\n `import * as viewModule from ${JSON.stringify(view.entryPath)};`,\n `bootstrapView(viewModule);`\n );\n if (options.dev !== undefined) {\n lines.push(\n `if (import.meta.hot) {`,\n ` import.meta.hot.accept();`,\n `}`\n );\n }\n lines.push(\"\");\n return lines.join(\"\\n\");\n },\n };\n}\n\n/**\n * Rollup input map for a client views build (one entry per view).\n *\n * @internal\n */\nexport function clientBuildInputs(\n views: DiscoveredView[]\n): Record<string, string> {\n const input: Record<string, string> = {};\n for (const view of views) {\n input[view.name] = virtualViewId(view.name);\n }\n return input;\n}\n"],"mappings":"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","names":["existsSync","join","join","join","existsSync","join"]}
|
package/dist/cli/build.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* `mcp-use build` — Vite SSR/node build of the user's server entry into the
|
|
3
3
|
* `.mcp-use/build/` workspace directory (CLI_SPEC.md § Commands → build).
|
|
4
4
|
*
|
|
5
|
-
* When views exist (under `
|
|
5
|
+
* When views exist (under `views/<name>/view.tsx`), also runs a client-environment
|
|
6
6
|
* build per view (hashed assets on disk), validates bindings, and emits a
|
|
7
7
|
* wrapper entry that primes views before re-exporting the server (VIEWS_SPEC.md §
|
|
8
8
|
* Build system).
|
package/dist/cli/dev.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/cli/dev.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAyDH;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,yCAAyC;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;;;;;;OAYG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAwID;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,MAAM,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/cli/dev.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAyDH;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,yCAAyC;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;;;;;;OAYG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAwID;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,MAAM,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAwb/D"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Root-level MCP env declaration shared by `mcp-use dev` and `mcp-use build`.
|
|
3
|
+
*
|
|
4
|
+
* Combines CSS module typing and a live type-only edge to the server entry so
|
|
5
|
+
* exported `ToolRef`s update in TypeScript without rerunning the CLI.
|
|
6
|
+
*/
|
|
7
|
+
/** Filename of the project-owned MCP env declaration. */
|
|
8
|
+
export declare const MCP_ENV_DECLARATION_NAME = "mcp-env.d.ts";
|
|
9
|
+
/** Build the stable declaration contents for a discovered server entry. */
|
|
10
|
+
export declare function renderMcpEnvDeclaration(cwd: string, entry: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Create the root `mcp-env.d.ts` if absent.
|
|
13
|
+
*
|
|
14
|
+
* Exclusive-create mode makes this safe when dev and build start together and
|
|
15
|
+
* guarantees that a user-authored declaration is never truncated or replaced.
|
|
16
|
+
*
|
|
17
|
+
* @returns `true` when this invocation created the file.
|
|
18
|
+
*/
|
|
19
|
+
export declare function ensureMcpEnvDeclaration(cwd: string, entry: string): Promise<boolean>;
|
|
20
|
+
//# sourceMappingURL=mcp-env-declaration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-env-declaration.d.ts","sourceRoot":"","sources":["../../src/cli/mcp-env-declaration.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,yDAAyD;AACzD,eAAO,MAAM,wBAAwB,iBAAiB,CAAC;AAoBvD,2EAA2E;AAC3E,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAe1E;AAED;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC,CAmBlB"}
|
package/dist/cli/tunnel.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tunnel.d.ts","sourceRoot":"","sources":["../../src/cli/tunnel.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAQD;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,+DAA+D;IAC/D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,4EAA4E;IAC5E,MAAM,IAAI;QAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;CAClC;
|
|
1
|
+
{"version":3,"file":"tunnel.d.ts","sourceRoot":"","sources":["../../src/cli/tunnel.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAQD;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,+DAA+D;IAC/D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,4EAA4E;IAC5E,MAAM,IAAI;QAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;CAClC;AAKD;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,aAAa,CAiTxE"}
|
package/dist/cli/views.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* View discovery for `mcp-use build` / `mcp-use dev`.
|
|
3
3
|
*
|
|
4
|
-
* Views live under `
|
|
4
|
+
* Views live under `views/<name>/view.tsx` (VIEWS_SPEC.md § File-based views).
|
|
5
5
|
*/
|
|
6
6
|
import type { ViteDevServer } from "vite";
|
|
7
7
|
import type { ViewsManifest } from "../views/types.js";
|
|
8
|
+
/** Author-facing view source directory at the project root. */
|
|
9
|
+
export declare const VIEWS_SOURCE_DIR: "views";
|
|
8
10
|
/** Prefix for per-view virtual entry modules (`virtual:mcp-use/views/<name>`). */
|
|
9
11
|
export declare const VIRTUAL_VIEW_PREFIX = "virtual:mcp-use/views/";
|
|
10
12
|
/** Resolved virtual id prefix (Rollup null-prefixed module id). */
|
|
@@ -15,15 +17,15 @@ export declare const VIRTUAL_VIEW_RESOLVED_PREFIX = "\0virtual:mcp-use/views/";
|
|
|
15
17
|
* @internal
|
|
16
18
|
*/
|
|
17
19
|
export interface DiscoveredView {
|
|
18
|
-
/** View directory name (the `
|
|
20
|
+
/** View directory name (the `views/<name>` segment). */
|
|
19
21
|
name: string;
|
|
20
|
-
/** Absolute path to `
|
|
22
|
+
/** Absolute path to `views/<name>/view.tsx`. */
|
|
21
23
|
entryPath: string;
|
|
22
24
|
}
|
|
23
25
|
/**
|
|
24
|
-
* Scan `
|
|
26
|
+
* Scan `views/<name>/view.tsx` under the project root.
|
|
25
27
|
*
|
|
26
|
-
* A missing or empty `
|
|
28
|
+
* A missing or empty `views/` directory yields an empty list — tool-only
|
|
27
29
|
* projects keep byte-identical CLI behavior.
|
|
28
30
|
*
|
|
29
31
|
* @param cwd - Absolute project root.
|
package/dist/cli/views.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"views.d.ts","sourceRoot":"","sources":["../../src/cli/views.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,kFAAkF;AAClF,eAAO,MAAM,mBAAmB,2BAA2B,CAAC;AAE5D,mEAAmE;AACnE,eAAO,MAAM,4BAA4B,6BAA6B,CAAC;AAEvE;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,
|
|
1
|
+
{"version":3,"file":"views.d.ts","sourceRoot":"","sources":["../../src/cli/views.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB,EAAG,OAAgB,CAAC;AAEjD,kFAAkF;AAClF,eAAO,MAAM,mBAAmB,2BAA2B,CAAC;AAE5D,mEAAmE;AACnE,eAAO,MAAM,4BAA4B,6BAA6B,CAAC;AAEvE;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,EAAE,CAkB3D;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAG7D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAGlE;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,aAAa,CAW5E;AAED;;;;GAIG;AACH,wBAAsB,6BAA6B,CACjD,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GAAG,KAAK,GACzB,OAAO,CAAC,aAAa,CAAC,CAWxB"}
|
package/dist/commands/build.js
CHANGED
|
@@ -2,13 +2,13 @@ import {
|
|
|
2
2
|
createBindingValidationServer,
|
|
3
3
|
discoverEntry,
|
|
4
4
|
discoverViews,
|
|
5
|
-
|
|
5
|
+
ensureMcpEnvDeclaration,
|
|
6
6
|
mcpUseViewsPlugin,
|
|
7
7
|
resolveTailwindCss,
|
|
8
8
|
resolveUserViteConfig,
|
|
9
9
|
resolveWorkspacePaths,
|
|
10
10
|
virtualViewId
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-XKJP5S7C.js";
|
|
12
12
|
import {
|
|
13
13
|
viewAssetsBasePath
|
|
14
14
|
} from "../chunk-STCR3P5O.js";
|
|
@@ -211,8 +211,8 @@ async function buildExternalView(view, options) {
|
|
|
211
211
|
async function runBuild(options) {
|
|
212
212
|
const startedAt = performance.now();
|
|
213
213
|
const entry = discoverEntry(options.cwd, options.entry);
|
|
214
|
-
if (await
|
|
215
|
-
console.log("[mcp-use] created
|
|
214
|
+
if (await ensureMcpEnvDeclaration(options.cwd, entry)) {
|
|
215
|
+
console.log("[mcp-use] created mcp-env.d.ts");
|
|
216
216
|
}
|
|
217
217
|
const paths = resolveWorkspacePaths(options.cwd);
|
|
218
218
|
const views = discoverViews(options.cwd);
|
|
@@ -229,7 +229,7 @@ async function runBuild(options) {
|
|
|
229
229
|
ssr: entry,
|
|
230
230
|
outDir: paths.build,
|
|
231
231
|
emptyOutDir: true,
|
|
232
|
-
target: "
|
|
232
|
+
target: "node22",
|
|
233
233
|
sourcemap: true,
|
|
234
234
|
minify: false,
|
|
235
235
|
rollupOptions: {
|
|
@@ -335,7 +335,7 @@ async function runBuild(options) {
|
|
|
335
335
|
ssr: wrapperEntry,
|
|
336
336
|
outDir: paths.build,
|
|
337
337
|
emptyOutDir: false,
|
|
338
|
-
target: "
|
|
338
|
+
target: "node22",
|
|
339
339
|
sourcemap: true,
|
|
340
340
|
minify: false,
|
|
341
341
|
rollupOptions: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/build.ts","../../src/cli/views-bindings.ts"],"sourcesContent":["/**\n * `mcp-use build` — Vite SSR/node build of the user's server entry into the\n * `.mcp-use/build/` workspace directory (CLI_SPEC.md § Commands → build).\n *\n * When views exist (under `resources/<name>/view.tsx`), also runs a client-environment\n * build per view (hashed assets on disk), validates bindings, and emits a\n * wrapper entry that primes views before re-exporting the server (VIEWS_SPEC.md §\n * Build system).\n *\n * `vite` is an optional peer dependency of `mcp-use` (never a regular\n * dependency): this module is only ever reached through the bin's dynamic\n * `import(\"./cli/index.js\")`, so a missing install surfaces as a rejected\n * promise there (classified by `bin/main.ts`'s `isViteMissing`), not at\n * package load time.\n */\n\nimport { randomBytes } from \"node:crypto\";\nimport { existsSync } from \"node:fs\";\nimport { cp, mkdir, rm, writeFile } from \"node:fs/promises\";\nimport { join, relative } from \"node:path\";\nimport tailwindcss from \"@tailwindcss/vite\";\nimport react from \"@vitejs/plugin-react\";\nimport { build } from \"vite\";\n\nimport { discoverEntry } from \"./entry.js\";\nimport { mcpUseViewsPlugin } from \"./views-plugin.js\";\nimport { ensureToolsDeclaration } from \"./tools-declaration.js\";\nimport {\n resolveBuildBasePath,\n validateViewBindingsAtBuild,\n} from \"./views-bindings.js\";\nimport {\n createBindingValidationServer,\n discoverViews,\n virtualViewId,\n type DiscoveredView,\n} from \"./views.js\";\nimport { resolveTailwindCss, resolveUserViteConfig } from \"./vite-config.js\";\nimport { resolveWorkspacePaths, type BuildManifest } from \"./workspace.js\";\nimport { normalizeAssetsBaseUrl } from \"../views/origin.js\";\nimport { viewAssetsBasePath } from \"../views/document.js\";\nimport type { ViewsManifest } from \"../views/types.js\";\n\n/** Fixed filename of the emitted server entry inside `.mcp-use/build/`. */\nconst BUILD_ENTRY_NAME = \"index.js\";\n\nconst WRAPPER_BASENAME = \"entry-wrapper.ts\";\n\n/** Inline imported assets as data URLs up to this byte size (effectively all). */\nconst ASSETS_INLINE_LIMIT = 100 * 1024 * 1024;\n\nasync function copyPublicAssets(cwd: string, outputDir: string): Promise<void> {\n const publicSrc = join(cwd, \"public\");\n if (existsSync(publicSrc)) {\n await cp(publicSrc, outputDir, { recursive: true });\n }\n}\n\n/**\n * Options for {@link runBuild}.\n *\n * @internal\n */\nexport interface BuildOptions {\n /** Absolute path to the project root (the directory containing the entry). */\n cwd: string;\n /**\n * Explicit entry path (the `--entry` flag), absolute or relative to `cwd`.\n *\n * @defaultValue Conventional discovery: `src/index.ts`, `src/server.ts`,\n * `index.ts`, `server.ts` — first hit wins.\n */\n entry?: string;\n /**\n * When true (`mcp-use build --with-inspector`), record `inspector: true`\n * in the build manifest.\n */\n withInspector?: boolean;\n}\n\n/**\n * Emit a short-lived wrapper module under `.mcp-use/cache/` that primes views\n * before re-exporting the user's entry (VIEWS_SPEC.md § Registration mechanism).\n */\nasync function writeWrapperEntry(\n cacheDir: string,\n userEntry: string,\n viewsManifest: ViewsManifest\n): Promise<string> {\n const wrapperPath = join(cacheDir, WRAPPER_BASENAME);\n await mkdir(cacheDir, { recursive: true });\n const manifestJson = JSON.stringify(viewsManifest);\n await writeFile(\n wrapperPath,\n [\n `import server from ${JSON.stringify(userEntry)};`,\n `import { registerViews } from \"mcp-use\";`,\n `server[registerViews](${manifestJson});`,\n `export default server;`,\n \"\",\n ].join(\"\\n\")\n );\n return wrapperPath;\n}\n\nfunction readBuildAssetsBase(): string | undefined {\n const raw = process.env[\"MCP_ASSETS_URL\"];\n if (raw === undefined || raw.trim() === \"\") {\n return undefined;\n }\n try {\n return normalizeAssetsBaseUrl(new URL(raw).href.replace(/\\/$/, \"\"));\n } catch {\n return undefined;\n }\n}\n\n/** Rewrite a view-relative manifest path to a full CDN URL at build time. */\nfunction toCdnAssetUrl(\n relativePath: string,\n viewName: string,\n assetsBase: string,\n basePath: string\n): string {\n const clean = relativePath.replace(/^\\/+/, \"\");\n return `${assetsBase}${viewAssetsBasePath(basePath, viewName)}${clean}`;\n}\n\nfunction applyBuildAssetsPrefix(\n entry: ViewsManifest[string],\n viewName: string,\n assetsBase: string,\n basePath: string\n): ViewsManifest[string] {\n if (entry.kind !== \"external\") {\n return entry;\n }\n return {\n ...entry,\n entry: toCdnAssetUrl(entry.entry, viewName, assetsBase, basePath),\n css: entry.css.map((path) =>\n toCdnAssetUrl(path, viewName, assetsBase, basePath)\n ),\n ...(entry.scripts !== undefined && {\n scripts: entry.scripts.map((path) =>\n toCdnAssetUrl(path, viewName, assetsBase, basePath)\n ),\n }),\n };\n}\n\n/**\n * Build one view into hashed assets on disk, then record view-relative paths\n * in the manifest (served over HTTP at runtime).\n */\nasync function buildExternalView(\n view: DiscoveredView,\n options: {\n cwd: string;\n cacheDir: string;\n viewsOutDir: string;\n userViteConfig: string | false;\n }\n): Promise<ViewsManifest[string]> {\n const viewOutDir = join(options.viewsOutDir, view.name);\n const clientResult = await build({\n root: options.cwd,\n configFile: options.userViteConfig,\n envFile: false,\n logLevel: \"warn\",\n cacheDir: options.cacheDir,\n resolve: { alias: { tailwindcss: resolveTailwindCss() } },\n plugins: [\n tailwindcss(),\n react(),\n mcpUseViewsPlugin({ getViews: () => [view] }),\n ],\n build: {\n outDir: viewOutDir,\n emptyOutDir: true,\n target: \"es2022\",\n sourcemap: false,\n minify: true,\n cssCodeSplit: false,\n assetsInlineLimit: ASSETS_INLINE_LIMIT,\n rollupOptions: {\n input: { [view.name]: virtualViewId(view.name) },\n output: {\n format: \"es\",\n codeSplitting: false,\n entryFileNames: \"assets/[name]-[hash].js\",\n assetFileNames: \"assets/[name]-[hash][extname]\",\n },\n },\n },\n base: \"./\",\n });\n\n const clientOutput = Array.isArray(clientResult)\n ? clientResult[0]\n : clientResult;\n if (clientOutput === undefined || !(\"output\" in clientOutput)) {\n throw new Error(`Client build for view \"${view.name}\" produced no output.`);\n }\n\n const rawOutput = clientOutput.output;\n const items = Array.isArray(rawOutput) ? rawOutput : Object.values(rawOutput);\n\n let jsFileName: string | undefined;\n let cssFileName: string | undefined;\n\n for (const item of items) {\n if (typeof item !== \"object\" || item === null || !(\"fileName\" in item)) {\n continue;\n }\n const fileName = (item as { fileName: unknown }).fileName;\n if (typeof fileName !== \"string\") {\n continue;\n }\n const typed = item as {\n type?: string;\n isEntry?: boolean;\n fileName: string;\n };\n if (typed.type === \"chunk\" && typed.isEntry === true) {\n jsFileName = typed.fileName;\n } else if (typed.type === \"asset\" && typed.fileName.endsWith(\".css\")) {\n cssFileName = typed.fileName;\n }\n }\n\n if (jsFileName === undefined) {\n throw new Error(\n `Client build produced no entry chunk for view \"${view.name}\".`\n );\n }\n\n return {\n kind: \"external\",\n entry: jsFileName.replace(/^\\/+/, \"\"),\n css: cssFileName !== undefined ? [cssFileName.replace(/^\\/+/, \"\")] : [],\n };\n}\n\n/**\n * Build the project's server for production: a Vite build of the SSR/node\n * environment only (the client environment for views arrives with\n * VIEWS_SPEC.md), emitted as ESM to `.mcp-use/build/` with a `manifest.json`\n * alongside it.\n *\n * Dependencies stay external (`ssr: { external: true }`): only the\n * user's own source is bundled; every bare import resolves from\n * `node_modules` at runtime. The built entry preserves the default export\n * (the `MCPServer` instance) so `mcp-use start` can import and serve it.\n *\n * There is deliberately no typecheck step — the build is transpile-only;\n * users run `tsc --noEmit` via their own script.\n *\n * @param options - Project root and optional entry override.\n * @throws If no entry is found (see {@link discoverEntry}), or if `vite` is\n * not installed (`mcp-use build` requires it as a devDependency) — the\n * `import(\"vite\")` rejection propagates to the bin's dispatch boundary,\n * which classifies it and prints the install hint.\n *\n * @internal Reached only via the bin's `import(\"./cli/index.js\")`\n * dispatch (`bin/main.ts`) — not re-exported from the package's \".\" entry.\n */\nexport async function runBuild(options: BuildOptions): Promise<void> {\n const startedAt = performance.now();\n const entry = discoverEntry(options.cwd, options.entry);\n if (await ensureToolsDeclaration(options.cwd, entry)) {\n console.log(\"[mcp-use] created tools.d.ts\");\n }\n const paths = resolveWorkspacePaths(options.cwd);\n const views = discoverViews(options.cwd);\n const userViteConfig = resolveUserViteConfig(options.cwd);\n const inspector = options.withInspector === true;\n\n if (views.length === 0) {\n await build({\n root: options.cwd,\n configFile: false,\n envFile: false,\n logLevel: \"warn\",\n cacheDir: paths.cache,\n build: {\n ssr: entry,\n outDir: paths.build,\n emptyOutDir: true,\n target: \"node24\",\n sourcemap: true,\n minify: false,\n rollupOptions: {\n output: {\n format: \"es\",\n entryFileNames: BUILD_ENTRY_NAME,\n },\n },\n },\n ssr: {\n external: true,\n target: \"node\",\n },\n });\n\n // Branding may reference project-public icon files even when the server\n // has no views. Keep the runtime public-asset location identical in both\n // shapes so `mcp-use start` and serverless built entries behave alike.\n await copyPublicAssets(options.cwd, join(paths.build, \"views/public\"));\n\n const manifest: BuildManifest = {\n buildId: randomBytes(8).toString(\"hex\"),\n entryPoint: BUILD_ENTRY_NAME,\n createdAt: new Date().toISOString(),\n inspector,\n };\n await mkdir(paths.build, { recursive: true });\n await writeFile(\n paths.buildManifest,\n `${JSON.stringify(manifest, null, 2)}\\n`\n );\n\n const duration = Math.round(performance.now() - startedAt);\n console.log(\n `[mcp-use] built ${relative(options.cwd, entry)} → ` +\n `${relative(options.cwd, paths.build)}/${BUILD_ENTRY_NAME} (${duration}ms)`\n );\n return;\n }\n\n await rm(paths.build, { recursive: true, force: true });\n\n const viewsOutDir = join(paths.build, \"views\");\n await mkdir(viewsOutDir, { recursive: true });\n\n const bindingServer = await createBindingValidationServer(\n options.cwd,\n paths.cache,\n false\n );\n let buildBasePath: string;\n try {\n buildBasePath = await resolveBuildBasePath(\n bindingServer.environments.ssr,\n entry\n );\n } catch (error) {\n await bindingServer.close();\n throw error;\n }\n\n const viewsManifest: ViewsManifest = {};\n const buildAssetsBase = readBuildAssetsBase();\n for (const view of views) {\n let manifestEntry = await buildExternalView(view, {\n cwd: options.cwd,\n cacheDir: paths.cache,\n viewsOutDir,\n userViteConfig,\n });\n if (buildAssetsBase !== undefined) {\n manifestEntry = applyBuildAssetsPrefix(\n manifestEntry,\n view.name,\n buildAssetsBase,\n buildBasePath\n );\n }\n viewsManifest[view.name] = manifestEntry;\n }\n\n if (buildAssetsBase !== undefined) {\n console.log(\n `[mcp-use] MCP_ASSETS_URL set — manifest uses CDN URLs; upload ` +\n `${relative(options.cwd, viewsOutDir)}/ to your asset host.`\n );\n if (buildBasePath !== \"/mcp\") {\n console.log(\n `[mcp-use] CDN manifest uses basePath ${buildBasePath} from server entry`\n );\n }\n }\n\n await copyPublicAssets(options.cwd, join(viewsOutDir, \"public\"));\n\n try {\n await validateViewBindingsAtBuild(\n bindingServer.environments.ssr,\n entry,\n viewsManifest\n );\n } finally {\n await bindingServer.close();\n }\n\n const wrapperEntry = await writeWrapperEntry(\n paths.cache,\n entry,\n viewsManifest\n );\n\n await build({\n root: options.cwd,\n configFile: false,\n envFile: false,\n logLevel: \"warn\",\n cacheDir: paths.cache,\n build: {\n ssr: wrapperEntry,\n outDir: paths.build,\n emptyOutDir: false,\n target: \"node24\",\n sourcemap: true,\n minify: false,\n rollupOptions: {\n output: {\n format: \"es\",\n entryFileNames: BUILD_ENTRY_NAME,\n },\n },\n },\n ssr: {\n external: true,\n target: \"node\",\n },\n });\n\n const manifest: BuildManifest = {\n buildId: randomBytes(8).toString(\"hex\"),\n entryPoint: BUILD_ENTRY_NAME,\n createdAt: new Date().toISOString(),\n inspector,\n };\n await mkdir(paths.build, { recursive: true });\n await writeFile(\n paths.buildManifest,\n `${JSON.stringify(manifest, null, 2)}\\n`\n );\n\n const duration = Math.round(performance.now() - startedAt);\n const viewNames = views.map((v) => v.name).join(\", \");\n console.log(\n `[mcp-use] built ${relative(options.cwd, entry)} + views (${viewNames}) → ` +\n `${relative(options.cwd, paths.build)}/${BUILD_ENTRY_NAME} (${duration}ms)`\n );\n}\n","/**\n * Build-time view binding validation via mount-time checks.\n */\n\nimport { createServerModuleRunner, type DevEnvironment } from \"vite\";\n\nimport type { ViewsManifest } from \"../views/types.js\";\n\nconst DEFAULT_BASE_PATH = \"/mcp\";\n\n/** Synthetic origin for entry evaluation when OAuth needs MCP_URL at import. */\nconst BUILD_ENTRY_MCP_URL = \"http://localhost:3000\";\n\n/**\n * Duck-typed server shape needed for binding validation.\n *\n * @internal\n */\ninterface ServerLike {\n getHandler(): unknown;\n __primeViews(views: ViewsManifest, options?: { dev?: boolean }): void;\n basePath?: string;\n}\n\n/**\n * Import the server entry and read `basePath` from the default export.\n *\n * Does not prime views or call `getHandler()`. Sets a synthetic `MCP_URL` only\n * when unset so OAuth entries can construct during build introspection.\n *\n * @internal\n */\nexport async function resolveBuildBasePath(\n environment: DevEnvironment,\n entry: string\n): Promise<string> {\n const runner = createServerModuleRunner(environment, {\n hmr: false,\n sourcemapInterceptor: \"node\",\n });\n\n const previousMcpUrl = process.env[\"MCP_URL\"];\n try {\n if (previousMcpUrl === undefined) {\n process.env[\"MCP_URL\"] = BUILD_ENTRY_MCP_URL;\n }\n\n const serverModule = (await runner.import(entry)) as {\n default?: ServerLike;\n };\n const server = serverModule.default;\n if (server === null || typeof server !== \"object\") {\n throw new Error(\n \"The server entry must default-export the MCPServer instance.\"\n );\n }\n\n return server.basePath ?? DEFAULT_BASE_PATH;\n } finally {\n if (previousMcpUrl === undefined) {\n delete process.env[\"MCP_URL\"];\n } else {\n process.env[\"MCP_URL\"] = previousMcpUrl;\n }\n await runner.close();\n }\n}\n\n/**\n * Prime the server with the manifest and run mount-time binding validation\n * by calling `getHandler()`.\n *\n * Surfaces the same errors as runtime mount: missing primed view, missing\n * `outputSchema`, double binding. Unbound views emit a warning to stderr.\n *\n * @param environment - Vite SSR environment for module evaluation.\n * @param entry - Absolute path to the user's server entry.\n * @param viewsManifest - Built or dev-shaped manifest to prime.\n * @throws On binding hard errors (naming the view/tool).\n *\n * @internal\n */\nexport async function validateViewBindingsAtBuild(\n environment: DevEnvironment,\n entry: string,\n viewsManifest: ViewsManifest\n): Promise<void> {\n const runner = createServerModuleRunner(environment, {\n hmr: false,\n sourcemapInterceptor: \"node\",\n });\n\n try {\n const serverModule = (await runner.import(entry)) as {\n default?: ServerLike;\n };\n const server = serverModule.default;\n if (server === null || typeof server !== \"object\") {\n throw new Error(\n \"The server entry must default-export the MCPServer instance.\"\n );\n }\n\n if (typeof server.__primeViews !== \"function\") {\n throw new Error(\n \"The entry's default export does not support __primeViews.\"\n );\n }\n server.__primeViews(viewsManifest);\n server.getHandler();\n } finally {\n await runner.close();\n }\n}\n"],"mappings":"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","names":["manifest","duration"]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/build.ts","../../src/cli/views-bindings.ts"],"sourcesContent":["/**\n * `mcp-use build` — Vite SSR/node build of the user's server entry into the\n * `.mcp-use/build/` workspace directory (CLI_SPEC.md § Commands → build).\n *\n * When views exist (under `views/<name>/view.tsx`), also runs a client-environment\n * build per view (hashed assets on disk), validates bindings, and emits a\n * wrapper entry that primes views before re-exporting the server (VIEWS_SPEC.md §\n * Build system).\n *\n * `vite` is an optional peer dependency of `mcp-use` (never a regular\n * dependency): this module is only ever reached through the bin's dynamic\n * `import(\"./cli/index.js\")`, so a missing install surfaces as a rejected\n * promise there (classified by `bin/main.ts`'s `isViteMissing`), not at\n * package load time.\n */\n\nimport { randomBytes } from \"node:crypto\";\nimport { existsSync } from \"node:fs\";\nimport { cp, mkdir, rm, writeFile } from \"node:fs/promises\";\nimport { join, relative } from \"node:path\";\nimport tailwindcss from \"@tailwindcss/vite\";\nimport react from \"@vitejs/plugin-react\";\nimport { build } from \"vite\";\n\nimport { discoverEntry } from \"./entry.js\";\nimport { mcpUseViewsPlugin } from \"./views-plugin.js\";\nimport { ensureMcpEnvDeclaration } from \"./mcp-env-declaration.js\";\nimport {\n resolveBuildBasePath,\n validateViewBindingsAtBuild,\n} from \"./views-bindings.js\";\nimport {\n createBindingValidationServer,\n discoverViews,\n virtualViewId,\n type DiscoveredView,\n} from \"./views.js\";\nimport { resolveTailwindCss, resolveUserViteConfig } from \"./vite-config.js\";\nimport { resolveWorkspacePaths, type BuildManifest } from \"./workspace.js\";\nimport { normalizeAssetsBaseUrl } from \"../views/origin.js\";\nimport { viewAssetsBasePath } from \"../views/document.js\";\nimport type { ViewsManifest } from \"../views/types.js\";\n\n/** Fixed filename of the emitted server entry inside `.mcp-use/build/`. */\nconst BUILD_ENTRY_NAME = \"index.js\";\n\nconst WRAPPER_BASENAME = \"entry-wrapper.ts\";\n\n/** Inline imported assets as data URLs up to this byte size (effectively all). */\nconst ASSETS_INLINE_LIMIT = 100 * 1024 * 1024;\n\nasync function copyPublicAssets(cwd: string, outputDir: string): Promise<void> {\n const publicSrc = join(cwd, \"public\");\n if (existsSync(publicSrc)) {\n await cp(publicSrc, outputDir, { recursive: true });\n }\n}\n\n/**\n * Options for {@link runBuild}.\n *\n * @internal\n */\nexport interface BuildOptions {\n /** Absolute path to the project root (the directory containing the entry). */\n cwd: string;\n /**\n * Explicit entry path (the `--entry` flag), absolute or relative to `cwd`.\n *\n * @defaultValue Conventional discovery: `src/index.ts`, `src/server.ts`,\n * `index.ts`, `server.ts` — first hit wins.\n */\n entry?: string;\n /**\n * When true (`mcp-use build --with-inspector`), record `inspector: true`\n * in the build manifest.\n */\n withInspector?: boolean;\n}\n\n/**\n * Emit a short-lived wrapper module under `.mcp-use/cache/` that primes views\n * before re-exporting the user's entry (VIEWS_SPEC.md § Registration mechanism).\n */\nasync function writeWrapperEntry(\n cacheDir: string,\n userEntry: string,\n viewsManifest: ViewsManifest\n): Promise<string> {\n const wrapperPath = join(cacheDir, WRAPPER_BASENAME);\n await mkdir(cacheDir, { recursive: true });\n const manifestJson = JSON.stringify(viewsManifest);\n await writeFile(\n wrapperPath,\n [\n `import server from ${JSON.stringify(userEntry)};`,\n `import { registerViews } from \"mcp-use\";`,\n `server[registerViews](${manifestJson});`,\n `export default server;`,\n \"\",\n ].join(\"\\n\")\n );\n return wrapperPath;\n}\n\nfunction readBuildAssetsBase(): string | undefined {\n const raw = process.env[\"MCP_ASSETS_URL\"];\n if (raw === undefined || raw.trim() === \"\") {\n return undefined;\n }\n try {\n return normalizeAssetsBaseUrl(new URL(raw).href.replace(/\\/$/, \"\"));\n } catch {\n return undefined;\n }\n}\n\n/** Rewrite a view-relative manifest path to a full CDN URL at build time. */\nfunction toCdnAssetUrl(\n relativePath: string,\n viewName: string,\n assetsBase: string,\n basePath: string\n): string {\n const clean = relativePath.replace(/^\\/+/, \"\");\n return `${assetsBase}${viewAssetsBasePath(basePath, viewName)}${clean}`;\n}\n\nfunction applyBuildAssetsPrefix(\n entry: ViewsManifest[string],\n viewName: string,\n assetsBase: string,\n basePath: string\n): ViewsManifest[string] {\n if (entry.kind !== \"external\") {\n return entry;\n }\n return {\n ...entry,\n entry: toCdnAssetUrl(entry.entry, viewName, assetsBase, basePath),\n css: entry.css.map((path) =>\n toCdnAssetUrl(path, viewName, assetsBase, basePath)\n ),\n ...(entry.scripts !== undefined && {\n scripts: entry.scripts.map((path) =>\n toCdnAssetUrl(path, viewName, assetsBase, basePath)\n ),\n }),\n };\n}\n\n/**\n * Build one view into hashed assets on disk, then record view-relative paths\n * in the manifest (served over HTTP at runtime).\n */\nasync function buildExternalView(\n view: DiscoveredView,\n options: {\n cwd: string;\n cacheDir: string;\n viewsOutDir: string;\n userViteConfig: string | false;\n }\n): Promise<ViewsManifest[string]> {\n const viewOutDir = join(options.viewsOutDir, view.name);\n const clientResult = await build({\n root: options.cwd,\n configFile: options.userViteConfig,\n envFile: false,\n logLevel: \"warn\",\n cacheDir: options.cacheDir,\n resolve: { alias: { tailwindcss: resolveTailwindCss() } },\n plugins: [\n tailwindcss(),\n react(),\n mcpUseViewsPlugin({ getViews: () => [view] }),\n ],\n build: {\n outDir: viewOutDir,\n emptyOutDir: true,\n target: \"es2022\",\n sourcemap: false,\n minify: true,\n cssCodeSplit: false,\n assetsInlineLimit: ASSETS_INLINE_LIMIT,\n rollupOptions: {\n input: { [view.name]: virtualViewId(view.name) },\n output: {\n format: \"es\",\n codeSplitting: false,\n entryFileNames: \"assets/[name]-[hash].js\",\n assetFileNames: \"assets/[name]-[hash][extname]\",\n },\n },\n },\n base: \"./\",\n });\n\n const clientOutput = Array.isArray(clientResult)\n ? clientResult[0]\n : clientResult;\n if (clientOutput === undefined || !(\"output\" in clientOutput)) {\n throw new Error(`Client build for view \"${view.name}\" produced no output.`);\n }\n\n const rawOutput = clientOutput.output;\n const items = Array.isArray(rawOutput) ? rawOutput : Object.values(rawOutput);\n\n let jsFileName: string | undefined;\n let cssFileName: string | undefined;\n\n for (const item of items) {\n if (typeof item !== \"object\" || item === null || !(\"fileName\" in item)) {\n continue;\n }\n const fileName = (item as { fileName: unknown }).fileName;\n if (typeof fileName !== \"string\") {\n continue;\n }\n const typed = item as {\n type?: string;\n isEntry?: boolean;\n fileName: string;\n };\n if (typed.type === \"chunk\" && typed.isEntry === true) {\n jsFileName = typed.fileName;\n } else if (typed.type === \"asset\" && typed.fileName.endsWith(\".css\")) {\n cssFileName = typed.fileName;\n }\n }\n\n if (jsFileName === undefined) {\n throw new Error(\n `Client build produced no entry chunk for view \"${view.name}\".`\n );\n }\n\n return {\n kind: \"external\",\n entry: jsFileName.replace(/^\\/+/, \"\"),\n css: cssFileName !== undefined ? [cssFileName.replace(/^\\/+/, \"\")] : [],\n };\n}\n\n/**\n * Build the project's server for production: a Vite build of the SSR/node\n * environment only (the client environment for views arrives with\n * VIEWS_SPEC.md), emitted as ESM to `.mcp-use/build/` with a `manifest.json`\n * alongside it.\n *\n * Dependencies stay external (`ssr: { external: true }`): only the\n * user's own source is bundled; every bare import resolves from\n * `node_modules` at runtime. The built entry preserves the default export\n * (the `MCPServer` instance) so `mcp-use start` can import and serve it.\n *\n * There is deliberately no typecheck step — the build is transpile-only;\n * users run `tsc --noEmit` via their own script.\n *\n * @param options - Project root and optional entry override.\n * @throws If no entry is found (see {@link discoverEntry}), or if `vite` is\n * not installed (`mcp-use build` requires it as a devDependency) — the\n * `import(\"vite\")` rejection propagates to the bin's dispatch boundary,\n * which classifies it and prints the install hint.\n *\n * @internal Reached only via the bin's `import(\"./cli/index.js\")`\n * dispatch (`bin/main.ts`) — not re-exported from the package's \".\" entry.\n */\nexport async function runBuild(options: BuildOptions): Promise<void> {\n const startedAt = performance.now();\n const entry = discoverEntry(options.cwd, options.entry);\n if (await ensureMcpEnvDeclaration(options.cwd, entry)) {\n console.log(\"[mcp-use] created mcp-env.d.ts\");\n }\n const paths = resolveWorkspacePaths(options.cwd);\n const views = discoverViews(options.cwd);\n const userViteConfig = resolveUserViteConfig(options.cwd);\n const inspector = options.withInspector === true;\n\n if (views.length === 0) {\n await build({\n root: options.cwd,\n configFile: false,\n envFile: false,\n logLevel: \"warn\",\n cacheDir: paths.cache,\n build: {\n ssr: entry,\n outDir: paths.build,\n emptyOutDir: true,\n target: \"node22\",\n sourcemap: true,\n minify: false,\n rollupOptions: {\n output: {\n format: \"es\",\n entryFileNames: BUILD_ENTRY_NAME,\n },\n },\n },\n ssr: {\n external: true,\n target: \"node\",\n },\n });\n\n // Branding may reference project-public icon files even when the server\n // has no views. Keep the runtime public-asset location identical in both\n // shapes so `mcp-use start` and serverless built entries behave alike.\n await copyPublicAssets(options.cwd, join(paths.build, \"views/public\"));\n\n const manifest: BuildManifest = {\n buildId: randomBytes(8).toString(\"hex\"),\n entryPoint: BUILD_ENTRY_NAME,\n createdAt: new Date().toISOString(),\n inspector,\n };\n await mkdir(paths.build, { recursive: true });\n await writeFile(\n paths.buildManifest,\n `${JSON.stringify(manifest, null, 2)}\\n`\n );\n\n const duration = Math.round(performance.now() - startedAt);\n console.log(\n `[mcp-use] built ${relative(options.cwd, entry)} → ` +\n `${relative(options.cwd, paths.build)}/${BUILD_ENTRY_NAME} (${duration}ms)`\n );\n return;\n }\n\n await rm(paths.build, { recursive: true, force: true });\n\n const viewsOutDir = join(paths.build, \"views\");\n await mkdir(viewsOutDir, { recursive: true });\n\n const bindingServer = await createBindingValidationServer(\n options.cwd,\n paths.cache,\n false\n );\n let buildBasePath: string;\n try {\n buildBasePath = await resolveBuildBasePath(\n bindingServer.environments.ssr,\n entry\n );\n } catch (error) {\n await bindingServer.close();\n throw error;\n }\n\n const viewsManifest: ViewsManifest = {};\n const buildAssetsBase = readBuildAssetsBase();\n for (const view of views) {\n let manifestEntry = await buildExternalView(view, {\n cwd: options.cwd,\n cacheDir: paths.cache,\n viewsOutDir,\n userViteConfig,\n });\n if (buildAssetsBase !== undefined) {\n manifestEntry = applyBuildAssetsPrefix(\n manifestEntry,\n view.name,\n buildAssetsBase,\n buildBasePath\n );\n }\n viewsManifest[view.name] = manifestEntry;\n }\n\n if (buildAssetsBase !== undefined) {\n console.log(\n `[mcp-use] MCP_ASSETS_URL set — manifest uses CDN URLs; upload ` +\n `${relative(options.cwd, viewsOutDir)}/ to your asset host.`\n );\n if (buildBasePath !== \"/mcp\") {\n console.log(\n `[mcp-use] CDN manifest uses basePath ${buildBasePath} from server entry`\n );\n }\n }\n\n await copyPublicAssets(options.cwd, join(viewsOutDir, \"public\"));\n\n try {\n await validateViewBindingsAtBuild(\n bindingServer.environments.ssr,\n entry,\n viewsManifest\n );\n } finally {\n await bindingServer.close();\n }\n\n const wrapperEntry = await writeWrapperEntry(\n paths.cache,\n entry,\n viewsManifest\n );\n\n await build({\n root: options.cwd,\n configFile: false,\n envFile: false,\n logLevel: \"warn\",\n cacheDir: paths.cache,\n build: {\n ssr: wrapperEntry,\n outDir: paths.build,\n emptyOutDir: false,\n target: \"node22\",\n sourcemap: true,\n minify: false,\n rollupOptions: {\n output: {\n format: \"es\",\n entryFileNames: BUILD_ENTRY_NAME,\n },\n },\n },\n ssr: {\n external: true,\n target: \"node\",\n },\n });\n\n const manifest: BuildManifest = {\n buildId: randomBytes(8).toString(\"hex\"),\n entryPoint: BUILD_ENTRY_NAME,\n createdAt: new Date().toISOString(),\n inspector,\n };\n await mkdir(paths.build, { recursive: true });\n await writeFile(\n paths.buildManifest,\n `${JSON.stringify(manifest, null, 2)}\\n`\n );\n\n const duration = Math.round(performance.now() - startedAt);\n const viewNames = views.map((v) => v.name).join(\", \");\n console.log(\n `[mcp-use] built ${relative(options.cwd, entry)} + views (${viewNames}) → ` +\n `${relative(options.cwd, paths.build)}/${BUILD_ENTRY_NAME} (${duration}ms)`\n );\n}\n","/**\n * Build-time view binding validation via mount-time checks.\n */\n\nimport { createServerModuleRunner, type DevEnvironment } from \"vite\";\n\nimport type { ViewsManifest } from \"../views/types.js\";\n\nconst DEFAULT_BASE_PATH = \"/mcp\";\n\n/** Synthetic origin for entry evaluation when OAuth needs MCP_URL at import. */\nconst BUILD_ENTRY_MCP_URL = \"http://localhost:3000\";\n\n/**\n * Duck-typed server shape needed for binding validation.\n *\n * @internal\n */\ninterface ServerLike {\n getHandler(): unknown;\n __primeViews(views: ViewsManifest, options?: { dev?: boolean }): void;\n basePath?: string;\n}\n\n/**\n * Import the server entry and read `basePath` from the default export.\n *\n * Does not prime views or call `getHandler()`. Sets a synthetic `MCP_URL` only\n * when unset so OAuth entries can construct during build introspection.\n *\n * @internal\n */\nexport async function resolveBuildBasePath(\n environment: DevEnvironment,\n entry: string\n): Promise<string> {\n const runner = createServerModuleRunner(environment, {\n hmr: false,\n sourcemapInterceptor: \"node\",\n });\n\n const previousMcpUrl = process.env[\"MCP_URL\"];\n try {\n if (previousMcpUrl === undefined) {\n process.env[\"MCP_URL\"] = BUILD_ENTRY_MCP_URL;\n }\n\n const serverModule = (await runner.import(entry)) as {\n default?: ServerLike;\n };\n const server = serverModule.default;\n if (server === null || typeof server !== \"object\") {\n throw new Error(\n \"The server entry must default-export the MCPServer instance.\"\n );\n }\n\n return server.basePath ?? DEFAULT_BASE_PATH;\n } finally {\n if (previousMcpUrl === undefined) {\n delete process.env[\"MCP_URL\"];\n } else {\n process.env[\"MCP_URL\"] = previousMcpUrl;\n }\n await runner.close();\n }\n}\n\n/**\n * Prime the server with the manifest and run mount-time binding validation\n * by calling `getHandler()`.\n *\n * Surfaces the same errors as runtime mount: missing primed view, missing\n * `outputSchema`, double binding. Unbound views emit a warning to stderr.\n *\n * @param environment - Vite SSR environment for module evaluation.\n * @param entry - Absolute path to the user's server entry.\n * @param viewsManifest - Built or dev-shaped manifest to prime.\n * @throws On binding hard errors (naming the view/tool).\n *\n * @internal\n */\nexport async function validateViewBindingsAtBuild(\n environment: DevEnvironment,\n entry: string,\n viewsManifest: ViewsManifest\n): Promise<void> {\n const runner = createServerModuleRunner(environment, {\n hmr: false,\n sourcemapInterceptor: \"node\",\n });\n\n try {\n const serverModule = (await runner.import(entry)) as {\n default?: ServerLike;\n };\n const server = serverModule.default;\n if (server === null || typeof server !== \"object\") {\n throw new Error(\n \"The server entry must default-export the MCPServer instance.\"\n );\n }\n\n if (typeof server.__primeViews !== \"function\") {\n throw new Error(\n \"The entry's default export does not support __primeViews.\"\n );\n }\n server.__primeViews(viewsManifest);\n server.getHandler();\n } finally {\n await runner.close();\n }\n}\n"],"mappings":"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","names":["manifest","duration"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/commands/client.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/commands/client.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AA+DrD,+CAA+C;AAC/C,wBAAsB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAqBxE;AAuUD;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,aAAa,SAAU,GACtB,OAAO,CAAC,aAAa,CAAC,CAWxB;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,OAAO,CAAC,aAAa,CAAC,CAOxB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,SAAS,MAAM,EAAE,GACtB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAyBzB"}
|
package/dist/commands/client.js
CHANGED
package/dist/commands/dev.js
CHANGED
|
@@ -5,13 +5,13 @@ import {
|
|
|
5
5
|
buildDevViewsManifest,
|
|
6
6
|
discoverEntry,
|
|
7
7
|
discoverViews,
|
|
8
|
-
|
|
8
|
+
ensureMcpEnvDeclaration,
|
|
9
9
|
isViewPath,
|
|
10
10
|
mcpUseViewsPlugin,
|
|
11
11
|
resolveTailwindCss,
|
|
12
12
|
resolveUserViteConfig,
|
|
13
13
|
resolveWorkspacePaths
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-XKJP5S7C.js";
|
|
15
15
|
|
|
16
16
|
// src/cli/dev.ts
|
|
17
17
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -100,10 +100,19 @@ var DEFAULT_TUNNEL_API = "https://local.mcp-use.run";
|
|
|
100
100
|
function tunnelApiBase() {
|
|
101
101
|
return process.env["MCP_USE_TUNNEL_API"] ?? DEFAULT_TUNNEL_API;
|
|
102
102
|
}
|
|
103
|
+
var RESPAWN_BACKOFF_INITIAL_MS = 1e3;
|
|
104
|
+
var RESPAWN_BACKOFF_MAX_MS = 3e4;
|
|
103
105
|
function createTunnelManager(stateFilePath) {
|
|
104
106
|
let proc;
|
|
105
107
|
let currentUrl = null;
|
|
106
108
|
let currentSubdomain;
|
|
109
|
+
let activePort;
|
|
110
|
+
let intentionalStop = false;
|
|
111
|
+
let respawnInFlight;
|
|
112
|
+
let respawnBackoffMs = RESPAWN_BACKOFF_INITIAL_MS;
|
|
113
|
+
const sleep = (ms) => new Promise((resolve) => {
|
|
114
|
+
setTimeout(resolve, ms);
|
|
115
|
+
});
|
|
107
116
|
const markShutdown = () => {
|
|
108
117
|
if (proc !== void 0 && "markShutdown" in proc && typeof proc.markShutdown === "function") {
|
|
109
118
|
proc.markShutdown();
|
|
@@ -141,6 +150,8 @@ function createTunnelManager(stateFilePath) {
|
|
|
141
150
|
);
|
|
142
151
|
}
|
|
143
152
|
};
|
|
153
|
+
let scheduleRespawn = () => {
|
|
154
|
+
};
|
|
144
155
|
const spawnTunnel = (port, subdomain) => new Promise((resolve, reject) => {
|
|
145
156
|
console.log(`[mcp-use] starting tunnel for port ${port}\u2026`);
|
|
146
157
|
const userAgent = process.env["npm_config_user_agent"] ?? "";
|
|
@@ -208,7 +219,11 @@ function createTunnelManager(stateFilePath) {
|
|
|
208
219
|
if (proc === child) {
|
|
209
220
|
proc = void 0;
|
|
210
221
|
currentUrl = null;
|
|
211
|
-
|
|
222
|
+
if (intentionalStop) {
|
|
223
|
+
currentSubdomain = void 0;
|
|
224
|
+
} else {
|
|
225
|
+
scheduleRespawn();
|
|
226
|
+
}
|
|
212
227
|
}
|
|
213
228
|
});
|
|
214
229
|
const setupTimeout = setTimeout(() => {
|
|
@@ -218,11 +233,62 @@ function createTunnelManager(stateFilePath) {
|
|
|
218
233
|
}
|
|
219
234
|
}, 3e4);
|
|
220
235
|
});
|
|
236
|
+
scheduleRespawn = () => {
|
|
237
|
+
if (intentionalStop || activePort === void 0 || currentUrl !== null) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
if (respawnInFlight !== void 0) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
respawnInFlight = (async () => {
|
|
244
|
+
while (!intentionalStop && activePort !== void 0 && currentUrl === null) {
|
|
245
|
+
console.log("[mcp-use] tunnel disconnected, restarting\u2026");
|
|
246
|
+
const subdomain = currentSubdomain ?? await loadSavedSubdomain();
|
|
247
|
+
try {
|
|
248
|
+
if (subdomain !== void 0) {
|
|
249
|
+
await releaseSubdomain(subdomain);
|
|
250
|
+
}
|
|
251
|
+
let tunnelInfo;
|
|
252
|
+
try {
|
|
253
|
+
tunnelInfo = await spawnTunnel(activePort, subdomain);
|
|
254
|
+
} catch (error) {
|
|
255
|
+
if (subdomain !== void 0) {
|
|
256
|
+
console.log(
|
|
257
|
+
`[mcp-use] subdomain "${subdomain}" unavailable, requesting a new one\u2026`
|
|
258
|
+
);
|
|
259
|
+
tunnelInfo = await spawnTunnel(activePort, void 0);
|
|
260
|
+
} else {
|
|
261
|
+
throw error;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
proc = tunnelInfo.process;
|
|
265
|
+
currentUrl = tunnelInfo.url;
|
|
266
|
+
currentSubdomain = tunnelInfo.subdomain;
|
|
267
|
+
await persistSubdomain(tunnelInfo.subdomain);
|
|
268
|
+
respawnBackoffMs = RESPAWN_BACKOFF_INITIAL_MS;
|
|
269
|
+
return;
|
|
270
|
+
} catch (error) {
|
|
271
|
+
console.warn(
|
|
272
|
+
`[mcp-use] tunnel restart failed: ${error instanceof Error ? error.message : String(error)}`
|
|
273
|
+
);
|
|
274
|
+
await sleep(respawnBackoffMs);
|
|
275
|
+
respawnBackoffMs = Math.min(
|
|
276
|
+
respawnBackoffMs * 2,
|
|
277
|
+
RESPAWN_BACKOFF_MAX_MS
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
})().finally(() => {
|
|
282
|
+
respawnInFlight = void 0;
|
|
283
|
+
});
|
|
284
|
+
};
|
|
221
285
|
return {
|
|
222
286
|
status() {
|
|
223
287
|
return { url: currentUrl };
|
|
224
288
|
},
|
|
225
289
|
async start(port) {
|
|
290
|
+
intentionalStop = false;
|
|
291
|
+
activePort = port;
|
|
226
292
|
if (currentUrl !== null) {
|
|
227
293
|
return {
|
|
228
294
|
url: currentUrl,
|
|
@@ -254,7 +320,11 @@ function createTunnelManager(stateFilePath) {
|
|
|
254
320
|
return { url: tunnelInfo.url, subdomain: tunnelInfo.subdomain };
|
|
255
321
|
},
|
|
256
322
|
async stop() {
|
|
323
|
+
intentionalStop = true;
|
|
257
324
|
markShutdown();
|
|
325
|
+
if (respawnInFlight !== void 0) {
|
|
326
|
+
await respawnInFlight;
|
|
327
|
+
}
|
|
258
328
|
if (currentSubdomain !== void 0) {
|
|
259
329
|
await releaseSubdomain(currentSubdomain);
|
|
260
330
|
}
|
|
@@ -262,8 +332,10 @@ function createTunnelManager(stateFilePath) {
|
|
|
262
332
|
proc.kill("SIGINT");
|
|
263
333
|
proc = void 0;
|
|
264
334
|
}
|
|
335
|
+
activePort = void 0;
|
|
265
336
|
currentUrl = null;
|
|
266
337
|
currentSubdomain = void 0;
|
|
338
|
+
respawnBackoffMs = RESPAWN_BACKOFF_INITIAL_MS;
|
|
267
339
|
}
|
|
268
340
|
};
|
|
269
341
|
}
|
|
@@ -359,8 +431,8 @@ async function runDev(options) {
|
|
|
359
431
|
process.env["PORT"] = String(port);
|
|
360
432
|
const localFallbackMcpUrl = process.env["MCP_URL"] === void 0 && (host === "127.0.0.1" || host === "localhost" || host === "::1") ? `http://localhost:${port}` : void 0;
|
|
361
433
|
const entry = discoverEntry(options.cwd, options.entry);
|
|
362
|
-
if (await
|
|
363
|
-
console.log("[mcp-use] created
|
|
434
|
+
if (await ensureMcpEnvDeclaration(options.cwd, entry)) {
|
|
435
|
+
console.log("[mcp-use] created mcp-env.d.ts");
|
|
364
436
|
}
|
|
365
437
|
let currentViews = discoverViews(options.cwd);
|
|
366
438
|
const viewsAtStartup = currentViews.length > 0;
|
|
@@ -530,15 +602,10 @@ async function runDev(options) {
|
|
|
530
602
|
const tunnelUrl = tunnelManager.status().url;
|
|
531
603
|
const tunnelHost = tunnelUrl !== null ? new URL(tunnelUrl).hostname : null;
|
|
532
604
|
const extra = tunnelHost !== null ? [tunnelHost] : [];
|
|
533
|
-
const
|
|
534
|
-
const hostResult = validateHostHeader(req.headers.host, [
|
|
605
|
+
const result = validateHostHeader(req.headers.host, [
|
|
535
606
|
...localhostAllowedHostnames(),
|
|
536
607
|
...extra
|
|
537
608
|
]);
|
|
538
|
-
const result = hostResult.ok && !readOnly ? validateOriginHeader(req.headers.origin, [
|
|
539
|
-
...localhostAllowedOrigins(),
|
|
540
|
-
...extra
|
|
541
|
-
]) : hostResult;
|
|
542
609
|
if (result.ok) {
|
|
543
610
|
return false;
|
|
544
611
|
}
|
|
@@ -578,7 +645,7 @@ async function runDev(options) {
|
|
|
578
645
|
const url = req.url ?? "/";
|
|
579
646
|
const pathname = new URL(url, "http://127.0.0.1").pathname;
|
|
580
647
|
const viewsEnabled = viewsAtStartup && currentViews.length > 0;
|
|
581
|
-
const isViteRequest = req.method === "GET" && (pathname.startsWith("/@") || pathname.startsWith("/node_modules/") || pathname.startsWith("/.mcp-use/") || viewsEnabled && pathname.startsWith("/
|
|
648
|
+
const isViteRequest = req.method === "GET" && (pathname.startsWith("/@") || pathname.startsWith("/node_modules/") || pathname.startsWith("/.mcp-use/") || viewsEnabled && pathname.startsWith("/views/"));
|
|
582
649
|
if (viewsEnabled && isViteRequest) {
|
|
583
650
|
applyViteModuleCors(req, res, {
|
|
584
651
|
tunnelActive: tunnelManager.status().url !== null,
|