mountly-mcp 0.0.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +283 -20
- package/dist/artifact/index.d.ts +49 -0
- package/dist/artifact/index.js +21 -0
- package/dist/artifact/index.js.map +1 -0
- package/dist/bridge/iframe-entry.d.ts +1 -0
- package/dist/bridge/iframe-entry.js +270 -220
- package/dist/bridge/index.d.ts +20 -15
- package/dist/bridge/index.js +2 -2
- package/dist/build/emit-html.d.ts +30 -0
- package/dist/build/emit-meta.d.ts +17 -0
- package/dist/build/index.d.ts +33 -48
- package/dist/build/index.js +9 -135
- package/dist/build/index.js.map +1 -1
- package/dist/chunk-33DMFKKD.js +111 -0
- package/dist/chunk-33DMFKKD.js.map +1 -0
- package/dist/chunk-4HC3OWAQ.js +185 -0
- package/dist/chunk-4HC3OWAQ.js.map +1 -0
- package/dist/chunk-5EHNJCMF.js +58 -0
- package/dist/chunk-5EHNJCMF.js.map +1 -0
- package/dist/chunk-6QHKKFO3.js +30 -0
- package/dist/chunk-6QHKKFO3.js.map +1 -0
- package/dist/chunk-AEVQKFXX.js +119 -0
- package/dist/chunk-AEVQKFXX.js.map +1 -0
- package/dist/chunk-DKK26TRS.js +199 -0
- package/dist/chunk-DKK26TRS.js.map +1 -0
- package/dist/chunk-JVQZGKBL.js +171 -0
- package/dist/chunk-JVQZGKBL.js.map +1 -0
- package/dist/chunk-KWVGW5Q7.js +582 -0
- package/dist/chunk-KWVGW5Q7.js.map +1 -0
- package/dist/{chunk-A64ZILAS.js → chunk-M4WFJR3C.js} +3 -2
- package/dist/{chunk-A64ZILAS.js.map → chunk-M4WFJR3C.js.map} +1 -1
- package/dist/chunk-MTJDRWGD.js +196 -0
- package/dist/chunk-MTJDRWGD.js.map +1 -0
- package/dist/chunk-SADNMGP6.js +16 -0
- package/dist/chunk-SADNMGP6.js.map +1 -0
- package/dist/chunk-UECZA34Q.js +52 -0
- package/dist/chunk-UECZA34Q.js.map +1 -0
- package/dist/chunk-YJA4H6IB.js +13 -0
- package/dist/chunk-YJA4H6IB.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +297 -0
- package/dist/cli.js.map +1 -0
- package/dist/connect-server-7L4HGKKL.js +7 -0
- package/dist/connect-server-7L4HGKKL.js.map +1 -0
- package/dist/create.d.ts +10 -0
- package/dist/create.js +107 -0
- package/dist/create.js.map +1 -0
- package/dist/dev/connect-server.d.ts +13 -0
- package/dist/dev/host-entry.d.ts +13 -0
- package/dist/dev/host-entry.js +18330 -0
- package/dist/dev/index.d.ts +45 -0
- package/dist/dev/index.js +14 -0
- package/dist/dev/index.js.map +1 -0
- package/dist/dev/sandbox-entry.d.ts +7 -0
- package/dist/dev/sandbox-entry.js +80 -0
- package/dist/html.d.ts +4 -0
- package/dist/index.d.ts +7 -26
- package/dist/index.js +16 -3
- package/dist/json-render/app.d.ts +22 -0
- package/dist/json-render/app.js +10 -0
- package/dist/json-render/app.js.map +1 -0
- package/dist/json-render/generative-view.d.ts +57 -0
- package/dist/json-render/index.d.ts +10 -0
- package/dist/json-render/index.js +120 -0
- package/dist/json-render/index.js.map +1 -0
- package/dist/json-render/mcp.d.ts +49 -0
- package/dist/json-render/mcp.js +11 -0
- package/dist/json-render/mcp.js.map +1 -0
- package/dist/json-render/server.d.ts +72 -0
- package/dist/json-render/server.js +98 -0
- package/dist/json-render/server.js.map +1 -0
- package/dist/json-render/spec-stream.d.ts +26 -0
- package/dist/json-render/use-spec-stream.d.ts +26 -0
- package/dist/publish.d.ts +10 -0
- package/dist/react/context.d.ts +14 -0
- package/dist/react/create-view.d.ts +8 -0
- package/dist/react/hooks.d.ts +46 -0
- package/dist/react/index.d.ts +3 -0
- package/dist/react/index.js +36 -0
- package/dist/react/index.js.map +1 -0
- package/dist/sandbox/index.d.ts +16 -0
- package/dist/sandbox/index.js +8 -0
- package/dist/sandbox/index.js.map +1 -0
- package/dist/schema.d.ts +20 -0
- package/dist/server/index.d.ts +73 -0
- package/dist/server/index.js +235 -0
- package/dist/server/index.js.map +1 -0
- package/dist/svelte/index.d.ts +29 -0
- package/dist/svelte/index.js +13 -0
- package/dist/svelte/index.js.map +1 -0
- package/dist/testing/index.d.ts +27 -0
- package/dist/testing/index.js +312 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/render-artifact.d.ts +35 -0
- package/dist/types.d.ts +65 -0
- package/dist/vite/index.d.ts +23 -0
- package/dist/vite/index.js +211 -0
- package/dist/vite/index.js.map +1 -0
- package/dist/vue/index.d.ts +51 -0
- package/dist/vue/index.js +93 -0
- package/dist/vue/index.js.map +1 -0
- package/package.json +162 -20
- package/templates/react/.gitignore.tmpl +4 -0
- package/templates/react/README.md.tmpl +15 -0
- package/templates/react/mcp.fixtures.json.tmpl +4 -0
- package/templates/react/package.json.tmpl +27 -0
- package/templates/react/server.mjs.tmpl +70 -0
- package/templates/react/src/view.tsx.tmpl +160 -0
- package/templates/react/tsconfig.json.tmpl +15 -0
- package/templates/react/vite.config.ts.tmpl +22 -0
- package/templates/svelte/.gitignore.tmpl +4 -0
- package/templates/svelte/README.md.tmpl +14 -0
- package/templates/svelte/mcp.fixtures.json.tmpl +4 -0
- package/templates/svelte/package.json.tmpl +26 -0
- package/templates/svelte/server.mjs.tmpl +70 -0
- package/templates/svelte/src/Dashboard.svelte.tmpl +158 -0
- package/templates/svelte/src/view.ts.tmpl +14 -0
- package/templates/svelte/tsconfig.json.tmpl +14 -0
- package/templates/svelte/vite.config.ts.tmpl +22 -0
- package/templates/vue/.gitignore.tmpl +4 -0
- package/templates/vue/README.md.tmpl +14 -0
- package/templates/vue/mcp.fixtures.json.tmpl +4 -0
- package/templates/vue/package.json.tmpl +26 -0
- package/templates/vue/server.mjs.tmpl +70 -0
- package/templates/vue/src/Dashboard.vue.tmpl +159 -0
- package/templates/vue/src/view.ts.tmpl +14 -0
- package/templates/vue/tsconfig.json.tmpl +15 -0
- package/templates/vue/vite.config.ts.tmpl +22 -0
- package/dist/chunk-BUGGLMNA.js +0 -132
- package/dist/chunk-BUGGLMNA.js.map +0 -1
- package/dist/types-B9JAWm4W.d.ts +0 -62
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/artifact/index.ts"],"sourcesContent":["import { readFile, writeFile } from \"node:fs/promises\";\nimport { dirname, isAbsolute, relative, resolve } from \"node:path\";\nimport {\n McpUiDisplayModeSchema,\n McpUiResourceMetaSchema,\n RESOURCE_MIME_TYPE,\n LATEST_PROTOCOL_VERSION,\n} from \"@modelcontextprotocol/ext-apps\";\nimport type { McpResourceDeclaration } from \"../types.js\";\n\nexport const MCP_APP_MANIFEST_VERSION = 1 as const;\nexport const MCP_APP_MANIFEST_FILE = \"mountly-mcp.manifest.json\";\n\nexport interface McpAppArtifact {\n /** Developer-facing unique key. */\n name: string;\n /** Protocol identity. */\n uri: string;\n /** Absolute path to the self-contained View HTML. */\n htmlPath: string;\n /** Absolute path to the transitional per-View sidecar. */\n metaPath: string;\n declaration: McpResourceDeclaration;\n}\n\nexport interface McpAppManifestEntry {\n name: string;\n uri: string;\n /** Path relative to the manifest, unless explicitly absolute. */\n html: string;\n /** Path relative to the manifest, unless explicitly absolute. */\n meta: string;\n declaration: McpResourceDeclaration;\n}\n\nexport interface McpAppManifest {\n formatVersion: typeof MCP_APP_MANIFEST_VERSION;\n protocolVersion: typeof LATEST_PROTOCOL_VERSION;\n apps: ReadonlyArray<McpAppManifestEntry>;\n}\n\nexport type ConformanceSeverity = \"error\" | \"warning\";\n\nexport interface ConformanceDiagnostic {\n severity: ConformanceSeverity;\n code: string;\n message: string;\n source?: string;\n}\n\nexport class McpAppConformanceError extends Error {\n readonly diagnostics: ReadonlyArray<ConformanceDiagnostic>;\n\n constructor(diagnostics: ReadonlyArray<ConformanceDiagnostic>) {\n super(diagnostics.map((d) => `${d.code}: ${d.message}`).join(\"\\n\"));\n this.name = \"McpAppConformanceError\";\n this.diagnostics = diagnostics;\n }\n}\n\nfunction object(value: unknown): Record<string, unknown> | undefined {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nexport function inspectMcpResourceDeclaration(\n value: unknown,\n source?: string,\n): ReadonlyArray<ConformanceDiagnostic> {\n const diagnostics: ConformanceDiagnostic[] = [];\n const add = (code: string, message: string): void => {\n diagnostics.push({ severity: \"error\", code, message, source });\n };\n const candidate = object(value);\n if (!candidate) {\n add(\"artifact/not-object\", \"resource declaration must be an object\");\n return diagnostics;\n }\n if (candidate.protocolVersion !== LATEST_PROTOCOL_VERSION) {\n add(\n \"artifact/protocol-version\",\n `sidecar protocolVersion must be '${LATEST_PROTOCOL_VERSION}' (received '${String(candidate.protocolVersion)}')`,\n );\n }\n if (typeof candidate.uri !== \"string\" || !candidate.uri.startsWith(\"ui://\")) {\n add(\"artifact/uri\", `uri must use the 'ui://' scheme (received '${String(candidate.uri)}')`);\n }\n if (typeof candidate.name !== \"string\" || candidate.name.trim() === \"\") {\n add(\"artifact/name\", \"name must be a non-empty string\");\n }\n if (candidate.mimeType !== RESOURCE_MIME_TYPE) {\n add(\n \"artifact/mime-type\",\n `sidecar mimeType must be '${RESOURCE_MIME_TYPE}' (received '${String(candidate.mimeType)}')`,\n );\n }\n if (typeof candidate.awaitToolResult !== \"boolean\") {\n add(\"artifact/await-tool-result\", \"awaitToolResult must be a boolean\");\n }\n if (\n !Array.isArray(candidate.displayModes) ||\n candidate.displayModes.length === 0 ||\n candidate.displayModes.some((mode) => !McpUiDisplayModeSchema.safeParse(mode).success)\n ) {\n add(\"artifact/display-modes\", \"displayModes must contain supported MCP Apps display modes\");\n }\n const meta = object(candidate._meta);\n const ui = meta && object(meta.ui);\n if (!ui || !McpUiResourceMetaSchema.safeParse(ui).success) {\n add(\"artifact/resource-meta\", \"_meta.ui must be valid MCP Apps resource metadata\");\n }\n return diagnostics;\n}\n\nexport function parseMcpResourceDeclaration(\n value: unknown,\n source?: string,\n): McpResourceDeclaration {\n const diagnostics = inspectMcpResourceDeclaration(value, source);\n if (diagnostics.length > 0) throw new McpAppConformanceError(diagnostics);\n return value as McpResourceDeclaration;\n}\n\nexport async function readMcpAppArtifact(\n htmlPath: string,\n expectedUri?: string,\n): Promise<McpAppArtifact> {\n const absoluteHtmlPath = resolve(htmlPath);\n const metaPath = `${absoluteHtmlPath}.meta.json`;\n const [html, raw] = await Promise.all([\n readFile(absoluteHtmlPath, \"utf8\"),\n readFile(metaPath, \"utf8\"),\n ]);\n if (!/^\\s*<!doctype html>/i.test(html)) {\n throw new McpAppConformanceError([\n {\n severity: \"error\",\n code: \"artifact/html5\",\n message: \"View HTML must start with an HTML5 doctype\",\n source: absoluteHtmlPath,\n },\n ]);\n }\n let decoded: unknown;\n try {\n decoded = JSON.parse(raw);\n } catch (error) {\n throw new McpAppConformanceError([\n {\n severity: \"error\",\n code: \"artifact/meta-json\",\n message: `metadata is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,\n source: metaPath,\n },\n ]);\n }\n const declaration = parseMcpResourceDeclaration(decoded, metaPath);\n if (expectedUri !== undefined && declaration.uri !== expectedUri) {\n throw new McpAppConformanceError([\n {\n severity: \"error\",\n code: \"artifact/uri-mismatch\",\n message: `registration uri '${expectedUri}' does not match sidecar uri '${declaration.uri}'`,\n source: metaPath,\n },\n ]);\n }\n return {\n name: declaration.name,\n uri: declaration.uri,\n htmlPath: absoluteHtmlPath,\n metaPath,\n declaration,\n };\n}\n\nfunction manifestPath(path: string, base: string): string {\n return isAbsolute(path) ? path : resolve(base, path);\n}\n\nexport async function writeMcpAppManifest(\n path: string,\n artifacts: ReadonlyArray<McpAppArtifact>,\n): Promise<McpAppManifest> {\n const absolutePath = resolve(path);\n const base = dirname(absolutePath);\n const names = new Set<string>();\n const uris = new Set<string>();\n for (const artifact of artifacts) {\n if (names.has(artifact.name))\n throw new Error(`mountly-mcp: duplicate app name '${artifact.name}'`);\n if (uris.has(artifact.uri)) throw new Error(`mountly-mcp: duplicate app uri '${artifact.uri}'`);\n names.add(artifact.name);\n uris.add(artifact.uri);\n }\n const manifest: McpAppManifest = {\n formatVersion: MCP_APP_MANIFEST_VERSION,\n protocolVersion: LATEST_PROTOCOL_VERSION,\n apps: artifacts.map((artifact) => ({\n name: artifact.name,\n uri: artifact.uri,\n html: relative(base, artifact.htmlPath),\n meta: relative(base, artifact.metaPath),\n declaration: artifact.declaration,\n })),\n };\n await writeFile(absolutePath, JSON.stringify(manifest, null, 2), \"utf8\");\n return manifest;\n}\n\nexport async function readMcpAppManifest(path: string): Promise<{\n path: string;\n manifest: McpAppManifest;\n artifacts: ReadonlyArray<McpAppArtifact>;\n}> {\n const absolutePath = resolve(path);\n const base = dirname(absolutePath);\n let decoded: unknown;\n try {\n decoded = JSON.parse(await readFile(absolutePath, \"utf8\"));\n } catch (error) {\n throw new Error(\n `mountly-mcp: could not read manifest '${absolutePath}': ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n const candidate = object(decoded);\n if (\n candidate?.formatVersion !== MCP_APP_MANIFEST_VERSION ||\n candidate.protocolVersion !== LATEST_PROTOCOL_VERSION ||\n !Array.isArray(candidate.apps)\n ) {\n throw new Error(\n `mountly-mcp: '${absolutePath}' is not a supported mountly-mcp manifest (expected formatVersion ${MCP_APP_MANIFEST_VERSION})`,\n );\n }\n const manifest = decoded as McpAppManifest;\n const names = new Set<string>();\n const uris = new Set<string>();\n const artifacts: McpAppArtifact[] = [];\n for (const entry of manifest.apps) {\n if (names.has(entry.name)) throw new Error(`mountly-mcp: duplicate app name '${entry.name}'`);\n if (uris.has(entry.uri)) throw new Error(`mountly-mcp: duplicate app uri '${entry.uri}'`);\n names.add(entry.name);\n uris.add(entry.uri);\n const declaration = parseMcpResourceDeclaration(entry.declaration, absolutePath);\n if (declaration.name !== entry.name || declaration.uri !== entry.uri) {\n throw new Error(\n `mountly-mcp: manifest identity does not match declaration for '${entry.name}'`,\n );\n }\n artifacts.push({\n name: entry.name,\n uri: entry.uri,\n htmlPath: manifestPath(entry.html, base),\n metaPath: manifestPath(entry.meta, base),\n declaration,\n });\n }\n return { path: absolutePath, manifest, artifacts };\n}\n"],"mappings":";AAAA,SAAS,UAAU,iBAAiB;AACpC,SAAS,SAAS,YAAY,UAAU,eAAe;AACvD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGA,IAAM,2BAA2B;AACjC,IAAM,wBAAwB;AAuC9B,IAAM,yBAAN,cAAqC,MAAM;AAAA,EAGhD,YAAY,aAAmD;AAC7D,UAAM,YAAY,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,KAAK,EAAE,OAAO,EAAE,EAAE,KAAK,IAAI,CAAC;AAClE,SAAK,OAAO;AACZ,SAAK,cAAc;AAAA,EACrB;AACF;AAEA,SAAS,OAAO,OAAqD;AACnE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK,IACrE,QACD;AACN;AAEO,SAAS,8BACd,OACA,QACsC;AACtC,QAAM,cAAuC,CAAC;AAC9C,QAAM,MAAM,CAAC,MAAc,YAA0B;AACnD,gBAAY,KAAK,EAAE,UAAU,SAAS,MAAM,SAAS,OAAO,CAAC;AAAA,EAC/D;AACA,QAAM,YAAY,OAAO,KAAK;AAC9B,MAAI,CAAC,WAAW;AACd,QAAI,uBAAuB,wCAAwC;AACnE,WAAO;AAAA,EACT;AACA,MAAI,UAAU,oBAAoB,yBAAyB;AACzD;AAAA,MACE;AAAA,MACA,oCAAoC,uBAAuB,gBAAgB,OAAO,UAAU,eAAe,CAAC;AAAA,IAC9G;AAAA,EACF;AACA,MAAI,OAAO,UAAU,QAAQ,YAAY,CAAC,UAAU,IAAI,WAAW,OAAO,GAAG;AAC3E,QAAI,gBAAgB,8CAA8C,OAAO,UAAU,GAAG,CAAC,IAAI;AAAA,EAC7F;AACA,MAAI,OAAO,UAAU,SAAS,YAAY,UAAU,KAAK,KAAK,MAAM,IAAI;AACtE,QAAI,iBAAiB,iCAAiC;AAAA,EACxD;AACA,MAAI,UAAU,aAAa,oBAAoB;AAC7C;AAAA,MACE;AAAA,MACA,6BAA6B,kBAAkB,gBAAgB,OAAO,UAAU,QAAQ,CAAC;AAAA,IAC3F;AAAA,EACF;AACA,MAAI,OAAO,UAAU,oBAAoB,WAAW;AAClD,QAAI,8BAA8B,mCAAmC;AAAA,EACvE;AACA,MACE,CAAC,MAAM,QAAQ,UAAU,YAAY,KACrC,UAAU,aAAa,WAAW,KAClC,UAAU,aAAa,KAAK,CAAC,SAAS,CAAC,uBAAuB,UAAU,IAAI,EAAE,OAAO,GACrF;AACA,QAAI,0BAA0B,4DAA4D;AAAA,EAC5F;AACA,QAAM,OAAO,OAAO,UAAU,KAAK;AACnC,QAAM,KAAK,QAAQ,OAAO,KAAK,EAAE;AACjC,MAAI,CAAC,MAAM,CAAC,wBAAwB,UAAU,EAAE,EAAE,SAAS;AACzD,QAAI,0BAA0B,mDAAmD;AAAA,EACnF;AACA,SAAO;AACT;AAEO,SAAS,4BACd,OACA,QACwB;AACxB,QAAM,cAAc,8BAA8B,OAAO,MAAM;AAC/D,MAAI,YAAY,SAAS,EAAG,OAAM,IAAI,uBAAuB,WAAW;AACxE,SAAO;AACT;AAEA,eAAsB,mBACpB,UACA,aACyB;AACzB,QAAM,mBAAmB,QAAQ,QAAQ;AACzC,QAAM,WAAW,GAAG,gBAAgB;AACpC,QAAM,CAAC,MAAM,GAAG,IAAI,MAAM,QAAQ,IAAI;AAAA,IACpC,SAAS,kBAAkB,MAAM;AAAA,IACjC,SAAS,UAAU,MAAM;AAAA,EAC3B,CAAC;AACD,MAAI,CAAC,uBAAuB,KAAK,IAAI,GAAG;AACtC,UAAM,IAAI,uBAAuB;AAAA,MAC/B;AAAA,QACE,UAAU;AAAA,QACV,MAAM;AAAA,QACN,SAAS;AAAA,QACT,QAAQ;AAAA,MACV;AAAA,IACF,CAAC;AAAA,EACH;AACA,MAAI;AACJ,MAAI;AACF,cAAU,KAAK,MAAM,GAAG;AAAA,EAC1B,SAAS,OAAO;AACd,UAAM,IAAI,uBAAuB;AAAA,MAC/B;AAAA,QACE,UAAU;AAAA,QACV,MAAM;AAAA,QACN,SAAS,+BAA+B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,QAC9F,QAAQ;AAAA,MACV;AAAA,IACF,CAAC;AAAA,EACH;AACA,QAAM,cAAc,4BAA4B,SAAS,QAAQ;AACjE,MAAI,gBAAgB,UAAa,YAAY,QAAQ,aAAa;AAChE,UAAM,IAAI,uBAAuB;AAAA,MAC/B;AAAA,QACE,UAAU;AAAA,QACV,MAAM;AAAA,QACN,SAAS,qBAAqB,WAAW,iCAAiC,YAAY,GAAG;AAAA,QACzF,QAAQ;AAAA,MACV;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AAAA,IACL,MAAM,YAAY;AAAA,IAClB,KAAK,YAAY;AAAA,IACjB,UAAU;AAAA,IACV;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,aAAa,MAAc,MAAsB;AACxD,SAAO,WAAW,IAAI,IAAI,OAAO,QAAQ,MAAM,IAAI;AACrD;AAEA,eAAsB,oBACpB,MACA,WACyB;AACzB,QAAM,eAAe,QAAQ,IAAI;AACjC,QAAM,OAAO,QAAQ,YAAY;AACjC,QAAM,QAAQ,oBAAI,IAAY;AAC9B,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,YAAY,WAAW;AAChC,QAAI,MAAM,IAAI,SAAS,IAAI;AACzB,YAAM,IAAI,MAAM,oCAAoC,SAAS,IAAI,GAAG;AACtE,QAAI,KAAK,IAAI,SAAS,GAAG,EAAG,OAAM,IAAI,MAAM,mCAAmC,SAAS,GAAG,GAAG;AAC9F,UAAM,IAAI,SAAS,IAAI;AACvB,SAAK,IAAI,SAAS,GAAG;AAAA,EACvB;AACA,QAAM,WAA2B;AAAA,IAC/B,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,MAAM,UAAU,IAAI,CAAC,cAAc;AAAA,MACjC,MAAM,SAAS;AAAA,MACf,KAAK,SAAS;AAAA,MACd,MAAM,SAAS,MAAM,SAAS,QAAQ;AAAA,MACtC,MAAM,SAAS,MAAM,SAAS,QAAQ;AAAA,MACtC,aAAa,SAAS;AAAA,IACxB,EAAE;AAAA,EACJ;AACA,QAAM,UAAU,cAAc,KAAK,UAAU,UAAU,MAAM,CAAC,GAAG,MAAM;AACvE,SAAO;AACT;AAEA,eAAsB,mBAAmB,MAItC;AACD,QAAM,eAAe,QAAQ,IAAI;AACjC,QAAM,OAAO,QAAQ,YAAY;AACjC,MAAI;AACJ,MAAI;AACF,cAAU,KAAK,MAAM,MAAM,SAAS,cAAc,MAAM,CAAC;AAAA,EAC3D,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,yCAAyC,YAAY,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,IACnH;AAAA,EACF;AACA,QAAM,YAAY,OAAO,OAAO;AAChC,MACE,WAAW,kBAAkB,4BAC7B,UAAU,oBAAoB,2BAC9B,CAAC,MAAM,QAAQ,UAAU,IAAI,GAC7B;AACA,UAAM,IAAI;AAAA,MACR,iBAAiB,YAAY,qEAAqE,wBAAwB;AAAA,IAC5H;AAAA,EACF;AACA,QAAM,WAAW;AACjB,QAAM,QAAQ,oBAAI,IAAY;AAC9B,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,YAA8B,CAAC;AACrC,aAAW,SAAS,SAAS,MAAM;AACjC,QAAI,MAAM,IAAI,MAAM,IAAI,EAAG,OAAM,IAAI,MAAM,oCAAoC,MAAM,IAAI,GAAG;AAC5F,QAAI,KAAK,IAAI,MAAM,GAAG,EAAG,OAAM,IAAI,MAAM,mCAAmC,MAAM,GAAG,GAAG;AACxF,UAAM,IAAI,MAAM,IAAI;AACpB,SAAK,IAAI,MAAM,GAAG;AAClB,UAAM,cAAc,4BAA4B,MAAM,aAAa,YAAY;AAC/E,QAAI,YAAY,SAAS,MAAM,QAAQ,YAAY,QAAQ,MAAM,KAAK;AACpE,YAAM,IAAI;AAAA,QACR,kEAAkE,MAAM,IAAI;AAAA,MAC9E;AAAA,IACF;AACA,cAAU,KAAK;AAAA,MACb,MAAM,MAAM;AAAA,MACZ,KAAK,MAAM;AAAA,MACX,UAAU,aAAa,MAAM,MAAM,IAAI;AAAA,MACvC,UAAU,aAAa,MAAM,MAAM,IAAI;AAAA,MACvC;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO,EAAE,MAAM,cAAc,UAAU,UAAU;AACnD;","names":[]}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MCP_ERROR_CODES
|
|
3
|
+
} from "./chunk-M4WFJR3C.js";
|
|
4
|
+
|
|
5
|
+
// src/bridge/index.ts
|
|
6
|
+
import {
|
|
7
|
+
App,
|
|
8
|
+
PostMessageTransport
|
|
9
|
+
} from "@modelcontextprotocol/ext-apps";
|
|
10
|
+
function renderErrorBoundary(container, code, message) {
|
|
11
|
+
container.setAttribute("data-mountly-mcp-state", "error");
|
|
12
|
+
const doc = container.ownerDocument;
|
|
13
|
+
if (!doc) return;
|
|
14
|
+
const errorDiv = doc.createElement("div");
|
|
15
|
+
errorDiv.setAttribute("data-mountly-mcp-error", code);
|
|
16
|
+
if (message !== void 0) errorDiv.textContent = message;
|
|
17
|
+
container.innerHTML = "";
|
|
18
|
+
container.appendChild(errorDiv);
|
|
19
|
+
}
|
|
20
|
+
function runBridge(options) {
|
|
21
|
+
const {
|
|
22
|
+
view,
|
|
23
|
+
container,
|
|
24
|
+
awaitToolResult = true,
|
|
25
|
+
streamToolInput = false,
|
|
26
|
+
availableDisplayModes = ["inline"],
|
|
27
|
+
appInfo = { name: "mountly-mcp", version: "0.0.0" }
|
|
28
|
+
} = options;
|
|
29
|
+
const appCapabilities = {
|
|
30
|
+
availableDisplayModes: [...availableDisplayModes]
|
|
31
|
+
};
|
|
32
|
+
const app = options.app ?? new App(appInfo, appCapabilities);
|
|
33
|
+
let toolInput;
|
|
34
|
+
let toolInputPartial;
|
|
35
|
+
let toolResult;
|
|
36
|
+
let mounted = false;
|
|
37
|
+
let stopped = false;
|
|
38
|
+
let pending = Promise.resolve();
|
|
39
|
+
function currentProps() {
|
|
40
|
+
return {
|
|
41
|
+
mcp: app,
|
|
42
|
+
toolInput,
|
|
43
|
+
toolInputPartial,
|
|
44
|
+
toolResult,
|
|
45
|
+
hostContext: app.getHostContext()
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function notifyError(code, error) {
|
|
49
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
50
|
+
try {
|
|
51
|
+
void app.sendLog({ level: "error", data: { code, message } }).catch(() => void 0);
|
|
52
|
+
} catch {
|
|
53
|
+
}
|
|
54
|
+
renderErrorBoundary(container, code, message);
|
|
55
|
+
}
|
|
56
|
+
function renderWith(props) {
|
|
57
|
+
pending = pending.then(async () => {
|
|
58
|
+
if (stopped) return;
|
|
59
|
+
try {
|
|
60
|
+
if (!mounted) {
|
|
61
|
+
const r = view.mount(container, props);
|
|
62
|
+
if (r instanceof Promise) await r;
|
|
63
|
+
mounted = true;
|
|
64
|
+
container.setAttribute("data-mountly-mcp-state", "mounted");
|
|
65
|
+
} else if (view.update) {
|
|
66
|
+
const r = view.update(container, props);
|
|
67
|
+
if (r instanceof Promise) await r;
|
|
68
|
+
} else {
|
|
69
|
+
await view.unmount(container);
|
|
70
|
+
mounted = false;
|
|
71
|
+
const r = view.mount(container, props);
|
|
72
|
+
if (r instanceof Promise) await r;
|
|
73
|
+
mounted = true;
|
|
74
|
+
}
|
|
75
|
+
} catch (error) {
|
|
76
|
+
notifyError(MCP_ERROR_CODES.VIEW_MOUNT_THREW, error);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
return pending;
|
|
80
|
+
}
|
|
81
|
+
async function unmountView() {
|
|
82
|
+
await pending;
|
|
83
|
+
if (!mounted) return;
|
|
84
|
+
mounted = false;
|
|
85
|
+
await view.unmount(container);
|
|
86
|
+
}
|
|
87
|
+
const handleToolInput = (params) => {
|
|
88
|
+
toolInput = params;
|
|
89
|
+
toolInputPartial = void 0;
|
|
90
|
+
if (!awaitToolResult) return;
|
|
91
|
+
if (mounted || toolResult !== void 0) void renderWith(currentProps());
|
|
92
|
+
};
|
|
93
|
+
const handleToolInputPartial = (params) => {
|
|
94
|
+
if (!streamToolInput) return;
|
|
95
|
+
toolInputPartial = params;
|
|
96
|
+
void renderWith(currentProps());
|
|
97
|
+
};
|
|
98
|
+
const handleToolResult = (params) => {
|
|
99
|
+
toolResult = params;
|
|
100
|
+
void renderWith(currentProps());
|
|
101
|
+
};
|
|
102
|
+
const handleToolCancelled = () => {
|
|
103
|
+
void renderWith(currentProps());
|
|
104
|
+
};
|
|
105
|
+
const handleHostContextChanged = () => {
|
|
106
|
+
if (mounted) void renderWith(currentProps());
|
|
107
|
+
};
|
|
108
|
+
app.addEventListener("toolinput", handleToolInput);
|
|
109
|
+
app.addEventListener("toolinputpartial", handleToolInputPartial);
|
|
110
|
+
app.addEventListener("toolresult", handleToolResult);
|
|
111
|
+
app.addEventListener("toolcancelled", handleToolCancelled);
|
|
112
|
+
app.addEventListener("hostcontextchanged", handleHostContextChanged);
|
|
113
|
+
const previousTeardown = app.onteardown;
|
|
114
|
+
const bridgeTeardown = async (params, extra) => {
|
|
115
|
+
stopped = true;
|
|
116
|
+
detachTeardown();
|
|
117
|
+
detachAppHandlers();
|
|
118
|
+
await unmountView();
|
|
119
|
+
return await previousTeardown?.(params, extra) ?? {};
|
|
120
|
+
};
|
|
121
|
+
app.onteardown = bridgeTeardown;
|
|
122
|
+
function detachAppHandlers() {
|
|
123
|
+
app.removeEventListener("toolinput", handleToolInput);
|
|
124
|
+
app.removeEventListener("toolinputpartial", handleToolInputPartial);
|
|
125
|
+
app.removeEventListener("toolresult", handleToolResult);
|
|
126
|
+
app.removeEventListener("toolcancelled", handleToolCancelled);
|
|
127
|
+
app.removeEventListener("hostcontextchanged", handleHostContextChanged);
|
|
128
|
+
if (app.onteardown === bridgeTeardown) app.onteardown = previousTeardown;
|
|
129
|
+
}
|
|
130
|
+
const ready = (async () => {
|
|
131
|
+
try {
|
|
132
|
+
if (!options.app) {
|
|
133
|
+
await app.connect();
|
|
134
|
+
}
|
|
135
|
+
if (!awaitToolResult) {
|
|
136
|
+
await renderWith(currentProps());
|
|
137
|
+
}
|
|
138
|
+
} catch (error) {
|
|
139
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
140
|
+
const code = /timeout/i.test(message) ? MCP_ERROR_CODES.INITIALIZE_TIMEOUT : MCP_ERROR_CODES.INITIALIZE_FAILED;
|
|
141
|
+
notifyError(code, error);
|
|
142
|
+
throw error;
|
|
143
|
+
}
|
|
144
|
+
})();
|
|
145
|
+
let detachTeardown = () => void 0;
|
|
146
|
+
function stopBridge() {
|
|
147
|
+
if (stopped) return;
|
|
148
|
+
stopped = true;
|
|
149
|
+
detachTeardown();
|
|
150
|
+
detachAppHandlers();
|
|
151
|
+
void unmountView();
|
|
152
|
+
if (!options.app) void app.close().catch(() => void 0);
|
|
153
|
+
}
|
|
154
|
+
detachTeardown = options.onTeardown?.(stopBridge) ?? (typeof window !== "undefined" ? (() => {
|
|
155
|
+
const h = () => stopBridge();
|
|
156
|
+
window.addEventListener("beforeunload", h);
|
|
157
|
+
return () => window.removeEventListener("beforeunload", h);
|
|
158
|
+
})() : () => void 0);
|
|
159
|
+
return {
|
|
160
|
+
ready,
|
|
161
|
+
app,
|
|
162
|
+
stop: stopBridge
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export {
|
|
167
|
+
App,
|
|
168
|
+
PostMessageTransport,
|
|
169
|
+
runBridge
|
|
170
|
+
};
|
|
171
|
+
//# sourceMappingURL=chunk-JVQZGKBL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/bridge/index.ts"],"sourcesContent":["/**\n * View-side bridge that turns an MCP Apps `App` into a mountly view module\n * lifecycle. The full spec handshake — `ui/initialize`,\n * `ui/notifications/initialized`, `ui/notifications/tool-input(-partial)`,\n * `ui/notifications/tool-result`, `ui/notifications/tool-cancelled`,\n * `ui/notifications/host-context-changed`, `ui/resource-teardown`,\n * `ui/notifications/size-changed` — is delegated to ext-apps's `App`.\n */\nimport {\n App,\n PostMessageTransport,\n type McpUiAppCapabilities,\n type McpUiDisplayMode,\n type McpUiToolInputNotification,\n type McpUiToolInputPartialNotification,\n type McpUiToolResultNotification,\n} from \"@modelcontextprotocol/ext-apps\";\n\nimport { MCP_ERROR_CODES } from \"../schema.js\";\nimport type { McpView, McpViewProps } from \"../types.js\";\n\nexport interface RunBridgeOptions {\n /** Pre-constructed App (used by jsdom tests); otherwise one is created here. */\n app?: App;\n view: McpView;\n container: Element;\n /**\n * If true (default), mount is deferred until the first tool-result arrives;\n * the View renders against `{ toolInput, toolResult, hostContext, mcp }`\n * props on each notification.\n *\n * If false, mount fires immediately after `ui/initialize` with `{ mcp }`\n * only — for \"stateless\" views that drive themselves via `mcp.callServerTool`.\n */\n awaitToolResult?: boolean;\n /**\n * Render progressive states from `ui/notifications/tool-input-partial`.\n *\n * Off by default — the spec lets views ignore partials, and they carry\n * best-effort recovered JSON that MUST NOT drive critical operations. When\n * on, partials arrive as `toolInputPartial` (mounting the View early if\n * needed) and are cleared once the complete `tool-input` lands.\n */\n streamToolInput?: boolean;\n /** Display modes this view supports. Declared to the host during `ui/initialize`. */\n availableDisplayModes?: ReadonlyArray<McpUiDisplayMode>;\n /** App identity sent during `ui/initialize`. */\n appInfo?: { name: string; version: string };\n /** Override for tests; defaults to `window.addEventListener('beforeunload', ...)`. */\n onTeardown?: (handler: () => void) => () => void;\n}\n\nexport interface RunningBridge {\n /** Resolves once `ui/initialize` handshake completes and the first mount (or deferred mount) is wired. */\n ready: Promise<void>;\n /** The underlying App; exposed for hosts that want to drive the view directly. */\n app: App;\n /** Synchronously triggers teardown. */\n stop(): void;\n}\n\n/**\n * `data-mountly-mcp-state` is the View's machine-readable outcome, read by\n * `verify --render`. It only ever moves forward — `mounted` once the View\n * has mounted, `error` if the boundary replaced it — so a state written here\n * can never be clobbered by a later lifecycle step.\n */\nfunction renderErrorBoundary(container: Element, code: string, message?: string): void {\n container.setAttribute(\"data-mountly-mcp-state\", \"error\");\n const doc = container.ownerDocument;\n if (!doc) return;\n const errorDiv = doc.createElement(\"div\");\n errorDiv.setAttribute(\"data-mountly-mcp-error\", code);\n if (message !== undefined) errorDiv.textContent = message;\n container.innerHTML = \"\";\n container.appendChild(errorDiv);\n}\n\nexport function runBridge(options: RunBridgeOptions): RunningBridge {\n const {\n view,\n container,\n awaitToolResult = true,\n streamToolInput = false,\n availableDisplayModes = [\"inline\"],\n appInfo = { name: \"mountly-mcp\", version: \"0.0.0\" },\n } = options;\n\n const appCapabilities: McpUiAppCapabilities = {\n availableDisplayModes: [...availableDisplayModes],\n };\n\n const app = options.app ?? new App(appInfo, appCapabilities);\n\n let toolInput: McpUiToolInputNotification[\"params\"] | undefined;\n let toolInputPartial: McpUiToolInputPartialNotification[\"params\"] | undefined;\n let toolResult: McpUiToolResultNotification[\"params\"] | undefined;\n let mounted = false;\n let stopped = false;\n let pending: Promise<void> = Promise.resolve();\n\n function currentProps(): McpViewProps {\n return {\n mcp: app,\n toolInput,\n toolInputPartial,\n toolResult,\n hostContext: app.getHostContext(),\n };\n }\n\n function notifyError(code: string, error: unknown): void {\n const message = error instanceof Error ? error.message : String(error);\n try {\n void app.sendLog({ level: \"error\", data: { code, message } }).catch(() => undefined);\n } catch {\n // ignore — log channel may not be ready\n }\n renderErrorBoundary(container, code, message);\n }\n\n function renderWith(props: McpViewProps): Promise<void> {\n pending = pending.then(async () => {\n if (stopped) return;\n try {\n if (!mounted) {\n const r = view.mount(container, props);\n if (r instanceof Promise) await r;\n mounted = true;\n container.setAttribute(\"data-mountly-mcp-state\", \"mounted\");\n } else if (view.update) {\n const r = view.update(container, props);\n if (r instanceof Promise) await r;\n } else {\n await view.unmount(container);\n mounted = false;\n const r = view.mount(container, props);\n if (r instanceof Promise) await r;\n mounted = true;\n }\n } catch (error) {\n notifyError(MCP_ERROR_CODES.VIEW_MOUNT_THREW, error);\n }\n });\n return pending;\n }\n\n async function unmountView(): Promise<void> {\n await pending;\n if (!mounted) return;\n mounted = false;\n await view.unmount(container);\n }\n\n // Event handlers MUST be registered before connect() — ext-apps will refuse\n // to attach handlers retroactively after the initialize handshake completes.\n const handleToolInput = (params: McpUiToolInputNotification[\"params\"]) => {\n toolInput = params;\n toolInputPartial = undefined;\n if (!awaitToolResult) return;\n if (mounted || toolResult !== undefined) void renderWith(currentProps());\n };\n\n const handleToolInputPartial = (params: McpUiToolInputPartialNotification[\"params\"]) => {\n // Views MAY ignore partial input per spec; opt in with `streamToolInput`.\n // Consumers wanting finer control can subscribe via app.addEventListener.\n if (!streamToolInput) return;\n toolInputPartial = params;\n void renderWith(currentProps());\n };\n\n const handleToolResult = (params: McpUiToolResultNotification[\"params\"]) => {\n toolResult = params;\n void renderWith(currentProps());\n };\n\n const handleToolCancelled = () => {\n void renderWith(currentProps());\n };\n\n const handleHostContextChanged = () => {\n if (mounted) void renderWith(currentProps());\n };\n\n app.addEventListener(\"toolinput\", handleToolInput);\n app.addEventListener(\"toolinputpartial\", handleToolInputPartial);\n app.addEventListener(\"toolresult\", handleToolResult);\n app.addEventListener(\"toolcancelled\", handleToolCancelled);\n app.addEventListener(\"hostcontextchanged\", handleHostContextChanged);\n\n const previousTeardown = app.onteardown;\n const bridgeTeardown: NonNullable<typeof app.onteardown> = async (params, extra) => {\n stopped = true;\n detachTeardown();\n detachAppHandlers();\n await unmountView();\n return (await previousTeardown?.(params, extra)) ?? {};\n };\n app.onteardown = bridgeTeardown;\n\n function detachAppHandlers(): void {\n app.removeEventListener(\"toolinput\", handleToolInput);\n app.removeEventListener(\"toolinputpartial\", handleToolInputPartial);\n app.removeEventListener(\"toolresult\", handleToolResult);\n app.removeEventListener(\"toolcancelled\", handleToolCancelled);\n app.removeEventListener(\"hostcontextchanged\", handleHostContextChanged);\n if (app.onteardown === bridgeTeardown) app.onteardown = previousTeardown;\n }\n\n const ready = (async () => {\n try {\n if (!options.app) {\n // App.connect() defaults to PostMessageTransport(window.parent, window.parent)\n // and owns automatic resize setup.\n await app.connect();\n }\n\n if (!awaitToolResult) {\n await renderWith(currentProps());\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const code = /timeout/i.test(message)\n ? MCP_ERROR_CODES.INITIALIZE_TIMEOUT\n : MCP_ERROR_CODES.INITIALIZE_FAILED;\n notifyError(code, error);\n throw error;\n }\n })();\n\n let detachTeardown: () => void = () => undefined;\n\n function stopBridge(): void {\n if (stopped) return;\n stopped = true;\n detachTeardown();\n detachAppHandlers();\n void unmountView();\n if (!options.app) void app.close().catch(() => undefined);\n }\n\n detachTeardown =\n options.onTeardown?.(stopBridge) ??\n (typeof window !== \"undefined\"\n ? (() => {\n const h = () => stopBridge();\n window.addEventListener(\"beforeunload\", h);\n return () => window.removeEventListener(\"beforeunload\", h);\n })()\n : () => undefined);\n\n return {\n ready,\n app,\n stop: stopBridge,\n };\n}\n\nexport { App, PostMessageTransport };\nexport type {\n McpUiAppCapabilities,\n McpUiHostCapabilities,\n McpUiHostContext,\n McpUiToolInputNotification,\n McpUiToolInputPartialNotification,\n McpUiToolResultNotification,\n McpUiToolCancelledNotification,\n McpUiHostContextChangedNotification,\n} from \"@modelcontextprotocol/ext-apps\";\n"],"mappings":"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","names":[]}
|