@nimblebrain/synapse 0.19.0 → 0.21.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/README.md +20 -25
- package/dist/check-QMTOCTRS.js +474 -0
- package/dist/check-QMTOCTRS.js.map +1 -0
- package/dist/check-VK4SOAUU.cjs +480 -0
- package/dist/check-VK4SOAUU.cjs.map +1 -0
- package/dist/{chunk-RU64F5RS.cjs → chunk-BNF352SA.cjs} +57 -146
- package/dist/chunk-BNF352SA.cjs.map +1 -0
- package/dist/{chunk-DRLVEHCD.js → chunk-DJS2FKBN.js} +21 -79
- package/dist/chunk-DJS2FKBN.js.map +1 -0
- package/dist/chunk-H3INUKA3.js +32 -0
- package/dist/chunk-H3INUKA3.js.map +1 -0
- package/dist/chunk-HQLSVUOR.cjs +667 -0
- package/dist/chunk-HQLSVUOR.cjs.map +1 -0
- package/dist/{chunk-NP7ROSH2.cjs → chunk-ISV6HFQE.cjs} +14 -7
- package/dist/chunk-ISV6HFQE.cjs.map +1 -0
- package/dist/chunk-TR2YNWZ5.js +658 -0
- package/dist/chunk-TR2YNWZ5.js.map +1 -0
- package/dist/{chunk-OYLZ5OCK.js → chunk-UKP4W6DI.js} +57 -146
- package/dist/chunk-UKP4W6DI.js.map +1 -0
- package/dist/{chunk-SZWHFTXV.cjs → chunk-YSL7KJNU.cjs} +21 -81
- package/dist/chunk-YSL7KJNU.cjs.map +1 -0
- package/dist/codegen/cli.cjs +41 -4
- package/dist/codegen/cli.cjs.map +1 -1
- package/dist/codegen/cli.js +41 -4
- package/dist/codegen/cli.js.map +1 -1
- package/dist/codegen/index.cjs +0 -1
- package/dist/codegen/index.d.cts +1 -1
- package/dist/codegen/index.d.ts +1 -1
- package/dist/codegen/index.js +0 -1
- package/dist/connect.iife.global.js +34 -34
- package/dist/{detect-DZMJsyvZ.d.cts → detect-DVGaL2bH.d.cts} +39 -33
- package/dist/{detect-DBwc8a21.d.ts → detect-DVGaL2bH.d.ts} +39 -33
- package/dist/host/index.cjs +17 -18
- package/dist/host/index.d.cts +11 -27
- package/dist/host/index.d.ts +11 -27
- package/dist/host/index.js +2 -3
- package/dist/index.cjs +30 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +72 -26
- package/dist/index.d.ts +72 -26
- package/dist/index.js +8 -9
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +9 -10
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +36 -8
- package/dist/react/index.d.ts +36 -8
- package/dist/react/index.js +3 -4
- package/dist/react/index.js.map +1 -1
- package/dist/schema-reader-776246MJ.js +3 -0
- package/dist/{schema-reader-GM4A4L44.js.map → schema-reader-776246MJ.js.map} +1 -1
- package/dist/{schema-reader-MWBRQ2TQ.cjs → schema-reader-B6LTGBMJ.cjs} +2 -3
- package/dist/{schema-reader-MWBRQ2TQ.cjs.map → schema-reader-B6LTGBMJ.cjs.map} +1 -1
- package/dist/{server-LR6T6C44.cjs → server-BR5MNFOB.cjs} +13 -14
- package/dist/server-BR5MNFOB.cjs.map +1 -0
- package/dist/{server-UHPEE55X.js → server-OOEEWAEG.js} +13 -14
- package/dist/server-OOEEWAEG.js.map +1 -0
- package/dist/synapse-runtime.iife.global.js +34 -34
- package/dist/synapse-ui.iife.global.js +4 -4
- package/dist/type-generator-MZ4X4DE5.js +3 -0
- package/dist/{type-generator-ZYSVFK3X.js.map → type-generator-MZ4X4DE5.js.map} +1 -1
- package/dist/{type-generator-YTPFWLVG.cjs → type-generator-UA3L4OIA.cjs} +2 -3
- package/dist/{type-generator-YTPFWLVG.cjs.map → type-generator-UA3L4OIA.cjs.map} +1 -1
- package/dist/{types-CG08aO82.d.cts → types-BxPfGHKO.d.cts} +35 -43
- package/dist/{types-CG08aO82.d.ts → types-BxPfGHKO.d.ts} +35 -43
- package/dist/ui/base.cjs +0 -1
- package/dist/ui/base.cjs.map +1 -1
- package/dist/ui/base.js +0 -1
- package/dist/ui/base.js.map +1 -1
- package/dist/ui/index.cjs +0 -1
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.js +0 -1
- package/dist/ui/index.js.map +1 -1
- package/dist/vite/index.cjs +10 -10
- package/dist/vite/index.cjs.map +1 -1
- package/dist/vite/index.js +6 -6
- package/dist/vite/index.js.map +1 -1
- package/dist/{writer-HDRCQSX2.cjs → writer-NDK4U6C5.cjs} +3 -3
- package/dist/{writer-HDRCQSX2.cjs.map → writer-NDK4U6C5.cjs.map} +1 -1
- package/dist/{writer-QNDPMEYD.js → writer-ZNBXYUYC.js} +3 -3
- package/dist/{writer-QNDPMEYD.js.map → writer-ZNBXYUYC.js.map} +1 -1
- package/package.json +6 -3
- package/dist/chunk-54W6IAHM.js +0 -24
- package/dist/chunk-54W6IAHM.js.map +0 -1
- package/dist/chunk-DRLVEHCD.js.map +0 -1
- package/dist/chunk-NP7ROSH2.cjs.map +0 -1
- package/dist/chunk-OYLZ5OCK.js.map +0 -1
- package/dist/chunk-P5DBJFSQ.js +0 -8459
- package/dist/chunk-P5DBJFSQ.js.map +0 -1
- package/dist/chunk-PZ5AY32C.js +0 -9
- package/dist/chunk-PZ5AY32C.js.map +0 -1
- package/dist/chunk-Q7SFCCGT.cjs +0 -11
- package/dist/chunk-Q7SFCCGT.cjs.map +0 -1
- package/dist/chunk-QXDCA7QW.cjs +0 -8466
- package/dist/chunk-QXDCA7QW.cjs.map +0 -1
- package/dist/chunk-RU64F5RS.cjs.map +0 -1
- package/dist/chunk-SZWHFTXV.cjs.map +0 -1
- package/dist/schema-reader-GM4A4L44.js +0 -4
- package/dist/server-LR6T6C44.cjs.map +0 -1
- package/dist/server-UHPEE55X.js.map +0 -1
- package/dist/type-generator-ZYSVFK3X.js +0 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/check/profiles.ts","../src/check/index.ts"],"names":["RESOURCE_MIME_TYPE","Client","EXTENSION_ID","StreamableHTTPClientTransport","ResultSchema","ListToolsResultSchema","extractWWWAuthenticateParams","discoverOAuthProtectedResourceMetadata","discoverAuthorizationServerMetadata","RESOURCE_URI_META_KEY"],"mappings":"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","file":"check-VK4SOAUU.cjs","sourcesContent":["/**\n * Store profiles for `synapse check`: which checks each host applies, and how\n * hard. A check a profile does not list is not run for that target.\n *\n * `error` fails the run. `warn` is reported and does not: it marks a\n * requirement the host is documented to have but is not known to enforce, so a\n * failure is a risk rather than a certain break.\n */\n\nexport type CheckId =\n | \"extension-declared\"\n | \"ui-resource-mime\"\n | \"tool-resource-uri\"\n | \"tool-ui-meta\"\n | \"resource-csp\"\n | \"resource-openai-csp\"\n | \"resource-data-fonts\"\n | \"resource-openai-data-fonts\"\n | \"auth-challenge\"\n | \"auth-resource-metadata\"\n | \"auth-issuer\"\n | \"tool-security-schemes\";\n\nexport type Severity = \"error\" | \"warn\";\n\nexport interface ProfileRule {\n severity: Severity;\n /** The host requirement behind the rule, printed when the check fails. */\n why: string;\n}\n\nexport interface Profile {\n name: TargetName;\n description: string;\n rules: Partial<Record<CheckId, ProfileRule>>;\n}\n\nexport type TargetName = \"nimblebrain\" | \"claude\" | \"chatgpt\";\n\nconst SPEC_MIME = \"UI resources are served as text/html;profile=mcp-app.\";\nconst RESOLVES = \"A tool's ui.resourceUri must name a ui:// resource the server serves.\";\nconst UI_META =\n \"ui.visibility is a non-empty subset of model/app; csp and permissions belong on the resource, not the tool.\";\nconst EXTENSION = \"A client uses MCP Apps only when both sides declare io.modelcontextprotocol/ui.\";\nconst CHALLENGE = \"Sign-in starts from a 401 whose WWW-Authenticate carries resource_metadata.\";\nconst PRM_RESOURCE =\n \"The protected-resource metadata's resource must equal the connector URL exactly.\";\nconst ISSUER =\n \"The authorization server's metadata issuer must equal the advertised authorization server exactly (RFC 8414).\";\nconst SPEC_CSP =\n \"ui.csp is the frame's security policy for Claude and the NimbleBrain host, and OpenAI documents it as generally preferred for new UI; measured 2026-09-17 in ChatGPT developer mode, a resource carrying it alone got no policy.\";\n\nexport const PROFILES: Record<TargetName, Profile> = {\n nimblebrain: {\n name: \"nimblebrain\",\n description: \"The NimbleBrain host.\",\n rules: {\n \"ui-resource-mime\": { severity: \"error\", why: SPEC_MIME },\n \"tool-resource-uri\": { severity: \"error\", why: RESOLVES },\n \"tool-ui-meta\": { severity: \"error\", why: UI_META },\n // The host resolves an app by its ui:// scheme and does not gate on the\n // declaration, so a missing one is a portability risk, not a break.\n \"extension-declared\": { severity: \"warn\", why: EXTENSION },\n // Only reported when the server challenges at all.\n \"auth-challenge\": { severity: \"warn\", why: CHALLENGE },\n \"auth-resource-metadata\": { severity: \"warn\", why: PRM_RESOURCE },\n \"auth-issuer\": { severity: \"warn\", why: ISSUER },\n },\n },\n claude: {\n name: \"claude\",\n description: \"claude.ai and Claude Desktop.\",\n rules: {\n \"ui-resource-mime\": { severity: \"error\", why: SPEC_MIME },\n \"tool-resource-uri\": { severity: \"error\", why: RESOLVES },\n \"tool-ui-meta\": { severity: \"error\", why: UI_META },\n \"extension-declared\": { severity: \"error\", why: EXTENSION },\n \"resource-csp\": {\n severity: \"warn\",\n why: \"Claude builds the frame's security policy from ui.csp; an undeclared origin is blocked.\",\n },\n \"resource-data-fonts\": {\n severity: \"error\",\n why: \"Claude's default security policy blocks data: fonts unless the resource declares them.\",\n },\n \"auth-challenge\": { severity: \"error\", why: CHALLENGE },\n \"auth-resource-metadata\": { severity: \"error\", why: PRM_RESOURCE },\n // Claude has been observed to accept an issuer that differs by a trailing\n // slash, so this is a correctness warning for Claude rather than a break.\n \"auth-issuer\": { severity: \"warn\", why: ISSUER },\n },\n },\n chatgpt: {\n name: \"chatgpt\",\n description: \"ChatGPT apps.\",\n rules: {\n \"ui-resource-mime\": { severity: \"error\", why: SPEC_MIME },\n \"tool-resource-uri\": { severity: \"error\", why: RESOLVES },\n \"tool-ui-meta\": { severity: \"error\", why: UI_META },\n \"extension-declared\": { severity: \"error\", why: EXTENSION },\n // A requirement the vendor documents and the host was not observed to\n // enforce is what `warn` is for. openai/widgetCSP is what was measured.\n \"resource-csp\": { severity: \"warn\", why: SPEC_CSP },\n \"resource-openai-csp\": {\n severity: \"error\",\n why: \"ChatGPT reads the frame's security policy from openai/widgetCSP (snake_case origin lists); measured 2026-09-17 in developer mode, a resource without it got no policy on the frame at all. OpenAI documents the key as a legacy compatibility surface.\",\n },\n \"resource-openai-data-fonts\": {\n severity: \"warn\",\n why: \"A data: font is blocked by a security policy that does not declare it.\",\n },\n \"auth-challenge\": { severity: \"error\", why: CHALLENGE },\n \"auth-resource-metadata\": { severity: \"error\", why: PRM_RESOURCE },\n \"auth-issuer\": { severity: \"error\", why: ISSUER },\n \"tool-security-schemes\": {\n severity: \"error\",\n why: \"ChatGPT prompts for sign-in mid-conversation only for tools that declare securitySchemes.\",\n },\n },\n },\n};\n\nexport function isTargetName(value: string): value is TargetName {\n return Object.hasOwn(PROFILES, value);\n}\n","/**\n * `synapse check` — verify, from outside, what a host sees of a running MCP\n * server: the UI resources and their metadata, the MCP Apps extension\n * declaration, and the OAuth discovery surface a host signs in through.\n *\n * Every check runs once against the server; each target's profile then decides\n * which results count and how hard (see `./profiles.ts`).\n */\n\nimport type {\n McpUiClientCapabilities,\n McpUiResourceMeta,\n McpUiToolMeta,\n} from \"@modelcontextprotocol/ext-apps\";\nimport {\n EXTENSION_ID,\n RESOURCE_MIME_TYPE,\n RESOURCE_URI_META_KEY,\n} from \"@modelcontextprotocol/ext-apps/server\";\nimport {\n discoverAuthorizationServerMetadata,\n discoverOAuthProtectedResourceMetadata,\n extractWWWAuthenticateParams,\n} from \"@modelcontextprotocol/sdk/client/auth.js\";\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport type {\n ReadResourceResult,\n Resource,\n ServerCapabilities,\n Tool,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { ListToolsResultSchema, ResultSchema } from \"@modelcontextprotocol/sdk/types.js\";\nimport { type CheckId, PROFILES, type Severity, type TargetName } from \"./profiles.js\";\n\nexport { type CheckId, isTargetName, PROFILES, type Profile, type TargetName } from \"./profiles.js\";\n\nexport type CheckStatus = \"pass\" | \"fail\" | \"skip\";\n\nexport interface CheckResult {\n id: CheckId;\n status: CheckStatus;\n detail: string;\n}\n\nexport interface TargetReport {\n target: TargetName;\n results: Array<CheckResult & { severity: Severity; why: string }>;\n /** True when any `error`-severity check failed. */\n failed: boolean;\n}\n\nexport interface CheckOptions {\n /** Bearer token for a server that requires auth. Without one, checks that need a session are skipped. */\n token?: string;\n}\n\nconst UI_SCHEME = \"ui://\";\nconst VISIBILITY = new Set([\"model\", \"app\"]);\n\ntype ResourceContents = ReadResourceResult[\"contents\"][number];\n\ninterface Session {\n capabilities: ServerCapabilities | undefined;\n tools: Tool[];\n resources: Resource[];\n reads: Map<string, ResourceContents[] | Error>;\n}\n\n/** Run every check against `url` once. */\nexport async function runChecks(url: string, options: CheckOptions = {}): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n const add = (id: CheckId, status: CheckStatus, detail: string) =>\n results.push({ id, status, detail });\n\n // Connect without credentials first: the response to that is what a host\n // sees before sign-in, and it decides whether the server requires auth.\n let challenge: Response | undefined;\n let session: Session | undefined;\n let connectError: unknown;\n try {\n session = await openSession(url, undefined, (res) => {\n if (res.status === 401) challenge ??= res;\n });\n } catch (err) {\n connectError = err;\n }\n\n const authRequired = challenge !== undefined;\n if (authRequired && options.token) {\n try {\n session = await openSession(url, options.token);\n connectError = undefined;\n } catch (err) {\n connectError = err;\n }\n }\n\n // A server that cannot be reached is not a server that passes.\n if (!session && (!authRequired || options.token)) {\n throw new Error(\n `could not connect to ${url}${authRequired ? \" with the given token\" : \"\"}: ${message(connectError)}`,\n );\n }\n\n await checkAuth(url, challenge, add);\n\n if (!session) {\n for (const id of SESSION_CHECKS) {\n add(id, \"skip\", \"the server requires auth; pass --token to run it\");\n }\n return results;\n }\n\n checkSession(session, authRequired, add);\n return results;\n}\n\n/** Apply each target's profile to one set of results. */\nexport function applyProfiles(results: CheckResult[], targets: TargetName[]): TargetReport[] {\n return targets.map((target) => {\n const rules = PROFILES[target].rules;\n const scored = results.flatMap((r) => {\n const rule = rules[r.id];\n return rule ? [{ ...r, severity: rule.severity, why: rule.why }] : [];\n });\n return {\n target,\n results: scored,\n failed: scored.some((r) => r.status === \"fail\" && r.severity === \"error\"),\n };\n });\n}\n\n/** One line per check, grouped by target. */\nexport function formatReport(url: string, reports: TargetReport[]): string {\n const width = Math.max(...reports.flatMap((r) => r.results.map((c) => c.id.length)), 0);\n const lines = [`synapse check ${url}`];\n for (const report of reports) {\n lines.push(\"\", `${report.target}: ${report.failed ? \"FAIL\" : \"ok\"}`);\n for (const r of report.results) {\n const label =\n r.status === \"fail\" ? (r.severity === \"error\" ? \"FAIL\" : \"WARN\") : r.status.toUpperCase();\n lines.push(` ${label.padEnd(4)} ${r.id.padEnd(width)} ${r.detail}`);\n if (r.status === \"fail\") lines.push(` ${\"\".padEnd(width)} ${r.why}`);\n }\n }\n return lines.join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// session\n// ---------------------------------------------------------------------------\n\nconst SESSION_CHECKS: CheckId[] = [\n \"extension-declared\",\n \"ui-resource-mime\",\n \"tool-resource-uri\",\n \"tool-ui-meta\",\n \"resource-csp\",\n \"resource-openai-csp\",\n \"resource-data-fonts\",\n \"resource-openai-data-fonts\",\n \"tool-security-schemes\",\n];\n\nasync function openSession(\n url: string,\n token: string | undefined,\n onResponse?: (res: Response) => void,\n): Promise<Session> {\n // Declare MCP Apps support, so a server that gates its UI on the client's\n // capability shows the UI a host would see.\n const ui: McpUiClientCapabilities = { mimeTypes: [RESOURCE_MIME_TYPE] };\n const client = new Client(\n { name: \"synapse-check\", version: \"1\" },\n { capabilities: { extensions: { [EXTENSION_ID]: ui } } },\n );\n const transport = new StreamableHTTPClientTransport(new URL(url), {\n requestInit: token ? { headers: { Authorization: `Bearer ${token}` } } : undefined,\n fetch: async (input, init) => {\n const res = await fetch(input, init);\n onResponse?.(res);\n return res;\n },\n });\n await client.connect(transport);\n try {\n const capabilities = client.getServerCapabilities();\n const tools: Tool[] = [];\n const resources: Resource[] = [];\n let cursor: string | undefined;\n if (capabilities?.tools) {\n do {\n // Requested raw rather than through `listTools()`: the SDK's tool schema\n // strips fields it does not model, and ChatGPT documents `securitySchemes`\n // at the tool's top level as well as in `_meta`. The one field is copied\n // back onto each parsed tool so `hasSecuritySchemes` can see either place.\n const raw = await client.request(\n { method: \"tools/list\", params: cursor ? { cursor } : {} },\n ResultSchema,\n );\n const page = ListToolsResultSchema.parse(raw);\n const rawTools = (raw as { tools?: Array<Record<string, unknown>> }).tools ?? [];\n page.tools.forEach((tool, i) => {\n const schemes = rawTools[i]?.securitySchemes;\n if (schemes !== undefined) (tool as Record<string, unknown>).securitySchemes = schemes;\n });\n tools.push(...page.tools);\n cursor = page.nextCursor;\n } while (cursor);\n }\n if (capabilities?.resources) {\n do {\n const page = await client.listResources({ cursor });\n resources.push(...page.resources);\n cursor = page.nextCursor;\n } while (cursor);\n }\n\n const uris = new Set(resources.map((r) => r.uri).filter((u) => u.startsWith(UI_SCHEME)));\n for (const tool of tools) {\n const uri = toolUi(tool)?.resourceUri;\n if (typeof uri === \"string\") uris.add(uri);\n }\n const reads = new Map<string, ResourceContents[] | Error>();\n for (const uri of uris) {\n try {\n reads.set(uri, (await client.readResource({ uri })).contents);\n } catch (err) {\n reads.set(uri, err instanceof Error ? err : new Error(String(err)));\n }\n }\n return { capabilities, tools, resources, reads };\n } finally {\n await client.close();\n }\n}\n\nfunction checkSession(\n s: Session,\n authRequired: boolean,\n add: (id: CheckId, status: CheckStatus, detail: string) => void,\n): void {\n const boundTools = s.tools.filter((t) => toolUi(t)?.resourceUri !== undefined);\n const uiResources = s.resources.filter((r) => r.uri.startsWith(UI_SCHEME));\n const hasUi = boundTools.length > 0 || uiResources.length > 0 || s.tools.some(legacyBinding);\n\n if (!hasUi) {\n for (const id of SESSION_CHECKS) {\n if (id !== \"tool-security-schemes\") add(id, \"skip\", \"the server exposes no UI\");\n }\n } else {\n // extension-declared\n const declared = s.capabilities?.extensions?.[EXTENSION_ID] !== undefined;\n add(\n \"extension-declared\",\n declared ? \"pass\" : \"fail\",\n declared\n ? `${EXTENSION_ID} is declared`\n : `the server does not declare ${EXTENSION_ID} in capabilities.extensions`,\n );\n\n // ui-resource-mime: every ui:// resource, as listed and as read.\n const wrongMime: string[] = [];\n for (const r of uiResources) {\n if (r.mimeType !== undefined && r.mimeType !== RESOURCE_MIME_TYPE) {\n wrongMime.push(`${r.uri} is listed as ${r.mimeType}`);\n }\n }\n for (const [uri, contents] of s.reads) {\n if (contents instanceof Error) continue;\n for (const c of contents) {\n if (c.mimeType !== RESOURCE_MIME_TYPE) {\n wrongMime.push(`${uri} is served as ${c.mimeType ?? \"no MIME type\"}`);\n }\n }\n }\n add(\n \"ui-resource-mime\",\n wrongMime.length ? \"fail\" : \"pass\",\n wrongMime.length\n ? `${wrongMime.join(\"; \")}; expected ${RESOURCE_MIME_TYPE}`\n : `every ui:// resource is ${RESOURCE_MIME_TYPE}`,\n );\n\n // tool-resource-uri\n const unresolved: string[] = [];\n for (const tool of s.tools) {\n const uri = toolUi(tool)?.resourceUri;\n if (uri === undefined) {\n if (legacyBinding(tool)) {\n unresolved.push(`${tool.name} binds its UI only through the deprecated flat key`);\n }\n continue;\n }\n if (typeof uri !== \"string\" || !uri.startsWith(UI_SCHEME)) {\n unresolved.push(`${tool.name}: ui.resourceUri ${JSON.stringify(uri)} is not a ui:// URI`);\n continue;\n }\n const read = s.reads.get(uri);\n if (read instanceof Error || !read?.length) {\n unresolved.push(\n `${tool.name}: ${uri} cannot be read${read instanceof Error ? ` (${read.message})` : \"\"}`,\n );\n }\n }\n if (boundTools.length === 0 && unresolved.length === 0) {\n unresolved.push(\"no tool binds a UI through ui.resourceUri\");\n }\n add(\n \"tool-resource-uri\",\n unresolved.length ? \"fail\" : \"pass\",\n unresolved.length\n ? unresolved.join(\"; \")\n : `${boundTools.length} tool(s) bind a UI that resolves`,\n );\n\n // tool-ui-meta\n const badMeta: string[] = [];\n for (const tool of s.tools) {\n const ui = toolUi(tool);\n if (!ui) continue;\n const vis = ui.visibility as unknown;\n if (\n vis !== undefined &&\n (!Array.isArray(vis) || vis.length === 0 || !vis.every((v) => VISIBILITY.has(v)))\n ) {\n badMeta.push(`${tool.name}: ui.visibility ${JSON.stringify(vis)}`);\n }\n for (const key of [\"csp\", \"permissions\"] as const) {\n if ((ui as Record<string, unknown>)[key] !== undefined) {\n badMeta.push(`${tool.name}: ui.${key} is on the tool, where hosts ignore it`);\n }\n }\n }\n add(\n \"tool-ui-meta\",\n badMeta.length ? \"fail\" : \"pass\",\n badMeta.length ? badMeta.join(\"; \") : \"tool ui metadata is well-formed\",\n );\n\n // The frame's security policy, in each dialect a host reads, per UI resource.\n const noCsp: string[] = [];\n const noOpenAiCsp: string[] = [];\n const dataFonts: string[] = [];\n const openAiDataFonts: string[] = [];\n for (const [uri, contents] of s.reads) {\n if (contents instanceof Error) continue;\n for (const c of contents) {\n const listed = s.resources.find((r) => r.uri === uri);\n // Hosts read the content item's metadata, and fall back to the list entry.\n const ui = (resourceUi(c) ?? resourceUi(listed)) as McpUiResourceMeta | undefined;\n const csp = ui?.csp as unknown;\n if (csp === undefined) {\n noCsp.push(`${uri} declares no ui.csp`);\n } else if (!isOriginLists(csp)) {\n noCsp.push(`${uri}: ui.csp is not a map of origin lists`);\n }\n const openAi = openAiCsp(c) ?? openAiCsp(listed);\n if (openAi === undefined) {\n noOpenAiCsp.push(`${uri} declares no ${OPENAI_CSP_KEY}`);\n } else if (!isOriginLists(openAi)) {\n noOpenAiCsp.push(`${uri}: ${OPENAI_CSP_KEY} is not a map of origin lists`);\n } else {\n const camel = SPEC_CSP_KEYS.filter((k) => k in openAi);\n if (camel.length) {\n noOpenAiCsp.push(\n `${uri}: ${OPENAI_CSP_KEY} names ${camel.join(\", \")}, which ChatGPT does not read`,\n );\n }\n }\n const html = \"text\" in c ? c.text : Buffer.from(c.blob, \"base64\").toString(\"utf-8\");\n if (hasDataFont(html)) {\n if (!declaresData(csp, \"resourceDomains\")) {\n dataFonts.push(`${uri} loads a data: font, and ui.csp.resourceDomains omits data:`);\n }\n if (!declaresData(openAi, \"resource_domains\")) {\n openAiDataFonts.push(\n `${uri} loads a data: font, and ${OPENAI_CSP_KEY}.resource_domains omits data:`,\n );\n }\n }\n }\n }\n add(\n \"resource-csp\",\n noCsp.length ? \"fail\" : \"pass\",\n noCsp.length ? noCsp.join(\"; \") : \"every UI resource declares ui.csp\",\n );\n add(\n \"resource-openai-csp\",\n noOpenAiCsp.length ? \"fail\" : \"pass\",\n noOpenAiCsp.length ? noOpenAiCsp.join(\"; \") : `every UI resource declares ${OPENAI_CSP_KEY}`,\n );\n add(\n \"resource-data-fonts\",\n dataFonts.length ? \"fail\" : \"pass\",\n dataFonts.length ? dataFonts.join(\"; \") : \"no data: font ui.csp omits\",\n );\n add(\n \"resource-openai-data-fonts\",\n openAiDataFonts.length ? \"fail\" : \"pass\",\n openAiDataFonts.length ? openAiDataFonts.join(\"; \") : `no data: font ${OPENAI_CSP_KEY} omits`,\n );\n }\n\n // tool-security-schemes: a question about auth, not about UI.\n if (!authRequired) {\n add(\"tool-security-schemes\", \"skip\", \"the server does not require auth\");\n } else {\n const missing = s.tools.filter((t) => !hasSecuritySchemes(t)).map((t) => t.name);\n add(\n \"tool-security-schemes\",\n missing.length ? \"fail\" : \"pass\",\n missing.length\n ? `no securitySchemes on: ${missing.join(\", \")}`\n : \"every tool declares securitySchemes\",\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n// auth\n// ---------------------------------------------------------------------------\n\nasync function checkAuth(\n url: string,\n challenge: Response | undefined,\n add: (id: CheckId, status: CheckStatus, detail: string) => void,\n): Promise<void> {\n if (!challenge) {\n const reason = \"the server answered without a 401 challenge\";\n add(\"auth-challenge\", \"skip\", reason);\n add(\"auth-resource-metadata\", \"skip\", reason);\n add(\"auth-issuer\", \"skip\", reason);\n return;\n }\n\n const { resourceMetadataUrl } = extractWWWAuthenticateParams(challenge);\n add(\n \"auth-challenge\",\n resourceMetadataUrl ? \"pass\" : \"fail\",\n resourceMetadataUrl\n ? `401 names resource_metadata ${resourceMetadataUrl.href}`\n : `401 WWW-Authenticate carries no resource_metadata (${JSON.stringify(challenge.headers.get(\"www-authenticate\"))})`,\n );\n\n let prm: Awaited<ReturnType<typeof discoverOAuthProtectedResourceMetadata>>;\n try {\n // Without resource_metadata, a client falls back to the well-known path,\n // so the rest of the surface is still worth reporting.\n prm = await discoverOAuthProtectedResourceMetadata(url, { resourceMetadataUrl });\n } catch (err) {\n add(\n \"auth-resource-metadata\",\n \"fail\",\n `protected-resource metadata unreadable: ${message(err)}`,\n );\n add(\"auth-issuer\", \"skip\", \"no protected-resource metadata\");\n return;\n }\n add(\n \"auth-resource-metadata\",\n prm.resource === url ? \"pass\" : \"fail\",\n prm.resource === url\n ? `resource equals ${url}`\n : `resource is ${JSON.stringify(prm.resource)}, not ${JSON.stringify(url)}`,\n );\n\n const advertised = prm.authorization_servers?.[0];\n if (!advertised) {\n add(\"auth-issuer\", \"fail\", \"protected-resource metadata lists no authorization_servers\");\n return;\n }\n try {\n const metadata = await discoverAuthorizationServerMetadata(advertised);\n if (!metadata) {\n add(\"auth-issuer\", \"fail\", `no authorization server metadata found for ${advertised}`);\n } else if (metadata.issuer !== advertised) {\n add(\n \"auth-issuer\",\n \"fail\",\n `issuer is ${JSON.stringify(metadata.issuer)}, advertised as ${JSON.stringify(advertised)}`,\n );\n } else {\n add(\"auth-issuer\", \"pass\", `issuer equals ${advertised}`);\n }\n } catch (err) {\n add(\"auth-issuer\", \"fail\", `authorization server metadata unreadable: ${message(err)}`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// helpers\n// ---------------------------------------------------------------------------\n\nfunction toolUi(tool: Tool): McpUiToolMeta | undefined {\n const ui = tool._meta?.ui;\n return ui && typeof ui === \"object\" ? (ui as McpUiToolMeta) : undefined;\n}\n\nfunction legacyBinding(tool: Tool): boolean {\n return (\n tool._meta?.[RESOURCE_URI_META_KEY] !== undefined && toolUi(tool)?.resourceUri === undefined\n );\n}\n\nfunction resourceUi(item: { _meta?: Record<string, unknown> } | undefined): unknown {\n const ui = item?._meta?.ui;\n return ui && typeof ui === \"object\" ? ui : undefined;\n}\n\n/**\n * ChatGPT's dialect of the frame's security policy. It is a sibling of `ui`\n * in the resource's `_meta`, not a key inside it, and its origin lists are\n * spelled `connect_domains`/`resource_domains`. OpenAI documents it as a legacy\n * compatibility key and `ui.csp` as generally preferred for new UI; measured\n * 2026-09-17 in developer mode, ChatGPT applied no policy from `ui.csp` alone.\n * So the two are checked separately, and a target's profile names the one its\n * host was observed to read.\n */\nconst OPENAI_CSP_KEY = \"openai/widgetCSP\";\n\n/** The spec's spellings, which under `openai/widgetCSP` name origins nothing reads. */\nconst SPEC_CSP_KEYS = [\"connectDomains\", \"resourceDomains\"];\n\nfunction openAiCsp(item: { _meta?: Record<string, unknown> } | undefined): unknown {\n return item?._meta?.[OPENAI_CSP_KEY];\n}\n\n/** The `{ name: [origin, ...] }` shape both CSP dialects have. */\nfunction isOriginLists(value: unknown): value is Record<string, string[]> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n Object.values(value).every((v) => Array.isArray(v) && v.every((o) => typeof o === \"string\"))\n );\n}\n\n/** Whether `csp` allows `data:` under the key naming static assets in its dialect. */\nfunction declaresData(csp: unknown, key: \"resourceDomains\" | \"resource_domains\"): boolean {\n return isOriginLists(csp) && (csp[key] ?? []).includes(\"data:\");\n}\n\nfunction hasSecuritySchemes(tool: Tool): boolean {\n const schemes = tool._meta?.securitySchemes ?? (tool as Record<string, unknown>).securitySchemes;\n return Array.isArray(schemes) && schemes.length > 0;\n}\n\nconst DATA_FONT_MIME = /data:(?:font\\/|application\\/(?:x-)?font|application\\/vnd\\.ms-fontobject)/i;\nconst FONT_FACE_DATA_URL = /@font-face\\s*{[^}]*url\\(\\s*[\"']?data:/i;\n\nfunction hasDataFont(html: string): boolean {\n return DATA_FONT_MIME.test(html) || FONT_FACE_DATA_URL.test(html);\n}\n\nfunction message(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n"]}
|
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkYSL7KJNU_cjs = require('./chunk-YSL7KJNU.cjs');
|
|
4
4
|
|
|
5
5
|
// src/host/theme.ts
|
|
6
6
|
function applyHostTheme(theme) {
|
|
7
7
|
if (typeof document !== "undefined") {
|
|
8
8
|
document.documentElement.setAttribute("data-theme", theme.mode);
|
|
9
9
|
}
|
|
10
|
-
|
|
10
|
+
chunkYSL7KJNU_cjs.applyTheme(theme.mode, theme.tokens);
|
|
11
|
+
}
|
|
12
|
+
var HOST_FONTS_STYLE_ID = "__mcp-host-fonts";
|
|
13
|
+
function injectHostFonts(css) {
|
|
14
|
+
if (typeof document === "undefined") return;
|
|
15
|
+
if (document.getElementById(HOST_FONTS_STYLE_ID)) return;
|
|
16
|
+
const style = document.createElement("style");
|
|
17
|
+
style.id = HOST_FONTS_STYLE_ID;
|
|
18
|
+
style.textContent = css;
|
|
19
|
+
document.head.appendChild(style);
|
|
11
20
|
}
|
|
12
21
|
function preferredMode(win) {
|
|
13
22
|
try {
|
|
@@ -27,13 +36,27 @@ var HostUnsupportedError = class extends Error {
|
|
|
27
36
|
this.name = "HostUnsupportedError";
|
|
28
37
|
}
|
|
29
38
|
};
|
|
39
|
+
var ToolCallError = class extends Error {
|
|
40
|
+
result;
|
|
41
|
+
constructor(name, result) {
|
|
42
|
+
super(toolErrorText(result) ?? `tool "${name}" returned an error`);
|
|
43
|
+
this.name = "ToolCallError";
|
|
44
|
+
this.result = result;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
function toolErrorText(result) {
|
|
48
|
+
const content = result?.content;
|
|
49
|
+
if (!Array.isArray(content)) return void 0;
|
|
50
|
+
for (const block of content) {
|
|
51
|
+
const b = block;
|
|
52
|
+
if (b?.type === "text" && typeof b.text === "string" && b.text !== "") return b.text;
|
|
53
|
+
}
|
|
54
|
+
return void 0;
|
|
55
|
+
}
|
|
56
|
+
function isToolError(result) {
|
|
57
|
+
return result != null && typeof result === "object" && result.isError === true;
|
|
58
|
+
}
|
|
30
59
|
var SYNAPSE_DATA_ELEMENT_ID = "synapse-ui-data";
|
|
31
|
-
var MCPUI_READY = "ui-lifecycle-iframe-ready";
|
|
32
|
-
var MCPUI_RENDER_DATA = "ui-lifecycle-iframe-render-data";
|
|
33
|
-
var MCPUI_SIZE_CHANGE = "ui-size-change";
|
|
34
|
-
var MCPUI_LINK = "link";
|
|
35
|
-
var MCPUI_PROMPT = "prompt";
|
|
36
|
-
var OPENAI_SET_GLOBALS = "openai:set_globals";
|
|
37
60
|
var MCPAPP_PROTOCOL_VERSION = "2026-01-26";
|
|
38
61
|
var MCPAPP_INITIALIZE = "ui/initialize";
|
|
39
62
|
var MCPAPP_INITIALIZED = "ui/notifications/initialized";
|
|
@@ -45,84 +68,6 @@ var MCPAPP_MESSAGE = "ui/message";
|
|
|
45
68
|
var MCPAPP_TEARDOWN = "ui/resource-teardown";
|
|
46
69
|
var MCP_TOOLS_CALL = "tools/call";
|
|
47
70
|
|
|
48
|
-
// src/host/adapters/chatgpt.ts
|
|
49
|
-
function createChatGPTAdapter(win, _options) {
|
|
50
|
-
const openai = () => win.openai;
|
|
51
|
-
let currentData = openai()?.toolOutput ?? null;
|
|
52
|
-
let currentTheme = {
|
|
53
|
-
mode: coerceMode(openai()?.theme, "light"),
|
|
54
|
-
tokens: {}
|
|
55
|
-
};
|
|
56
|
-
const dataCbs = /* @__PURE__ */ new Set();
|
|
57
|
-
const themeCbs = /* @__PURE__ */ new Set();
|
|
58
|
-
let destroyed = false;
|
|
59
|
-
const onSetGlobals = (event) => {
|
|
60
|
-
if (destroyed) return;
|
|
61
|
-
const globals = event.detail?.globals;
|
|
62
|
-
if (!globals) return;
|
|
63
|
-
if ("toolOutput" in globals && globals.toolOutput != null) {
|
|
64
|
-
currentData = globals.toolOutput;
|
|
65
|
-
for (const cb of dataCbs) cb(currentData);
|
|
66
|
-
}
|
|
67
|
-
if ("theme" in globals && globals.theme != null) {
|
|
68
|
-
const mode = coerceMode(globals.theme, currentTheme.mode);
|
|
69
|
-
if (mode !== currentTheme.mode) {
|
|
70
|
-
currentTheme = { mode, tokens: {} };
|
|
71
|
-
for (const cb of themeCbs) cb(currentTheme);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
return {
|
|
76
|
-
host: "chatgpt",
|
|
77
|
-
getData: () => currentData,
|
|
78
|
-
onData(cb) {
|
|
79
|
-
dataCbs.add(cb);
|
|
80
|
-
return () => dataCbs.delete(cb);
|
|
81
|
-
},
|
|
82
|
-
getTheme: () => currentTheme,
|
|
83
|
-
onTheme(cb) {
|
|
84
|
-
themeCbs.add(cb);
|
|
85
|
-
return () => themeCbs.delete(cb);
|
|
86
|
-
},
|
|
87
|
-
async callTool(name, args) {
|
|
88
|
-
const call = openai()?.callTool;
|
|
89
|
-
if (!call) throw new HostUnsupportedError("callTool", "chatgpt");
|
|
90
|
-
return await call(name, args ?? {});
|
|
91
|
-
},
|
|
92
|
-
sendPrompt(text) {
|
|
93
|
-
const o = openai();
|
|
94
|
-
const send = o?.sendFollowUpMessage ?? o?.sendFollowupMessage;
|
|
95
|
-
send?.({ prompt: text });
|
|
96
|
-
},
|
|
97
|
-
openLink(url) {
|
|
98
|
-
const open = openai()?.openExternal;
|
|
99
|
-
if (open) open({ href: url });
|
|
100
|
-
else win.open(url, "_blank", "noopener,noreferrer");
|
|
101
|
-
},
|
|
102
|
-
resize() {
|
|
103
|
-
},
|
|
104
|
-
capabilities() {
|
|
105
|
-
const o = openai();
|
|
106
|
-
return {
|
|
107
|
-
pull: typeof o?.callTool === "function",
|
|
108
|
-
sendPrompt: typeof o?.sendFollowUpMessage === "function" || typeof o?.sendFollowupMessage === "function",
|
|
109
|
-
openLink: true
|
|
110
|
-
};
|
|
111
|
-
},
|
|
112
|
-
start() {
|
|
113
|
-
win.addEventListener(OPENAI_SET_GLOBALS, onSetGlobals, { passive: true });
|
|
114
|
-
currentData = openai()?.toolOutput ?? currentData;
|
|
115
|
-
},
|
|
116
|
-
destroy() {
|
|
117
|
-
if (destroyed) return;
|
|
118
|
-
destroyed = true;
|
|
119
|
-
win.removeEventListener(OPENAI_SET_GLOBALS, onSetGlobals);
|
|
120
|
-
dataCbs.clear();
|
|
121
|
-
themeCbs.clear();
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
|
|
126
71
|
// src/host/data.ts
|
|
127
72
|
function readInlineData(doc, elementId) {
|
|
128
73
|
if (!doc) return null;
|
|
@@ -136,15 +81,6 @@ function readInlineData(doc, elementId) {
|
|
|
136
81
|
return null;
|
|
137
82
|
}
|
|
138
83
|
}
|
|
139
|
-
function unwrapRenderData(payload) {
|
|
140
|
-
if (payload == null || typeof payload !== "object") return null;
|
|
141
|
-
const rec = payload;
|
|
142
|
-
const nested = rec.renderData;
|
|
143
|
-
const source = nested != null && typeof nested === "object" ? nested : rec;
|
|
144
|
-
if (source.toolOutput != null) return source.toolOutput;
|
|
145
|
-
if (source.structuredContent != null) return source.structuredContent;
|
|
146
|
-
return source;
|
|
147
|
-
}
|
|
148
84
|
|
|
149
85
|
// src/host/adapters/inline.ts
|
|
150
86
|
function createInlineAdapter(win, options) {
|
|
@@ -215,7 +151,7 @@ function createMcpAppsAdapter(win, options) {
|
|
|
215
151
|
const dataCbs = /* @__PURE__ */ new Set();
|
|
216
152
|
const themeCbs = /* @__PURE__ */ new Set();
|
|
217
153
|
let destroyed = false;
|
|
218
|
-
let
|
|
154
|
+
let initialized = false;
|
|
219
155
|
let nextId = 1;
|
|
220
156
|
const pending = /* @__PURE__ */ new Map();
|
|
221
157
|
let lastReportedHeight = -1;
|
|
@@ -225,10 +161,6 @@ function createMcpAppsAdapter(win, options) {
|
|
|
225
161
|
function post(message) {
|
|
226
162
|
parent().postMessage(message, "*");
|
|
227
163
|
}
|
|
228
|
-
function postLegacy(message) {
|
|
229
|
-
if (standardConfirmed) return;
|
|
230
|
-
post(message);
|
|
231
|
-
}
|
|
232
164
|
function notify(method, params) {
|
|
233
165
|
post({ jsonrpc: "2.0", method, params: params ?? {} });
|
|
234
166
|
}
|
|
@@ -250,7 +182,9 @@ function createMcpAppsAdapter(win, options) {
|
|
|
250
182
|
}
|
|
251
183
|
function applyHostContext(ctx) {
|
|
252
184
|
if (!ctx || typeof ctx !== "object") return;
|
|
253
|
-
|
|
185
|
+
const fontCss = chunkYSL7KJNU_cjs.extractHostFontCss(ctx);
|
|
186
|
+
if (fontCss !== void 0) injectHostFonts(fontCss);
|
|
187
|
+
let { mode, tokens } = currentTheme;
|
|
254
188
|
let changed = false;
|
|
255
189
|
if (ctx.theme != null) {
|
|
256
190
|
const next = coerceMode(ctx.theme, mode);
|
|
@@ -264,23 +198,17 @@ function createMcpAppsAdapter(win, options) {
|
|
|
264
198
|
tokens = { ...tokens, ...styles.variables };
|
|
265
199
|
changed = true;
|
|
266
200
|
}
|
|
267
|
-
const nextFaces = chunkSZWHFTXV_cjs.foldFontFaces(fontFaces, ctx);
|
|
268
|
-
if (chunkSZWHFTXV_cjs.fontFacesKey(nextFaces) !== chunkSZWHFTXV_cjs.fontFacesKey(fontFaces)) {
|
|
269
|
-
fontFaces = nextFaces;
|
|
270
|
-
changed = true;
|
|
271
|
-
}
|
|
272
201
|
if (changed) {
|
|
273
|
-
currentTheme = { mode, tokens
|
|
202
|
+
currentTheme = { mode, tokens };
|
|
274
203
|
for (const cb of themeCbs) cb(currentTheme);
|
|
275
204
|
}
|
|
276
205
|
}
|
|
277
206
|
function reportSize(height) {
|
|
278
|
-
if (destroyed) return;
|
|
207
|
+
if (destroyed || !initialized) return;
|
|
279
208
|
const h = typeof height === "number" ? height : Math.ceil(win.document.body.scrollHeight);
|
|
280
209
|
if (h === lastReportedHeight) return;
|
|
281
210
|
lastReportedHeight = h;
|
|
282
|
-
|
|
283
|
-
postLegacy({ type: MCPUI_SIZE_CHANGE, payload: { height: h } });
|
|
211
|
+
notify(MCPAPP_SIZE_CHANGED, { height: h });
|
|
284
212
|
}
|
|
285
213
|
function handleResponse(d) {
|
|
286
214
|
const id = Number(d.id);
|
|
@@ -298,7 +226,7 @@ function createMcpAppsAdapter(win, options) {
|
|
|
298
226
|
function handleNotification(method, params) {
|
|
299
227
|
if (method === MCPAPP_TOOL_RESULT) {
|
|
300
228
|
const structured = params.structuredContent;
|
|
301
|
-
emitData(structured != null ? structured :
|
|
229
|
+
emitData(structured != null ? structured : params);
|
|
302
230
|
} else if (method === MCPAPP_HOST_CONTEXT_CHANGED) {
|
|
303
231
|
applyHostContext(params);
|
|
304
232
|
}
|
|
@@ -308,22 +236,11 @@ function createMcpAppsAdapter(win, options) {
|
|
|
308
236
|
post({ jsonrpc: "2.0", id: d.id, result: {} });
|
|
309
237
|
}
|
|
310
238
|
}
|
|
311
|
-
function handleLegacy(d) {
|
|
312
|
-
if (d.type === MCPUI_RENDER_DATA || d.type === "renderData") {
|
|
313
|
-
const { theme, ...rest } = d.payload ?? {};
|
|
314
|
-
if (theme != null) applyHostContext({ theme });
|
|
315
|
-
if (Object.keys(rest).length > 0) emitData(unwrapRenderData(rest));
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
239
|
const onMessage = (event) => {
|
|
319
240
|
if (destroyed) return;
|
|
320
241
|
if (event.source && event.source !== parent()) return;
|
|
321
242
|
const d = event.data;
|
|
322
|
-
if (!d || typeof d !== "object") return;
|
|
323
|
-
if (d.jsonrpc !== "2.0") {
|
|
324
|
-
handleLegacy(d);
|
|
325
|
-
return;
|
|
326
|
-
}
|
|
243
|
+
if (!d || typeof d !== "object" || d.jsonrpc !== "2.0") return;
|
|
327
244
|
if (d.id != null && ("result" in d || "error" in d)) {
|
|
328
245
|
handleResponse(d);
|
|
329
246
|
} else if (typeof d.method === "string") {
|
|
@@ -340,7 +257,7 @@ function createMcpAppsAdapter(win, options) {
|
|
|
340
257
|
}
|
|
341
258
|
}
|
|
342
259
|
return {
|
|
343
|
-
host: "
|
|
260
|
+
host: "mcp-apps",
|
|
344
261
|
getData: () => currentData,
|
|
345
262
|
onData(cb) {
|
|
346
263
|
dataCbs.add(cb);
|
|
@@ -359,12 +276,10 @@ function createMcpAppsAdapter(win, options) {
|
|
|
359
276
|
() => {
|
|
360
277
|
}
|
|
361
278
|
);
|
|
362
|
-
postLegacy({ type: MCPUI_PROMPT, payload: { prompt: text } });
|
|
363
279
|
},
|
|
364
280
|
openLink(url) {
|
|
365
281
|
void request(MCPAPP_OPEN_LINK, { url }).catch(() => {
|
|
366
282
|
});
|
|
367
|
-
postLegacy({ type: MCPUI_LINK, payload: { url } });
|
|
368
283
|
},
|
|
369
284
|
resize(height) {
|
|
370
285
|
reportSize(height);
|
|
@@ -376,21 +291,18 @@ function createMcpAppsAdapter(win, options) {
|
|
|
376
291
|
win.addEventListener("message", onMessage);
|
|
377
292
|
currentData = readInlineData(win.document, dataElementId);
|
|
378
293
|
if (autoResize) setupResize();
|
|
379
|
-
post({ type: MCPUI_READY });
|
|
380
294
|
request(MCPAPP_INITIALIZE, {
|
|
381
295
|
appInfo: { name: options.name ?? "synapse-ui", version: options.version ?? "0.0.0" },
|
|
382
296
|
appCapabilities: { availableDisplayModes: ["inline"] },
|
|
383
297
|
protocolVersion: MCPAPP_PROTOCOL_VERSION
|
|
384
298
|
}).then((result) => {
|
|
385
299
|
if (destroyed) return;
|
|
386
|
-
standardConfirmed = true;
|
|
387
300
|
applyHostContext(result?.hostContext);
|
|
388
301
|
notify(MCPAPP_INITIALIZED, {});
|
|
389
|
-
|
|
302
|
+
initialized = true;
|
|
390
303
|
reportSize();
|
|
391
304
|
}).catch(() => {
|
|
392
305
|
});
|
|
393
|
-
reportSize();
|
|
394
306
|
},
|
|
395
307
|
destroy() {
|
|
396
308
|
if (destroyed) return;
|
|
@@ -413,24 +325,17 @@ function createMcpAppsAdapter(win, options) {
|
|
|
413
325
|
|
|
414
326
|
// src/host/detect.ts
|
|
415
327
|
function detectHostKind(win) {
|
|
416
|
-
if (win.openai != null) return "chatgpt";
|
|
417
328
|
try {
|
|
418
|
-
if (win.parent != null && win.parent !== win) return "
|
|
329
|
+
if (win.parent != null && win.parent !== win) return "mcp-apps";
|
|
419
330
|
} catch {
|
|
420
|
-
return "
|
|
331
|
+
return "mcp-apps";
|
|
421
332
|
}
|
|
422
333
|
return "generic";
|
|
423
334
|
}
|
|
424
335
|
function adapterForKind(kind, win, options) {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
case "claude":
|
|
429
|
-
case "nimblebrain":
|
|
430
|
-
return createMcpAppsAdapter(win, options);
|
|
431
|
-
default:
|
|
432
|
-
return createInlineAdapter(win, options);
|
|
433
|
-
}
|
|
336
|
+
if (kind === "mcp-apps") return createMcpAppsAdapter(win, options);
|
|
337
|
+
if (kind === "generic") return createInlineAdapter(win, options);
|
|
338
|
+
throw new TypeError(`unknown host "${String(kind)}": expected "mcp-apps" or "generic"`);
|
|
434
339
|
}
|
|
435
340
|
function selectAdapter(win, options) {
|
|
436
341
|
const kind = options.host ?? detectHostKind(win);
|
|
@@ -450,7 +355,13 @@ function connectUI(options = {}) {
|
|
|
450
355
|
onData: (cb) => adapter.onData(cb),
|
|
451
356
|
theme: () => adapter.getTheme(),
|
|
452
357
|
onTheme: (cb) => adapter.onTheme(cb),
|
|
453
|
-
|
|
358
|
+
// Decided here rather than per adapter: every host reports a failed or
|
|
359
|
+
// refused call inside the result, because that is how MCP defines one.
|
|
360
|
+
async callTool(name, args) {
|
|
361
|
+
const result = await adapter.callTool(name, args);
|
|
362
|
+
if (isToolError(result)) throw new ToolCallError(name, result);
|
|
363
|
+
return result;
|
|
364
|
+
},
|
|
454
365
|
sendPrompt: (text) => adapter.sendPrompt(text),
|
|
455
366
|
openLink: (url) => adapter.openLink(url),
|
|
456
367
|
resize: (height) => adapter.resize(height),
|
|
@@ -467,15 +378,15 @@ function connectUI(options = {}) {
|
|
|
467
378
|
|
|
468
379
|
exports.HostUnsupportedError = HostUnsupportedError;
|
|
469
380
|
exports.SYNAPSE_DATA_ELEMENT_ID = SYNAPSE_DATA_ELEMENT_ID;
|
|
381
|
+
exports.ToolCallError = ToolCallError;
|
|
470
382
|
exports.adapterForKind = adapterForKind;
|
|
471
383
|
exports.applyHostTheme = applyHostTheme;
|
|
472
384
|
exports.coerceMode = coerceMode;
|
|
473
385
|
exports.connectUI = connectUI;
|
|
474
|
-
exports.createChatGPTAdapter = createChatGPTAdapter;
|
|
475
386
|
exports.createInlineAdapter = createInlineAdapter;
|
|
476
387
|
exports.createMcpAppsAdapter = createMcpAppsAdapter;
|
|
477
388
|
exports.detectHostKind = detectHostKind;
|
|
478
389
|
exports.preferredMode = preferredMode;
|
|
479
390
|
exports.selectAdapter = selectAdapter;
|
|
480
|
-
//# sourceMappingURL=chunk-
|
|
481
|
-
//# sourceMappingURL=chunk-
|
|
391
|
+
//# sourceMappingURL=chunk-BNF352SA.cjs.map
|
|
392
|
+
//# sourceMappingURL=chunk-BNF352SA.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/host/theme.ts","../src/host/types.ts","../src/host/data.ts","../src/host/adapters/inline.ts","../src/host/adapters/mcpapps.ts","../src/host/detect.ts","../src/host/connect.ts"],"names":["applyTheme","extractHostFontCss"],"mappings":"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","file":"chunk-BNF352SA.cjs","sourcesContent":["import { applyTheme } from \"../theme-defaults.js\";\nimport type { SynapseUITheme } from \"./types.js\";\n\n/**\n * Apply a resolved theme to the DOM for the cross-host client.\n *\n * Two conventions coexist across Synapse components, so the client drives both:\n *\n * - `document.documentElement[data-theme=\"light\"|\"dark\"]` — how self-contained\n * HTML components (Bassethound's report) gate their `--var` palettes, and the\n * lever a host's light/dark signal actually flips.\n * - CSS custom properties via {@link applyTheme} — how the\n * `@nimblebrain/synapse/ui` token components consume theme, backed by the\n * SDK's neutral defaults so every referenced var resolves in both modes.\n *\n * Setting both means an app can use either convention (and a host that supplies\n * only a mode string still themes correctly). SSR-safe.\n *\n * Fonts travel separately, as the host's `@font-face` CSS: see\n * {@link injectHostFonts}.\n */\nexport function applyHostTheme(theme: SynapseUITheme): void {\n if (typeof document !== \"undefined\") {\n document.documentElement.setAttribute(\"data-theme\", theme.mode);\n }\n applyTheme(theme.mode, theme.tokens);\n}\n\n/** The style element the host's font CSS goes in — the same id the spec's\n * `applyHostFonts` uses, so both clients agree on one element. */\nexport const HOST_FONTS_STYLE_ID = \"__mcp-host-fonts\";\n\n/**\n * Load the host's `@font-face` CSS (the spec's `hostContext.styles.css.fonts`)\n * into the document.\n *\n * Mirrors ext-apps `applyHostFonts`, which this client cannot import without\n * pulling the ext-apps runtime into its IIFE: the CSS is injected once and left\n * in place, so a later host-context change without `css` keeps the typeface\n * loaded. A host that sends none leaves the web-safe fallbacks in force.\n * SSR-safe.\n */\nexport function injectHostFonts(css: string): void {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(HOST_FONTS_STYLE_ID)) return;\n const style = document.createElement(\"style\");\n style.id = HOST_FONTS_STYLE_ID;\n style.textContent = css;\n document.head.appendChild(style);\n}\n\n/** Read the OS-level color scheme as a sane default for hosts that don't push a\n * theme until the handshake completes, or ever (standalone). */\nexport function preferredMode(win: Window | undefined): \"light\" | \"dark\" {\n try {\n if (win?.matchMedia?.(\"(prefers-color-scheme: dark)\").matches) return \"dark\";\n } catch {\n // matchMedia unavailable (older test envs) — fall through to light.\n }\n return \"light\";\n}\n\n/** Coerce an arbitrary host-supplied theme signal to a mode. Accepts the string\n * form (`\"dark\"`) both hosts use; anything else falls back. */\nexport function coerceMode(value: unknown, fallback: \"light\" | \"dark\"): \"light\" | \"dark\" {\n return value === \"light\" || value === \"dark\" ? value : fallback;\n}\n","/**\n * Cross-host UI client — types and wire constants.\n *\n * The cross-host client (`connectUI`) renders one Synapse-authored component in\n * any MCP Apps host (ChatGPT, Claude, NimbleBrain) and standalone. Apps code\n * against `synapse.*` and never touch the bridge. This is a **push-first** surface: the tool output that spawned\n * the widget is delivered at render (`data()` / `onData()`); `callTool()` is the\n * pull escape hatch, advertised per host via `capabilities()`.\n *\n * This layer intentionally has ZERO dependency on `@modelcontextprotocol/*` — the\n * bridge is JSON-RPC over `postMessage`, spoken by hand, so the IIFE that apps\n * inline stays tiny (no Zod, no ext-apps schemas).\n */\n\n/**\n * The bridge the client resolved to, as reported by `synapse.host()`:\n * `\"mcp-apps\"` in a frame, `\"generic\"` standalone. It names the bridge, not the\n * product — every framing host speaks the same one. Apps should rarely branch on\n * it; `capabilities()` is the supported way to feature-detect.\n */\nexport type HostKind = \"mcp-apps\" | \"generic\";\n\n/** Resolved theme. `mode` always resolves to light or dark. `tokens` are CSS\n * custom properties the host publishes — the MCP Apps adapter reads them from\n * `hostContext.styles.variables`; where a host sends none they stay empty and the\n * SDK's neutral defaults back them. */\nexport interface SynapseUITheme {\n mode: \"light\" | \"dark\";\n tokens: Record<string, string>;\n}\n\n/** What the active host actually supports. `data()`/`onData()`/`theme()`/\n * `resize()` work everywhere; these three vary. */\nexport interface HostCapabilities {\n /** `callTool()` can reach the server (widget→server fetch). */\n pull: boolean;\n /** `sendPrompt()` reaches the agent conversation. */\n sendPrompt: boolean;\n /** `openLink()` opens an external URL through the host. */\n openLink: boolean;\n}\n\n/** Thrown by `callTool()` when the active host offers no widget→server call. */\nexport class HostUnsupportedError extends Error {\n constructor(feature: string, host: HostKind) {\n super(`\"${feature}\" is not supported by the \"${host}\" host`);\n this.name = \"HostUnsupportedError\";\n }\n}\n\n/**\n * Thrown by `callTool()` when the tool result says the call failed\n * (`isError: true`). MCP reports a tool failure inside the result rather than as\n * a JSON-RPC error, and a host reports a refusal the same way — ChatGPT answers a\n * call to a tool the app may not see with an `isError` result — so without this a\n * failure would resolve as if it were data. The message is the result's first\n * text block; the whole result is on `result`.\n */\nexport class ToolCallError extends Error {\n readonly result: unknown;\n constructor(name: string, result: unknown) {\n super(toolErrorText(result) ?? `tool \"${name}\" returned an error`);\n this.name = \"ToolCallError\";\n this.result = result;\n }\n}\n\nfunction toolErrorText(result: unknown): string | undefined {\n const content = (result as { content?: unknown } | null)?.content;\n if (!Array.isArray(content)) return undefined;\n for (const block of content) {\n const b = block as { type?: unknown; text?: unknown } | null;\n if (b?.type === \"text\" && typeof b.text === \"string\" && b.text !== \"\") return b.text;\n }\n return undefined;\n}\n\n/** True when a tool result reports failure, as MCP defines it. */\nexport function isToolError(result: unknown): boolean {\n return (\n result != null &&\n typeof result === \"object\" &&\n (result as { isError?: unknown }).isError === true\n );\n}\n\nexport interface ConnectUIOptions {\n /** App name — informational; forwarded to hosts that accept an appInfo. */\n name?: string;\n /** App semver — informational. */\n version?: string;\n /**\n * Force a host adapter instead of auto-detecting. Used by preview harnesses,\n * SSR, and tests; production apps omit it and let the SDK feature-detect.\n * `\"mcp-apps\"` → MCP Apps standard adapter, `\"generic\"` → inline adapter.\n */\n host?: HostKind;\n /**\n * `id` of the `<script type=\"application/json\">` element carrying pushed data\n * baked into the HTML (the SSR / standalone path). Defaults to\n * {@link SYNAPSE_DATA_ELEMENT_ID}.\n */\n dataElementId?: string;\n /**\n * Auto-report content height to the host on layout changes (MCP Apps only).\n * Defaults to `true`. Set `false` to size manually via `resize()`.\n */\n autoResize?: boolean;\n /** Window to bind to. Defaults to the global `window`. Injectable for tests. */\n window?: Window & typeof globalThis;\n}\n\n/**\n * The public cross-host client. Bound to `synapse` by convention.\n *\n * ```ts\n * const synapse = connectUI();\n * synapse.onData(render); // future pushes/updates\n * render(synapse.data()); // current value (may be null → empty state)\n * ```\n */\nexport interface SynapseUIClient {\n /** The current pushed data, or `null` before anything has been delivered. */\n data<T = unknown>(): T | null;\n /** Subscribe to data updates (NOT replayed — read `data()` for the current\n * value). Returns an unsubscribe. */\n onData<T = unknown>(cb: (data: T) => void): () => void;\n\n /** The current resolved theme. */\n theme(): SynapseUITheme;\n /** Subscribe to theme changes. The client already applies the theme to the DOM\n * (`data-theme` attribute + CSS variables) before this fires. */\n onTheme(cb: (theme: SynapseUITheme) => void): () => void;\n\n /** Widget→server tool call. Resolves with the tool result. Rejects with\n * {@link ToolCallError} when the result reports failure (`isError: true`), and\n * with {@link HostUnsupportedError} where the host advertises no pull\n * (`capabilities().pull === false`). */\n callTool<O = unknown>(name: string, args?: Record<string, unknown>): Promise<O>;\n /** Send a follow-up message to the agent conversation. No-op where unsupported. */\n sendPrompt(text: string): void;\n /** Open an external URL through the host (falls back to `window.open`). */\n openLink(url: string): void;\n /** Report content height to the host. Omit `height` to measure `document.body`. */\n resize(height?: number): void;\n\n /** What the active host supports. */\n capabilities(): HostCapabilities;\n /** The resolved host — an escape hatch; prefer `capabilities()`. */\n host(): HostKind;\n /** Tear down listeners/observers. */\n destroy(): void;\n}\n\n/**\n * Internal adapter contract. One per host bridge; the client is a thin façade\n * over the selected adapter.\n */\nexport interface HostAdapter {\n readonly host: HostKind;\n getData<T = unknown>(): T | null;\n onData<T = unknown>(cb: (data: T) => void): () => void;\n getTheme(): SynapseUITheme;\n onTheme(cb: (theme: SynapseUITheme) => void): () => void;\n callTool<O = unknown>(name: string, args?: Record<string, unknown>): Promise<O>;\n sendPrompt(text: string): void;\n openLink(url: string): void;\n resize(height?: number): void;\n capabilities(): HostCapabilities;\n /** Begin listening / send the ready handshake / read baked-in data. Called once\n * by `connectUI` synchronously so `getData()` is populated on return. */\n start(): void;\n destroy(): void;\n}\n\n// ---------------------------------------------------------------------------\n// Wire constants — the bridge message shapes. Centralized so a\n// host protocol tweak is a one-line change, not a grep-and-pray.\n// ---------------------------------------------------------------------------\n\n/** Default `id` of the baked-in data `<script type=\"application/json\">`. */\nexport const SYNAPSE_DATA_ELEMENT_ID = \"synapse-ui-data\";\n\n// ---------------------------------------------------------------------------\n// MCP Apps standard (SEP-1865) — the bridge every framing host speaks. The View iframe is an MCP client and the\n// host an MCP server; they exchange raw JSON-RPC 2.0 objects over `postMessage`\n// (no wrapper envelope). Method names are canonical to the ext-apps spec.\n// ---------------------------------------------------------------------------\n\n/** Protocol version exchanged in the `ui/initialize` handshake. */\nexport const MCPAPP_PROTOCOL_VERSION = \"2026-01-26\";\n/** View → host handshake request; the result carries the host context. */\nexport const MCPAPP_INITIALIZE = \"ui/initialize\";\n/** View → host notification sent once after the init result — the host holds all\n * pushes until it arrives. */\nexport const MCPAPP_INITIALIZED = \"ui/notifications/initialized\";\n/** Host → view notification carrying the tool output. `params` IS the\n * `CallToolResult` (data at `params.structuredContent`) — no `result` wrapper. */\nexport const MCPAPP_TOOL_RESULT = \"ui/notifications/tool-result\";\n/** Host → view notification carrying a partial host context (theme, styles, …). */\nexport const MCPAPP_HOST_CONTEXT_CHANGED = \"ui/notifications/host-context-changed\";\n/** View → host notification reporting intrinsic size (`{ width?, height? }`). A\n * host may keep the frame hidden until it receives one, so it is sent promptly. */\nexport const MCPAPP_SIZE_CHANGED = \"ui/notifications/size-changed\";\n/** View → host request: open an external URL (`{ url }`). */\nexport const MCPAPP_OPEN_LINK = \"ui/open-link\";\n/** View → host request: send a follow-up to the conversation\n * (`{ role: \"user\", content: ContentBlock[] }`). */\nexport const MCPAPP_MESSAGE = \"ui/message\";\n/** Host → view request: graceful teardown; the view replies `{}`. */\nexport const MCPAPP_TEARDOWN = \"ui/resource-teardown\";\n/** Standard MCP method the View may call over the same channel (pull). */\nexport const MCP_TOOLS_CALL = \"tools/call\";\n","/**\n * Read data baked into the HTML as `<script type=\"application/json\" id=…>`.\n *\n * This is how a server delivers tool output with no round-trip, for first paint\n * and for a standalone render: the server helper escapes the payload\n * and substitutes it into the element (see the Python `SynapseUI.render_html`).\n * A data-free template leaves the marker comment in place, which fails\n * `JSON.parse` and reads back as `null` — exactly the \"no data yet\" state.\n */\nexport function readInlineData<T = unknown>(\n doc: Document | undefined,\n elementId: string,\n): T | null {\n if (!doc) return null;\n const el = doc.getElementById(elementId);\n const text = el?.textContent;\n if (!text) return null;\n try {\n const parsed = JSON.parse(text);\n return (parsed ?? null) as T | null;\n } catch {\n // Unreplaced marker or malformed blob — treat as no data.\n return null;\n }\n}\n","import { readInlineData } from \"../data.js\";\nimport { coerceMode, preferredMode } from \"../theme.js\";\nimport {\n type ConnectUIOptions,\n type HostAdapter,\n type HostCapabilities,\n HostUnsupportedError,\n SYNAPSE_DATA_ELEMENT_ID,\n type SynapseUITheme,\n} from \"../types.js\";\n\n/**\n * Inline / standalone fallback adapter.\n *\n * No live host bridge — used for SSR, previews, and a plain browser render. Data\n * comes only from the baked-in `<script type=\"application/json\">` blob; there is\n * nothing to push, so `onData` never fires after `start()`. Theme follows the OS\n * color scheme and tracks `prefers-color-scheme` changes. `openLink` opens a new\n * tab; `sendPrompt`/`callTool` have no destination.\n */\nexport function createInlineAdapter(\n win: Window & typeof globalThis,\n options: ConnectUIOptions,\n): HostAdapter {\n const dataElementId = options.dataElementId ?? SYNAPSE_DATA_ELEMENT_ID;\n\n let currentData: unknown = null;\n let currentTheme: SynapseUITheme = { mode: preferredMode(win), tokens: {} };\n\n const themeCbs = new Set<(t: SynapseUITheme) => void>();\n let destroyed = false;\n let media: MediaQueryList | null = null;\n\n const onSchemeChange = (event: MediaQueryListEvent) => {\n if (destroyed) return;\n const mode = coerceMode(event.matches ? \"dark\" : \"light\", currentTheme.mode);\n if (mode === currentTheme.mode) return;\n currentTheme = { mode, tokens: {} };\n for (const cb of themeCbs) cb(currentTheme);\n };\n\n return {\n host: \"generic\",\n getData: <T>() => currentData as T | null,\n onData() {\n // Static render — no updates after the initial baked-in read.\n return () => {};\n },\n getTheme: () => currentTheme,\n onTheme(cb) {\n themeCbs.add(cb);\n return () => themeCbs.delete(cb);\n },\n async callTool<O>(_name: string): Promise<O> {\n throw new HostUnsupportedError(\"callTool\", \"generic\");\n },\n sendPrompt() {\n // No agent to reach in a standalone render.\n },\n openLink(url: string) {\n win.open(url, \"_blank\", \"noopener,noreferrer\");\n },\n resize() {\n // No host to size for.\n },\n capabilities(): HostCapabilities {\n return { pull: false, sendPrompt: false, openLink: true };\n },\n start() {\n currentData = readInlineData(win.document, dataElementId);\n try {\n media = win.matchMedia?.(\"(prefers-color-scheme: dark)\") ?? null;\n media?.addEventListener?.(\"change\", onSchemeChange);\n } catch {\n media = null;\n }\n },\n destroy() {\n if (destroyed) return;\n destroyed = true;\n media?.removeEventListener?.(\"change\", onSchemeChange);\n media = null;\n themeCbs.clear();\n },\n };\n}\n","// `detection` is type-only against `@modelcontextprotocol/*`, so importing it\n// keeps this adapter free of the ext-apps runtime (and Zod) that the lean\n// `window.SynapseUI` IIFE deliberately excludes.\nimport { extractHostFontCss } from \"../../detection.js\";\nimport { readInlineData } from \"../data.js\";\nimport { coerceMode, injectHostFonts, preferredMode } from \"../theme.js\";\nimport {\n type ConnectUIOptions,\n type HostAdapter,\n type HostCapabilities,\n MCP_TOOLS_CALL,\n MCPAPP_HOST_CONTEXT_CHANGED,\n MCPAPP_INITIALIZE,\n MCPAPP_INITIALIZED,\n MCPAPP_MESSAGE,\n MCPAPP_OPEN_LINK,\n MCPAPP_PROTOCOL_VERSION,\n MCPAPP_SIZE_CHANGED,\n MCPAPP_TEARDOWN,\n MCPAPP_TOOL_RESULT,\n SYNAPSE_DATA_ELEMENT_ID,\n type SynapseUITheme,\n} from \"../types.js\";\n\n/** How long a widget→host request (`callTool`, `openLink`, `sendPrompt`) waits\n * for its response before rejecting, so a silent host never hangs a promise. */\nconst REQUEST_TIMEOUT_MS = 30_000;\n\ninterface PendingRequest {\n resolve: (value: unknown) => void;\n reject: (reason: unknown) => void;\n timer: ReturnType<typeof setTimeout>;\n}\n\n/**\n * MCP Apps standard (SEP-1865) adapter — the bridge for every framed host.\n * ChatGPT, Claude and NimbleBrain all implement the standard, so there is one.\n *\n * The View iframe is an MCP client speaking JSON-RPC 2.0 to `window.parent`:\n *\n * 1. posts `ui/initialize` and awaits the host context (theme, style variables);\n * 2. posts `ui/notifications/initialized`, then a `size-changed` — a host keeps\n * the frame hidden until it has both the handshake and a size;\n * 3. receives data via `ui/notifications/tool-result` (`params` IS the\n * `CallToolResult`, so data is at `params.structuredContent`) and theme via\n * `ui/notifications/host-context-changed`.\n *\n * Actions go up as requests: `ui/open-link`, `ui/message` (follow-up), and\n * `tools/call` (pull).\n */\nexport function createMcpAppsAdapter(\n win: Window & typeof globalThis,\n options: ConnectUIOptions,\n): HostAdapter {\n const dataElementId = options.dataElementId ?? SYNAPSE_DATA_ELEMENT_ID;\n const autoResize = options.autoResize !== false;\n\n let currentData: unknown = null;\n let currentTheme: SynapseUITheme = { mode: preferredMode(win), tokens: {} };\n\n const dataCbs = new Set<(d: unknown) => void>();\n const themeCbs = new Set<(t: SynapseUITheme) => void>();\n let destroyed = false;\n // Set once the host has answered `ui/initialize` and been told `initialized`.\n let initialized = false;\n let nextId = 1;\n const pending = new Map<number, PendingRequest>();\n let lastReportedHeight = -1;\n let resizeObserver: ResizeObserver | null = null;\n let onWindowResize: (() => void) | null = null;\n\n const parent = () => win.parent ?? win;\n\n function post(message: Record<string, unknown>): void {\n parent().postMessage(message, \"*\");\n }\n\n function notify(method: string, params?: Record<string, unknown>): void {\n post({ jsonrpc: \"2.0\", method, params: params ?? {} });\n }\n\n function request<T = unknown>(method: string, params?: Record<string, unknown>): Promise<T> {\n const id = nextId++;\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => {\n pending.delete(id);\n reject(new Error(`\"${method}\" timed out`));\n }, REQUEST_TIMEOUT_MS);\n pending.set(id, { resolve: resolve as (v: unknown) => void, reject, timer });\n post({ jsonrpc: \"2.0\", id, method, params: params ?? {} });\n });\n }\n\n function emitData(next: unknown): void {\n if (next == null) return;\n currentData = next;\n for (const cb of dataCbs) cb(next);\n }\n\n /** Merge a full or partial host context into the resolved theme (mode, tokens),\n * and load the host's `@font-face` CSS from the spec's `styles.css.fonts`. */\n function applyHostContext(ctx: Record<string, unknown> | null | undefined): void {\n if (!ctx || typeof ctx !== \"object\") return;\n const fontCss = extractHostFontCss(ctx);\n if (fontCss !== undefined) injectHostFonts(fontCss);\n let { mode, tokens } = currentTheme;\n let changed = false;\n if (ctx.theme != null) {\n const next = coerceMode(ctx.theme, mode);\n if (next !== mode) {\n mode = next;\n changed = true;\n }\n }\n const styles = ctx.styles as { variables?: Record<string, string> } | undefined;\n if (styles?.variables && typeof styles.variables === \"object\") {\n tokens = { ...tokens, ...styles.variables };\n changed = true;\n }\n if (changed) {\n currentTheme = { mode, tokens };\n for (const cb of themeCbs) cb(currentTheme);\n }\n }\n\n function reportSize(height?: number): void {\n // `ui/initialize` is the app's first word on this bridge, and a strict host\n // drops anything that arrives before it — leaving the frame hidden. The\n // handshake reports a size as soon as it completes, so nothing is lost.\n if (destroyed || !initialized) return;\n const h = typeof height === \"number\" ? height : Math.ceil(win.document.body.scrollHeight);\n if (h === lastReportedHeight) return;\n lastReportedHeight = h;\n notify(MCPAPP_SIZE_CHANGED, { height: h });\n }\n\n function handleResponse(d: Record<string, unknown>): void {\n // Normalize the echoed id: JSON-RPC requires a same-type echo, but a lax host\n // that returned \"1\" for 1 would otherwise miss the numeric-keyed pending map.\n const id = Number(d.id);\n const p = pending.get(id);\n if (!p) return;\n pending.delete(id);\n clearTimeout(p.timer);\n if (d.error != null) {\n const err = d.error as { message?: string };\n p.reject(new Error(err.message ?? \"request failed\"));\n } else {\n p.resolve(d.result);\n }\n }\n\n function handleNotification(method: string, params: Record<string, unknown>): void {\n if (method === MCPAPP_TOOL_RESULT) {\n // `params` is the CallToolResult: the render data lives at structuredContent.\n const structured = params.structuredContent;\n emitData(structured != null ? structured : params);\n } else if (method === MCPAPP_HOST_CONTEXT_CHANGED) {\n applyHostContext(params);\n }\n }\n\n function handleRequest(d: Record<string, unknown>): void {\n // The one host→view request we honor: acknowledge teardown so the host can\n // dispose the frame cleanly.\n if (d.method === MCPAPP_TEARDOWN) {\n post({ jsonrpc: \"2.0\", id: d.id, result: {} });\n }\n }\n\n const onMessage = (event: MessageEvent) => {\n if (destroyed) return;\n // Accept only frames from the host window when the browser sets a source.\n if (event.source && event.source !== parent()) return;\n const d = event.data as Record<string, unknown> | null | undefined;\n if (!d || typeof d !== \"object\" || d.jsonrpc !== \"2.0\") return;\n if (d.id != null && (\"result\" in d || \"error\" in d)) {\n handleResponse(d);\n } else if (typeof d.method === \"string\") {\n if (d.id != null) handleRequest(d);\n else handleNotification(d.method, (d.params ?? {}) as Record<string, unknown>);\n }\n };\n\n function setupResize(): void {\n onWindowResize = () => reportSize();\n win.addEventListener(\"resize\", onWindowResize);\n if (typeof win.ResizeObserver !== \"undefined\") {\n resizeObserver = new win.ResizeObserver(() => reportSize());\n resizeObserver.observe(win.document.body);\n }\n }\n\n return {\n host: \"mcp-apps\",\n getData: <T>() => currentData as T | null,\n onData(cb) {\n dataCbs.add(cb as (d: unknown) => void);\n return () => dataCbs.delete(cb as (d: unknown) => void);\n },\n getTheme: () => currentTheme,\n onTheme(cb) {\n themeCbs.add(cb);\n return () => themeCbs.delete(cb);\n },\n async callTool<O>(name: string, args?: Record<string, unknown>): Promise<O> {\n return (await request(MCP_TOOLS_CALL, { name, arguments: args ?? {} })) as O;\n },\n sendPrompt(text: string) {\n void request(MCPAPP_MESSAGE, { role: \"user\", content: [{ type: \"text\", text }] }).catch(\n () => {},\n );\n },\n openLink(url: string) {\n void request(MCPAPP_OPEN_LINK, { url }).catch(() => {});\n },\n resize(height?: number) {\n reportSize(height);\n },\n capabilities(): HostCapabilities {\n // An MCP Apps host answers `tools/call`, `ui/message` and `ui/open-link`\n // over this bridge.\n return { pull: true, sendPrompt: true, openLink: true };\n },\n start() {\n win.addEventListener(\"message\", onMessage as EventListener);\n\n // Baked-in data → available on first paint, before the handshake resolves.\n currentData = readInlineData(win.document, dataElementId);\n\n if (autoResize) setupResize();\n\n request<{ hostContext?: Record<string, unknown> }>(MCPAPP_INITIALIZE, {\n appInfo: { name: options.name ?? \"synapse-ui\", version: options.version ?? \"0.0.0\" },\n appCapabilities: { availableDisplayModes: [\"inline\"] },\n protocolVersion: MCPAPP_PROTOCOL_VERSION,\n })\n .then((result) => {\n if (destroyed) return;\n applyHostContext(result?.hostContext);\n notify(MCPAPP_INITIALIZED, {});\n initialized = true;\n // A host keeps the frame hidden until it gets a size after init, and\n // this is the first point at which sending one is allowed.\n reportSize();\n })\n .catch(() => {\n // The parent never answered: it is not an MCP Apps host, and nothing\n // reaches the component over this bridge. Baked-in data still renders.\n });\n },\n destroy() {\n if (destroyed) return;\n destroyed = true;\n win.removeEventListener(\"message\", onMessage as EventListener);\n if (onWindowResize) win.removeEventListener(\"resize\", onWindowResize);\n onWindowResize = null;\n resizeObserver?.disconnect();\n resizeObserver = null;\n for (const p of pending.values()) {\n clearTimeout(p.timer);\n p.reject(new Error(\"adapter destroyed\"));\n }\n pending.clear();\n dataCbs.clear();\n themeCbs.clear();\n },\n };\n}\n","import { createInlineAdapter } from \"./adapters/inline.js\";\nimport { createMcpAppsAdapter } from \"./adapters/mcpapps.js\";\nimport type { ConnectUIOptions, HostAdapter, HostKind } from \"./types.js\";\n\n/**\n * Minimal window shape the detector inspects. Kept structural so detection is\n * unit-testable with a plain object — no full `Window` fake required.\n */\ninterface DetectableWindow {\n parent?: unknown;\n}\n\n/**\n * Detect the bridge from the browsing context.\n *\n * - a nested browsing context (`parent !== self`, or a cross-origin access that\n * throws) → **mcp-apps**: every host that frames a component speaks the MCP\n * Apps standard.\n * - top-level document → **generic** (inline / standalone).\n *\n * Nothing on the window names the host. `window.openai` in particular does not:\n * ChatGPT injects it into every frame it serves, whatever the component is.\n * Which host answered is in the handshake, not here.\n */\nexport function detectHostKind(win: DetectableWindow): HostKind {\n try {\n if (win.parent != null && win.parent !== win) return \"mcp-apps\";\n } catch {\n // Cross-origin parent access throws → we are framed by another origin.\n return \"mcp-apps\";\n }\n return \"generic\";\n}\n\n/** Build the adapter for an explicit host kind (`options.host` or a detected one). */\nexport function adapterForKind(\n kind: HostKind,\n win: Window & typeof globalThis,\n options: ConnectUIOptions,\n): HostAdapter {\n if (kind === \"mcp-apps\") return createMcpAppsAdapter(win, options);\n if (kind === \"generic\") return createInlineAdapter(win, options);\n // A script-tag caller has no compiler to reject a value outside `HostKind`, and\n // treating one as standalone inside a frame sends no handshake: the host keeps\n // the frame hidden and the component is blank with nothing to say why.\n throw new TypeError(`unknown host \"${String(kind)}\": expected \"mcp-apps\" or \"generic\"`);\n}\n\n/** Select and construct the host adapter, honoring `options.host` when set. */\nexport function selectAdapter(\n win: Window & typeof globalThis,\n options: ConnectUIOptions,\n): HostAdapter {\n const kind = options.host ?? detectHostKind(win as unknown as DetectableWindow);\n return adapterForKind(kind, win, options);\n}\n","import { selectAdapter } from \"./detect.js\";\nimport { applyHostTheme } from \"./theme.js\";\nimport {\n type ConnectUIOptions,\n isToolError,\n type SynapseUIClient,\n ToolCallError,\n} from \"./types.js\";\n\n/**\n * Connect a Synapse-authored component to whatever host it renders in — any MCP\n * Apps host, or a plain/standalone page — behind one push-first API. Detects\n * whether it is framed, selects an adapter, and applies the\n * host theme to the DOM before returning.\n *\n * Synchronous: `data()` is populated from baked-in data (where present) on\n * return, and pushed updates arrive via `onData`. Bind the result to `synapse`:\n *\n * ```ts\n * const synapse = connectUI({ name: \"my-widget\", version: \"1.0.0\" });\n * synapse.onData(render); // future pushes/updates\n * render(synapse.data()); // current value (null → empty state)\n * ```\n */\nexport function connectUI(options: ConnectUIOptions = {}): SynapseUIClient {\n const win = options.window ?? (globalThis as unknown as Window & typeof globalThis);\n const adapter = selectAdapter(win, options);\n\n // The client owns theme application: adapters resolve mode/tokens; this puts\n // them on the DOM (data-theme + CSS vars) so apps never wire theme by hand.\n applyHostTheme(adapter.getTheme());\n const unsubTheme = adapter.onTheme(applyHostTheme);\n\n adapter.start();\n\n let destroyed = false;\n\n return {\n data: <T>() => adapter.getData<T>(),\n onData: <T>(cb: (data: T) => void) => adapter.onData<T>(cb),\n theme: () => adapter.getTheme(),\n onTheme: (cb) => adapter.onTheme(cb),\n // Decided here rather than per adapter: every host reports a failed or\n // refused call inside the result, because that is how MCP defines one.\n async callTool<O>(name: string, args?: Record<string, unknown>): Promise<O> {\n const result = await adapter.callTool<O>(name, args);\n if (isToolError(result)) throw new ToolCallError(name, result);\n return result;\n },\n sendPrompt: (text: string) => adapter.sendPrompt(text),\n openLink: (url: string) => adapter.openLink(url),\n resize: (height?: number) => adapter.resize(height),\n capabilities: () => adapter.capabilities(),\n host: () => adapter.host,\n destroy() {\n if (destroyed) return;\n destroyed = true;\n unsubTheme();\n adapter.destroy();\n },\n };\n}\n"]}
|