@mcp-ts/sdk 1.3.7 → 1.3.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +397 -404
  3. package/dist/adapters/agui-middleware.js.map +1 -1
  4. package/dist/adapters/agui-middleware.mjs.map +1 -1
  5. package/dist/bin/mcp-ts.js +0 -0
  6. package/dist/bin/mcp-ts.js.map +1 -1
  7. package/dist/bin/mcp-ts.mjs +0 -0
  8. package/dist/bin/mcp-ts.mjs.map +1 -1
  9. package/dist/client/index.js.map +1 -1
  10. package/dist/client/index.mjs.map +1 -1
  11. package/dist/client/react.d.mts +10 -28
  12. package/dist/client/react.d.ts +10 -28
  13. package/dist/client/react.js +101 -52
  14. package/dist/client/react.js.map +1 -1
  15. package/dist/client/react.mjs +102 -53
  16. package/dist/client/react.mjs.map +1 -1
  17. package/dist/client/vue.js.map +1 -1
  18. package/dist/client/vue.mjs.map +1 -1
  19. package/dist/index.js +78 -6
  20. package/dist/index.js.map +1 -1
  21. package/dist/index.mjs +73 -6
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/server/index.js +78 -6
  24. package/dist/server/index.js.map +1 -1
  25. package/dist/server/index.mjs +73 -6
  26. package/dist/server/index.mjs.map +1 -1
  27. package/dist/shared/index.js.map +1 -1
  28. package/dist/shared/index.mjs.map +1 -1
  29. package/package.json +185 -185
  30. package/src/adapters/agui-middleware.ts +382 -382
  31. package/src/bin/mcp-ts.ts +102 -102
  32. package/src/client/core/app-host.ts +417 -417
  33. package/src/client/core/sse-client.ts +371 -371
  34. package/src/client/core/types.ts +31 -31
  35. package/src/client/index.ts +27 -27
  36. package/src/client/react/index.ts +20 -16
  37. package/src/client/react/use-app-host.ts +74 -73
  38. package/src/client/react/use-mcp-apps.tsx +224 -214
  39. package/src/client/react/use-mcp.ts +669 -641
  40. package/src/client/vue/index.ts +10 -10
  41. package/src/client/vue/use-mcp.ts +617 -617
  42. package/src/index.ts +11 -11
  43. package/src/server/handlers/nextjs-handler.ts +204 -204
  44. package/src/server/handlers/sse-handler.ts +631 -631
  45. package/src/server/index.ts +57 -57
  46. package/src/server/mcp/multi-session-client.ts +228 -228
  47. package/src/server/mcp/oauth-client.ts +1188 -1188
  48. package/src/server/mcp/storage-oauth-provider.ts +272 -272
  49. package/src/server/storage/crypto.ts +92 -0
  50. package/src/server/storage/file-backend.ts +157 -157
  51. package/src/server/storage/index.ts +176 -176
  52. package/src/server/storage/memory-backend.ts +123 -123
  53. package/src/server/storage/redis-backend.ts +276 -276
  54. package/src/server/storage/redis.ts +160 -160
  55. package/src/server/storage/sqlite-backend.ts +182 -182
  56. package/src/server/storage/supabase-backend.ts +229 -228
  57. package/src/server/storage/types.ts +116 -116
  58. package/src/shared/constants.ts +29 -29
  59. package/src/shared/errors.ts +133 -133
  60. package/src/shared/event-routing.ts +28 -28
  61. package/src/shared/events.ts +180 -180
  62. package/src/shared/index.ts +75 -75
  63. package/src/shared/tool-utils.ts +61 -61
  64. package/src/shared/types.ts +282 -282
  65. package/src/shared/utils.ts +38 -38
  66. package/supabase/migrations/20260330195700_install_mcp_sessions.sql +84 -84
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/client/core/sse-client.ts","../../src/client/core/app-host.ts"],"names":["nanoid","data","AppBridge","PostMessageTransport"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Stateless RPC-over-stream client for MCP connections.\r\n *\r\n * Uses single POST requests with `Accept: text/event-stream` for every RPC call.\r\n * Progress events and the final rpc-response are delivered in the same response.\r\n */\r\n\r\nimport { nanoid } from 'nanoid';\r\nimport type {\r\n McpConnectionEvent,\r\n McpObservabilityEvent,\r\n McpAppsUIEvent\r\n} from '../../shared/events.js';\r\nimport type {\r\n McpRpcRequest,\r\n McpRpcResponse,\r\n McpRpcMethod,\r\n McpRpcParams,\r\n ConnectParams,\r\n SessionListResult,\r\n ConnectResult,\r\n DisconnectResult,\r\n RestoreSessionResult,\r\n FinishAuthResult,\r\n ListToolsRpcResult,\r\n ListPromptsResult,\r\n ListResourcesResult,\r\n} from '../../shared/types.js';\r\n\r\nexport interface SSEClientOptions {\r\n /** MCP endpoint URL */\r\n url: string;\r\n\r\n /** User/Client identifier */\r\n identity: string;\r\n\r\n /** Optional auth token for authenticated requests */\r\n authToken?: string;\r\n\r\n /** Callback for MCP connection state changes */\r\n onConnectionEvent?: (event: McpConnectionEvent) => void;\r\n\r\n /** Callback for observability/logging events */\r\n onObservabilityEvent?: (event: McpObservabilityEvent) => void;\r\n\r\n /** Callback for connection status changes */\r\n onStatusChange?: (status: ConnectionStatus) => void;\r\n\r\n /** Callback for MCP App UI events */\r\n onEvent?: (event: McpAppsUIEvent) => void;\r\n\r\n /** Enable debug logging @default false */\r\n debug?: boolean;\r\n}\r\n\r\nexport type ConnectionStatus = 'connecting' | 'connected' | 'disconnected' | 'error';\r\n\r\nconst CONNECTION_EVENT_INTERVAL_MS = 300;\r\n\r\ninterface ToolUiMetadata {\r\n resourceUri?: string;\r\n uri?: string;\r\n visibility?: string[];\r\n}\r\n\r\nexport class SSEClient {\r\n private resourceCache = new Map<string, Promise<unknown>>();\r\n private connected = false;\r\n\r\n constructor(private readonly options: SSEClientOptions) {}\r\n\r\n connect(): void {\r\n if (this.connected) {\r\n return;\r\n }\r\n this.connected = true;\r\n this.options.onStatusChange?.('connected');\r\n this.log('RPC mode: post_stream');\r\n }\r\n\r\n disconnect(): void {\r\n this.connected = false;\r\n this.options.onStatusChange?.('disconnected');\r\n }\r\n\r\n isConnected(): boolean {\r\n return this.connected;\r\n }\r\n\r\n async getSessions(): Promise<SessionListResult> {\r\n return this.sendRequest<SessionListResult>('getSessions');\r\n }\r\n\r\n async connectToServer(params: ConnectParams): Promise<ConnectResult> {\r\n return this.sendRequest<ConnectResult>('connect', params);\r\n }\r\n\r\n async disconnectFromServer(sessionId: string): Promise<DisconnectResult> {\r\n return this.sendRequest<DisconnectResult>('disconnect', { sessionId });\r\n }\r\n\r\n async listTools(sessionId: string): Promise<ListToolsRpcResult> {\r\n return this.sendRequest<ListToolsRpcResult>('listTools', { sessionId });\r\n }\r\n\r\n async callTool(\r\n sessionId: string,\r\n toolName: string,\r\n toolArgs: Record<string, unknown>\r\n ): Promise<unknown> {\r\n const result = await this.sendRequest('callTool', { sessionId, toolName, toolArgs });\r\n this.emitUiEventIfPresent(result, sessionId, toolName);\r\n return result;\r\n }\r\n\r\n async restoreSession(sessionId: string): Promise<RestoreSessionResult> {\r\n return this.sendRequest<RestoreSessionResult>('restoreSession', { sessionId });\r\n }\r\n\r\n async finishAuth(sessionId: string, code: string): Promise<FinishAuthResult> {\r\n return this.sendRequest<FinishAuthResult>('finishAuth', { sessionId, code });\r\n }\r\n\r\n async listPrompts(sessionId: string): Promise<ListPromptsResult> {\r\n return this.sendRequest<ListPromptsResult>('listPrompts', { sessionId });\r\n }\r\n\r\n async getPrompt(sessionId: string, name: string, args?: Record<string, string>): Promise<unknown> {\r\n return this.sendRequest('getPrompt', { sessionId, name, args });\r\n }\r\n\r\n async listResources(sessionId: string): Promise<ListResourcesResult> {\r\n return this.sendRequest<ListResourcesResult>('listResources', { sessionId });\r\n }\r\n\r\n async readResource(sessionId: string, uri: string): Promise<unknown> {\r\n return this.sendRequest('readResource', { sessionId, uri });\r\n }\r\n\r\n preloadToolUiResources(sessionId: string, tools: Array<{ name: string; _meta?: unknown }>): void {\r\n for (const tool of tools) {\r\n const uri = this.extractUiResourceUri(tool);\r\n if (!uri || this.resourceCache.has(uri)) continue;\r\n const promise = this.sendRequest('readResource', { sessionId, uri }).catch((err) => {\r\n this.log(`Failed to preload resource ${uri}: ${err.message}`, 'warn');\r\n this.resourceCache.delete(uri);\r\n return null;\r\n });\r\n this.resourceCache.set(uri, promise);\r\n }\r\n }\r\n\r\n getOrFetchResource(sessionId: string, uri: string): Promise<unknown> {\r\n const cached = this.resourceCache.get(uri);\r\n if (cached) return cached;\r\n const promise = this.sendRequest('readResource', { sessionId, uri });\r\n this.resourceCache.set(uri, promise);\r\n return promise;\r\n }\r\n\r\n hasPreloadedResource(uri: string): boolean {\r\n return this.resourceCache.has(uri);\r\n }\r\n\r\n clearResourceCache(): void {\r\n this.resourceCache.clear();\r\n }\r\n\r\n private async sendRequest<T = unknown>(method: McpRpcMethod, params?: McpRpcParams): Promise<T> {\r\n if (!this.connected) {\r\n this.connect();\r\n }\r\n\r\n this.log(`RPC request via post_stream: ${method}`);\r\n\r\n const request: McpRpcRequest = {\r\n id: `rpc_${nanoid(10)}`,\r\n method,\r\n params,\r\n };\r\n\r\n const response = await fetch(this.buildUrl(), {\r\n method: 'POST',\r\n headers: this.buildHeaders(),\r\n body: JSON.stringify(request),\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\r\n }\r\n\r\n const contentType = (response.headers.get('content-type') || '').toLowerCase();\r\n if (!contentType.includes('text/event-stream')) {\r\n const data = await response.json() as McpRpcResponse;\r\n return this.parseRpcResponse<T>(data);\r\n }\r\n\r\n const data = await this.readRpcResponseFromStream(response, {\r\n delayConnectionEvents:\r\n method === 'connect' ||\r\n method === 'restoreSession' ||\r\n method === 'finishAuth',\r\n });\r\n return this.parseRpcResponse<T>(data);\r\n }\r\n\r\n private async readRpcResponseFromStream(\r\n response: Response,\r\n options: { delayConnectionEvents?: boolean } = {}\r\n ): Promise<McpRpcResponse> {\r\n if (!response.body) {\r\n throw new Error('Streaming response body is missing');\r\n }\r\n\r\n const reader = response.body.getReader();\r\n const decoder = new TextDecoder();\r\n let buffer = '';\r\n let rpcResponse: McpRpcResponse | null = null;\r\n\r\n const dispatchBlock = async (block: string) => {\r\n const lines = block.split('\\n');\r\n let eventName = 'message';\r\n const dataLines: string[] = [];\r\n\r\n for (const rawLine of lines) {\r\n const line = rawLine.replace(/\\r$/, '');\r\n if (!line || line.startsWith(':')) continue;\r\n if (line.startsWith('event:')) {\r\n eventName = line.slice('event:'.length).trim();\r\n continue;\r\n }\r\n if (line.startsWith('data:')) {\r\n dataLines.push(line.slice('data:'.length).trimStart());\r\n }\r\n }\r\n\r\n if (!dataLines.length) return;\r\n const payloadText = dataLines.join('\\n');\r\n let payload: unknown = payloadText;\r\n try {\r\n payload = JSON.parse(payloadText);\r\n } catch {\r\n // Keep raw text\r\n }\r\n\r\n switch (eventName) {\r\n case 'connected':\r\n this.options.onStatusChange?.('connected');\r\n break;\r\n case 'connection':\r\n this.options.onConnectionEvent?.(payload as McpConnectionEvent);\r\n if (options.delayConnectionEvents) {\r\n await this.sleep(CONNECTION_EVENT_INTERVAL_MS);\r\n }\r\n break;\r\n case 'observability':\r\n this.options.onObservabilityEvent?.(payload as McpObservabilityEvent);\r\n break;\r\n case 'rpc-response':\r\n rpcResponse = payload as McpRpcResponse;\r\n break;\r\n default:\r\n break;\r\n }\r\n };\r\n\r\n while (true) {\r\n const { value, done } = await reader.read();\r\n if (done) break;\r\n buffer += decoder.decode(value, { stream: true });\r\n\r\n let separatorMatch = buffer.match(/\\r?\\n\\r?\\n/);\r\n while (separatorMatch && separatorMatch.index !== undefined) {\r\n const separatorIndex = separatorMatch.index;\r\n const separatorLength = separatorMatch[0].length;\r\n const block = buffer.slice(0, separatorIndex);\r\n buffer = buffer.slice(separatorIndex + separatorLength);\r\n await dispatchBlock(block);\r\n separatorMatch = buffer.match(/\\r?\\n\\r?\\n/);\r\n }\r\n }\r\n\r\n if (buffer.trim()) {\r\n await dispatchBlock(buffer);\r\n }\r\n\r\n if (!rpcResponse) {\r\n throw new Error('Missing rpc-response event in streamed RPC result');\r\n }\r\n\r\n return rpcResponse;\r\n }\r\n\r\n private sleep(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n }\r\n\r\n private parseRpcResponse<T>(data: McpRpcResponse): T {\r\n if ('result' in data) {\r\n return data.result as T;\r\n }\r\n if ('error' in data && data.error) {\r\n throw new Error(data.error.message || 'Unknown RPC error');\r\n }\r\n // JSON omits `result` when it is `undefined` (response becomes `{ id: ... }`).\r\n // Treat that shape as a successful void result.\r\n if (data && typeof data === 'object' && 'id' in data) {\r\n return undefined as T;\r\n }\r\n throw new Error('Invalid RPC response format');\r\n }\r\n\r\n private buildUrl(): string {\r\n const url = new URL(this.options.url, globalThis.location?.origin);\r\n url.searchParams.set('identity', this.options.identity);\r\n if (this.options.authToken) {\r\n url.searchParams.set('token', this.options.authToken);\r\n }\r\n return url.toString();\r\n }\r\n\r\n private buildHeaders(): HeadersInit {\r\n const headers: HeadersInit = {\r\n 'Content-Type': 'application/json',\r\n 'Accept': 'text/event-stream',\r\n };\r\n if (this.options.authToken) {\r\n headers['Authorization'] = `Bearer ${this.options.authToken}`;\r\n }\r\n return headers;\r\n }\r\n\r\n private extractUiResourceUri(tool: { name: string; _meta?: unknown }): string | undefined {\r\n const meta = (tool._meta as { ui?: ToolUiMetadata })?.ui;\r\n if (!meta || typeof meta !== 'object') return undefined;\r\n if (meta.visibility && !meta.visibility.includes('app')) return undefined;\r\n return meta.resourceUri ?? meta.uri;\r\n }\r\n\r\n private emitUiEventIfPresent(result: unknown, sessionId: string, toolName: string): void {\r\n const meta = (result as { _meta?: { ui?: ToolUiMetadata } })?._meta;\r\n const resourceUri = meta?.ui?.resourceUri ?? (meta as any)?.['ui/resourceUri'];\r\n\r\n if (resourceUri) {\r\n this.options.onEvent?.({\r\n type: 'mcp-apps-ui',\r\n sessionId,\r\n resourceUri,\r\n toolName,\r\n result,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n }\r\n\r\n private log(message: string, level: 'info' | 'warn' | 'error' = 'info'): void {\r\n if (!this.options.debug && level === 'info') return;\r\n\r\n const prefix = '[SSEClient]';\r\n switch (level) {\r\n case 'warn':\r\n console.warn(prefix, message);\r\n break;\r\n case 'error':\r\n console.error(prefix, message);\r\n break;\r\n default:\r\n console.log(prefix, message);\r\n }\r\n }\r\n}\r\n","/**\r\n * MCP App Host\r\n *\r\n * Bridges the gap between an iframe (MCP App) and the SSEClient (MCP Server).\r\n * Handles secure iframe sandboxing, resource loading, and bi-directional\r\n * communication via the AppBridge protocol.\r\n *\r\n * Key features:\r\n * - Secure iframe sandboxing with minimal permissions\r\n * - Resource preloading for instant MCP App UI loading\r\n * - Cache-aware resource fetching (SSEClient cache → local cache → direct fetch)\r\n * - Support for ui:// and mcp-app:// resource URIs\r\n */\r\n\r\nimport { AppBridge, PostMessageTransport } from '@modelcontextprotocol/ext-apps/app-bridge';\r\nimport type { AppHostClient } from './types';\r\n\r\n// ============================================\r\n// Types & Interfaces\r\n// ============================================\r\n\r\nexport interface AppHostOptions {\r\n /** Enable debug logging @default false */\r\n debug?: boolean;\r\n}\r\n\r\nexport interface AppMessageParams {\r\n role: string;\r\n content: unknown;\r\n}\r\n\r\ninterface ToolCallParams {\r\n name: string;\r\n arguments?: Record<string, unknown>;\r\n}\r\n\r\ninterface ResourceContent {\r\n blob?: string;\r\n text?: string;\r\n}\r\n\r\ninterface ResourceResponse {\r\n contents: ResourceContent[];\r\n}\r\n\r\n// ============================================\r\n// Constants\r\n// ============================================\r\n\r\nconst HOST_INFO = { name: 'mcp-ts-host', version: '1.0.0' };\r\n\r\n/** Sandbox permissions - minimal set required for MCP Apps to function */\r\nconst SANDBOX_PERMISSIONS = [\r\n 'allow-scripts', // Required for app JavaScript execution\r\n 'allow-forms', // Required for form submissions\r\n 'allow-same-origin', // Required for Blob URL correctness\r\n 'allow-modals', // Required for dialogs/alerts\r\n 'allow-popups', // Required for opening links\r\n 'allow-downloads' // Required for file downloads\r\n].join(' ');\r\n\r\n/** Supported MCP App URI schemes */\r\nconst MCP_URI_SCHEMES = ['ui://', 'mcp-app://'] as const;\r\n\r\n// ============================================\r\n// AppHost Class\r\n// ============================================\r\n\r\n/**\r\n * Host for MCP Apps embedded in iframes.\r\n * Manages secure communication between the app and the MCP server.\r\n */\r\nexport class AppHost {\r\n private bridge: AppBridge;\r\n private sessionId?: string;\r\n private resourceCache = new Map<string, Promise<ResourceResponse | null>>();\r\n private debug: boolean;\r\n\r\n /** Callback for app messages (e.g., chat messages from the app) */\r\n public onAppMessage?: (params: AppMessageParams) => void;\r\n\r\n constructor(\r\n private readonly client: AppHostClient,\r\n private readonly iframe: HTMLIFrameElement,\r\n options?: AppHostOptions\r\n ) {\r\n this.debug = options?.debug ?? false;\r\n this.configureSandbox();\r\n this.bridge = this.initializeBridge();\r\n }\r\n\r\n // ============================================\r\n // Public API\r\n // ============================================\r\n\r\n /**\r\n * Start the host. This prepares the bridge handlers but doesn't connect yet.\r\n * The actual connection happens in launch() after HTML is loaded.\r\n * @returns Promise that resolves immediately (bridge connects during launch)\r\n */\r\n async start(): Promise<void> {\r\n // Bridge handlers are already registered in constructor.\r\n // Connection happens in launch() after HTML is loaded.\r\n this.log('Host started, ready to launch');\r\n }\r\n\r\n /**\r\n * Preload UI resources to enable instant app loading.\r\n * Call this when tools are discovered to cache their UI resources.\r\n */\r\n preload(tools: Array<{ _meta?: unknown }>): void {\r\n for (const tool of tools) {\r\n const uri = this.extractUiResourceUri(tool);\r\n if (!uri || this.resourceCache.has(uri)) continue;\r\n\r\n const promise = this.preloadResource(uri);\r\n this.resourceCache.set(uri, promise);\r\n }\r\n }\r\n\r\n /**\r\n * Launch an MCP App from a URL or MCP resource URI.\r\n * Loads the HTML first, then establishes bridge connection.\r\n */\r\n async launch(url: string, sessionId?: string): Promise<void> {\r\n if (sessionId) this.sessionId = sessionId;\r\n\r\n // Set up initialization promise BEFORE connecting\r\n const initializedPromise = this.onAppReady();\r\n\r\n // Load HTML into iframe first\r\n if (this.isMcpUri(url)) {\r\n await this.launchMcpApp(url);\r\n } else {\r\n this.iframe.src = url;\r\n }\r\n\r\n // Wait for iframe to load before connecting bridge\r\n await this.onIframeReady();\r\n\r\n // Connect the bridge (HTML is loaded, contentWindow is ready)\r\n await this.connectBridge();\r\n\r\n // Wait for app to signal it's initialized (with timeout)\r\n this.log('Waiting for app initialization');\r\n await Promise.race([\r\n initializedPromise,\r\n new Promise<void>((resolve) => setTimeout(() => {\r\n this.log('Initialization timeout - continuing anyway', 'warn');\r\n resolve();\r\n }, 3000))\r\n ]);\r\n this.log('App launched and ready');\r\n }\r\n\r\n /**\r\n * Wait for app to signal initialization complete\r\n */\r\n private onAppReady(): Promise<void> {\r\n return new Promise<void>((resolve) => {\r\n const originalHandler = this.bridge.oninitialized;\r\n this.bridge.oninitialized = (...args) => {\r\n this.log('App initialized');\r\n resolve();\r\n this.bridge.oninitialized = originalHandler;\r\n originalHandler?.(...args);\r\n };\r\n });\r\n }\r\n\r\n /**\r\n * Wait for iframe to finish loading\r\n */\r\n private onIframeReady(): Promise<void> {\r\n return new Promise((resolve) => {\r\n if (this.iframe.contentDocument?.readyState === 'complete') {\r\n resolve();\r\n return;\r\n }\r\n this.iframe.addEventListener('load', () => resolve(), { once: true });\r\n });\r\n }\r\n\r\n /**\r\n * Send tool input arguments to the MCP App.\r\n * Call this after launch() when tool input is available.\r\n */\r\n sendToolInput(args: Record<string, unknown>): void {\r\n this.log('Sending tool input to app');\r\n this.bridge.sendToolInput({ arguments: args });\r\n }\r\n\r\n /**\r\n * Send tool result to the MCP App.\r\n * Call this when the tool call completes.\r\n */\r\n sendToolResult(result: unknown): void {\r\n this.log('Sending tool result to app');\r\n this.bridge.sendToolResult(result as any);\r\n }\r\n\r\n /**\r\n * Send tool cancellation to the MCP App.\r\n * Call this when the tool call is cancelled or fails.\r\n */\r\n sendToolCancelled(reason: string): void {\r\n this.log('Sending tool cancellation to app');\r\n this.bridge.sendToolCancelled({ reason });\r\n }\r\n\r\n // ============================================\r\n // Private: Initialization\r\n // ============================================\r\n\r\n private configureSandbox(): void {\r\n if (this.iframe.sandbox.value !== SANDBOX_PERMISSIONS) {\r\n this.iframe.sandbox.value = SANDBOX_PERMISSIONS;\r\n }\r\n }\r\n\r\n private initializeBridge(): AppBridge {\r\n const bridge = new AppBridge(\r\n null,\r\n HOST_INFO,\r\n {\r\n openLinks: {},\r\n serverTools: {},\r\n logging: {},\r\n // Declare support for model context updates\r\n updateModelContext: { text: {} },\r\n },\r\n {\r\n // Initial host context\r\n hostContext: {\r\n theme: 'dark',\r\n platform: 'web',\r\n containerDimensions: { maxHeight: 6000 },\r\n displayMode: 'inline',\r\n availableDisplayModes: ['inline', 'fullscreen'],\r\n },\r\n }\r\n );\r\n\r\n // Register handlers - must be done BEFORE connect()\r\n bridge.oncalltool = (params) => this.handleToolCall(params);\r\n bridge.onopenlink = this.handleOpenLink.bind(this);\r\n bridge.onmessage = this.handleMessage.bind(this);\r\n bridge.onloggingmessage = (params) => this.log(`App log [${params.level}]: ${params.data}`);\r\n bridge.onupdatemodelcontext = async () => ({});\r\n bridge.onsizechange = async ({ width, height }) => {\r\n if (height !== undefined) this.iframe.style.height = `${height}px`;\r\n if (width !== undefined) this.iframe.style.minWidth = `min(${width}px, 100%)`;\r\n return {};\r\n };\r\n bridge.onrequestdisplaymode = async (params) => ({\r\n mode: params.mode === 'fullscreen' ? 'fullscreen' : 'inline'\r\n });\r\n\r\n return bridge;\r\n }\r\n\r\n private async connectBridge(): Promise<void> {\r\n this.log('Connecting bridge to iframe');\r\n\r\n const transport = new PostMessageTransport(\r\n this.iframe.contentWindow!,\r\n this.iframe.contentWindow!\r\n );\r\n\r\n try {\r\n await this.bridge.connect(transport);\r\n this.log('Bridge connected successfully');\r\n } catch (error) {\r\n this.log('Bridge connection failed', 'error');\r\n throw error;\r\n }\r\n }\r\n\r\n // ============================================\r\n // Private: Bridge Event Handlers\r\n // ============================================\r\n\r\n private async handleToolCall(params: ToolCallParams) {\r\n if (!this.client.isConnected()) {\r\n throw new Error('Client disconnected');\r\n }\r\n\r\n const sessionId = await this.getSessionId();\r\n if (!sessionId) {\r\n throw new Error('No active session');\r\n }\r\n\r\n const result = await this.client.callTool(\r\n sessionId,\r\n params.name,\r\n params.arguments ?? {}\r\n );\r\n return result as any;\r\n }\r\n\r\n private async handleOpenLink(params: { url: string }): Promise<Record<string, never>> {\r\n window.open(params.url, '_blank', 'noopener,noreferrer');\r\n return {};\r\n }\r\n\r\n private async handleMessage(params: AppMessageParams): Promise<Record<string, never>> {\r\n this.onAppMessage?.(params);\r\n return {};\r\n }\r\n\r\n // ============================================\r\n // Private: Resource Loading\r\n // ============================================\r\n\r\n private async launchMcpApp(uri: string): Promise<void> {\r\n if (!this.client.isConnected()) {\r\n throw new Error('Client must be connected');\r\n }\r\n\r\n const sessionId = await this.getSessionId();\r\n if (!sessionId) {\r\n throw new Error('No active session');\r\n }\r\n\r\n // Fetch resource using cache hierarchy: SSEClient cache → local cache → direct fetch\r\n const response = await this.fetchResourceWithCache(sessionId, uri);\r\n if (!response?.contents?.length) {\r\n throw new Error(`Empty resource: ${uri}`);\r\n }\r\n\r\n const content = response.contents[0];\r\n const html = this.decodeContent(content);\r\n if (!html) {\r\n throw new Error(`Invalid content in resource: ${uri}`);\r\n }\r\n\r\n // Render via Blob URL for clean isolation\r\n const blob = new Blob([html], { type: 'text/html' });\r\n this.iframe.src = URL.createObjectURL(blob);\r\n }\r\n\r\n private async fetchResourceWithCache(sessionId: string, uri: string): Promise<ResourceResponse> {\r\n // Priority 1: SSEClient's built-in cache (best performance)\r\n if (this.hasClientCache()) {\r\n return (this.client as any).getOrFetchResource(sessionId, uri);\r\n }\r\n\r\n // Priority 2: Local preload cache\r\n const cached = this.resourceCache.get(uri);\r\n if (cached) {\r\n const result = await cached;\r\n if (result) return result;\r\n }\r\n\r\n // Priority 3: Direct fetch\r\n return this.client.readResource(sessionId, uri) as Promise<ResourceResponse>;\r\n }\r\n\r\n private async preloadResource(uri: string): Promise<ResourceResponse | null> {\r\n try {\r\n const sessionId = await this.getSessionId();\r\n if (!sessionId) return null;\r\n return await this.client.readResource(sessionId, uri) as ResourceResponse;\r\n } catch (error) {\r\n this.log(`Preload failed for ${uri}`, 'warn');\r\n return null;\r\n }\r\n }\r\n\r\n // ============================================\r\n // Private: Utilities\r\n // ============================================\r\n\r\n private async getSessionId(): Promise<string | undefined> {\r\n if (this.sessionId) return this.sessionId;\r\n const result = await this.client.getSessions();\r\n return result.sessions?.[0]?.sessionId;\r\n }\r\n\r\n private isMcpUri(url: string): boolean {\r\n return MCP_URI_SCHEMES.some(scheme => url.startsWith(scheme));\r\n }\r\n\r\n private hasClientCache(): boolean {\r\n return 'getOrFetchResource' in this.client &&\r\n typeof (this.client as any).getOrFetchResource === 'function';\r\n }\r\n\r\n private extractUiResourceUri(tool: { _meta?: unknown }): string | undefined {\r\n const meta = tool._meta as { ui?: { resourceUri?: string; uri?: string } } | undefined;\r\n if (!meta?.ui) return undefined;\r\n return meta.ui.resourceUri ?? meta.ui.uri;\r\n }\r\n\r\n private decodeContent(content: ResourceContent): string | undefined {\r\n if (content.blob) {\r\n return atob(content.blob);\r\n }\r\n return content.text;\r\n }\r\n\r\n private log(message: string, level: 'info' | 'warn' | 'error' = 'info'): void {\r\n if (!this.debug && level === 'info') return;\r\n\r\n const prefix = '[AppHost]';\r\n switch (level) {\r\n case 'warn':\r\n console.warn(prefix, message);\r\n break;\r\n case 'error':\r\n console.error(prefix, message);\r\n break;\r\n default:\r\n console.log(prefix, message);\r\n }\r\n }\r\n}\r\n"]}
1
+ {"version":3,"sources":["../../src/client/core/sse-client.ts","../../src/client/core/app-host.ts"],"names":["nanoid","data","AppBridge","PostMessageTransport"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Stateless RPC-over-stream client for MCP connections.\n *\n * Uses single POST requests with `Accept: text/event-stream` for every RPC call.\n * Progress events and the final rpc-response are delivered in the same response.\n */\n\nimport { nanoid } from 'nanoid';\nimport type {\n McpConnectionEvent,\n McpObservabilityEvent,\n McpAppsUIEvent\n} from '../../shared/events.js';\nimport type {\n McpRpcRequest,\n McpRpcResponse,\n McpRpcMethod,\n McpRpcParams,\n ConnectParams,\n SessionListResult,\n ConnectResult,\n DisconnectResult,\n RestoreSessionResult,\n FinishAuthResult,\n ListToolsRpcResult,\n ListPromptsResult,\n ListResourcesResult,\n} from '../../shared/types.js';\n\nexport interface SSEClientOptions {\n /** MCP endpoint URL */\n url: string;\n\n /** User/Client identifier */\n identity: string;\n\n /** Optional auth token for authenticated requests */\n authToken?: string;\n\n /** Callback for MCP connection state changes */\n onConnectionEvent?: (event: McpConnectionEvent) => void;\n\n /** Callback for observability/logging events */\n onObservabilityEvent?: (event: McpObservabilityEvent) => void;\n\n /** Callback for connection status changes */\n onStatusChange?: (status: ConnectionStatus) => void;\n\n /** Callback for MCP App UI events */\n onEvent?: (event: McpAppsUIEvent) => void;\n\n /** Enable debug logging @default false */\n debug?: boolean;\n}\n\nexport type ConnectionStatus = 'connecting' | 'connected' | 'disconnected' | 'error';\n\nconst CONNECTION_EVENT_INTERVAL_MS = 300;\n\ninterface ToolUiMetadata {\n resourceUri?: string;\n uri?: string;\n visibility?: string[];\n}\n\nexport class SSEClient {\n private resourceCache = new Map<string, Promise<unknown>>();\n private connected = false;\n\n constructor(private readonly options: SSEClientOptions) {}\n\n connect(): void {\n if (this.connected) {\n return;\n }\n this.connected = true;\n this.options.onStatusChange?.('connected');\n this.log('RPC mode: post_stream');\n }\n\n disconnect(): void {\n this.connected = false;\n this.options.onStatusChange?.('disconnected');\n }\n\n isConnected(): boolean {\n return this.connected;\n }\n\n async getSessions(): Promise<SessionListResult> {\n return this.sendRequest<SessionListResult>('getSessions');\n }\n\n async connectToServer(params: ConnectParams): Promise<ConnectResult> {\n return this.sendRequest<ConnectResult>('connect', params);\n }\n\n async disconnectFromServer(sessionId: string): Promise<DisconnectResult> {\n return this.sendRequest<DisconnectResult>('disconnect', { sessionId });\n }\n\n async listTools(sessionId: string): Promise<ListToolsRpcResult> {\n return this.sendRequest<ListToolsRpcResult>('listTools', { sessionId });\n }\n\n async callTool(\n sessionId: string,\n toolName: string,\n toolArgs: Record<string, unknown>\n ): Promise<unknown> {\n const result = await this.sendRequest('callTool', { sessionId, toolName, toolArgs });\n this.emitUiEventIfPresent(result, sessionId, toolName);\n return result;\n }\n\n async restoreSession(sessionId: string): Promise<RestoreSessionResult> {\n return this.sendRequest<RestoreSessionResult>('restoreSession', { sessionId });\n }\n\n async finishAuth(sessionId: string, code: string): Promise<FinishAuthResult> {\n return this.sendRequest<FinishAuthResult>('finishAuth', { sessionId, code });\n }\n\n async listPrompts(sessionId: string): Promise<ListPromptsResult> {\n return this.sendRequest<ListPromptsResult>('listPrompts', { sessionId });\n }\n\n async getPrompt(sessionId: string, name: string, args?: Record<string, string>): Promise<unknown> {\n return this.sendRequest('getPrompt', { sessionId, name, args });\n }\n\n async listResources(sessionId: string): Promise<ListResourcesResult> {\n return this.sendRequest<ListResourcesResult>('listResources', { sessionId });\n }\n\n async readResource(sessionId: string, uri: string): Promise<unknown> {\n return this.sendRequest('readResource', { sessionId, uri });\n }\n\n preloadToolUiResources(sessionId: string, tools: Array<{ name: string; _meta?: unknown }>): void {\n for (const tool of tools) {\n const uri = this.extractUiResourceUri(tool);\n if (!uri || this.resourceCache.has(uri)) continue;\n const promise = this.sendRequest('readResource', { sessionId, uri }).catch((err) => {\n this.log(`Failed to preload resource ${uri}: ${err.message}`, 'warn');\n this.resourceCache.delete(uri);\n return null;\n });\n this.resourceCache.set(uri, promise);\n }\n }\n\n getOrFetchResource(sessionId: string, uri: string): Promise<unknown> {\n const cached = this.resourceCache.get(uri);\n if (cached) return cached;\n const promise = this.sendRequest('readResource', { sessionId, uri });\n this.resourceCache.set(uri, promise);\n return promise;\n }\n\n hasPreloadedResource(uri: string): boolean {\n return this.resourceCache.has(uri);\n }\n\n clearResourceCache(): void {\n this.resourceCache.clear();\n }\n\n private async sendRequest<T = unknown>(method: McpRpcMethod, params?: McpRpcParams): Promise<T> {\n if (!this.connected) {\n this.connect();\n }\n\n this.log(`RPC request via post_stream: ${method}`);\n\n const request: McpRpcRequest = {\n id: `rpc_${nanoid(10)}`,\n method,\n params,\n };\n\n const response = await fetch(this.buildUrl(), {\n method: 'POST',\n headers: this.buildHeaders(),\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const contentType = (response.headers.get('content-type') || '').toLowerCase();\n if (!contentType.includes('text/event-stream')) {\n const data = await response.json() as McpRpcResponse;\n return this.parseRpcResponse<T>(data);\n }\n\n const data = await this.readRpcResponseFromStream(response, {\n delayConnectionEvents:\n method === 'connect' ||\n method === 'restoreSession' ||\n method === 'finishAuth',\n });\n return this.parseRpcResponse<T>(data);\n }\n\n private async readRpcResponseFromStream(\n response: Response,\n options: { delayConnectionEvents?: boolean } = {}\n ): Promise<McpRpcResponse> {\n if (!response.body) {\n throw new Error('Streaming response body is missing');\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n let rpcResponse: McpRpcResponse | null = null;\n\n const dispatchBlock = async (block: string) => {\n const lines = block.split('\\n');\n let eventName = 'message';\n const dataLines: string[] = [];\n\n for (const rawLine of lines) {\n const line = rawLine.replace(/\\r$/, '');\n if (!line || line.startsWith(':')) continue;\n if (line.startsWith('event:')) {\n eventName = line.slice('event:'.length).trim();\n continue;\n }\n if (line.startsWith('data:')) {\n dataLines.push(line.slice('data:'.length).trimStart());\n }\n }\n\n if (!dataLines.length) return;\n const payloadText = dataLines.join('\\n');\n let payload: unknown = payloadText;\n try {\n payload = JSON.parse(payloadText);\n } catch {\n // Keep raw text\n }\n\n switch (eventName) {\n case 'connected':\n this.options.onStatusChange?.('connected');\n break;\n case 'connection':\n this.options.onConnectionEvent?.(payload as McpConnectionEvent);\n if (options.delayConnectionEvents) {\n await this.sleep(CONNECTION_EVENT_INTERVAL_MS);\n }\n break;\n case 'observability':\n this.options.onObservabilityEvent?.(payload as McpObservabilityEvent);\n break;\n case 'rpc-response':\n rpcResponse = payload as McpRpcResponse;\n break;\n default:\n break;\n }\n };\n\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n\n let separatorMatch = buffer.match(/\\r?\\n\\r?\\n/);\n while (separatorMatch && separatorMatch.index !== undefined) {\n const separatorIndex = separatorMatch.index;\n const separatorLength = separatorMatch[0].length;\n const block = buffer.slice(0, separatorIndex);\n buffer = buffer.slice(separatorIndex + separatorLength);\n await dispatchBlock(block);\n separatorMatch = buffer.match(/\\r?\\n\\r?\\n/);\n }\n }\n\n if (buffer.trim()) {\n await dispatchBlock(buffer);\n }\n\n if (!rpcResponse) {\n throw new Error('Missing rpc-response event in streamed RPC result');\n }\n\n return rpcResponse;\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n private parseRpcResponse<T>(data: McpRpcResponse): T {\n if ('result' in data) {\n return data.result as T;\n }\n if ('error' in data && data.error) {\n throw new Error(data.error.message || 'Unknown RPC error');\n }\n // JSON omits `result` when it is `undefined` (response becomes `{ id: ... }`).\n // Treat that shape as a successful void result.\n if (data && typeof data === 'object' && 'id' in data) {\n return undefined as T;\n }\n throw new Error('Invalid RPC response format');\n }\n\n private buildUrl(): string {\n const url = new URL(this.options.url, globalThis.location?.origin);\n url.searchParams.set('identity', this.options.identity);\n if (this.options.authToken) {\n url.searchParams.set('token', this.options.authToken);\n }\n return url.toString();\n }\n\n private buildHeaders(): HeadersInit {\n const headers: HeadersInit = {\n 'Content-Type': 'application/json',\n 'Accept': 'text/event-stream',\n };\n if (this.options.authToken) {\n headers['Authorization'] = `Bearer ${this.options.authToken}`;\n }\n return headers;\n }\n\n private extractUiResourceUri(tool: { name: string; _meta?: unknown }): string | undefined {\n const meta = (tool._meta as { ui?: ToolUiMetadata })?.ui;\n if (!meta || typeof meta !== 'object') return undefined;\n if (meta.visibility && !meta.visibility.includes('app')) return undefined;\n return meta.resourceUri ?? meta.uri;\n }\n\n private emitUiEventIfPresent(result: unknown, sessionId: string, toolName: string): void {\n const meta = (result as { _meta?: { ui?: ToolUiMetadata } })?._meta;\n const resourceUri = meta?.ui?.resourceUri ?? (meta as any)?.['ui/resourceUri'];\n\n if (resourceUri) {\n this.options.onEvent?.({\n type: 'mcp-apps-ui',\n sessionId,\n resourceUri,\n toolName,\n result,\n timestamp: Date.now(),\n });\n }\n }\n\n private log(message: string, level: 'info' | 'warn' | 'error' = 'info'): void {\n if (!this.options.debug && level === 'info') return;\n\n const prefix = '[SSEClient]';\n switch (level) {\n case 'warn':\n console.warn(prefix, message);\n break;\n case 'error':\n console.error(prefix, message);\n break;\n default:\n console.log(prefix, message);\n }\n }\n}\n","/**\n * MCP App Host\n *\n * Bridges the gap between an iframe (MCP App) and the SSEClient (MCP Server).\n * Handles secure iframe sandboxing, resource loading, and bi-directional\n * communication via the AppBridge protocol.\n *\n * Key features:\n * - Secure iframe sandboxing with minimal permissions\n * - Resource preloading for instant MCP App UI loading\n * - Cache-aware resource fetching (SSEClient cache → local cache → direct fetch)\n * - Support for ui:// and mcp-app:// resource URIs\n */\n\nimport { AppBridge, PostMessageTransport } from '@modelcontextprotocol/ext-apps/app-bridge';\nimport type { AppHostClient } from './types';\n\n// ============================================\n// Types & Interfaces\n// ============================================\n\nexport interface AppHostOptions {\n /** Enable debug logging @default false */\n debug?: boolean;\n}\n\nexport interface AppMessageParams {\n role: string;\n content: unknown;\n}\n\ninterface ToolCallParams {\n name: string;\n arguments?: Record<string, unknown>;\n}\n\ninterface ResourceContent {\n blob?: string;\n text?: string;\n}\n\ninterface ResourceResponse {\n contents: ResourceContent[];\n}\n\n// ============================================\n// Constants\n// ============================================\n\nconst HOST_INFO = { name: 'mcp-ts-host', version: '1.0.0' };\n\n/** Sandbox permissions - minimal set required for MCP Apps to function */\nconst SANDBOX_PERMISSIONS = [\n 'allow-scripts', // Required for app JavaScript execution\n 'allow-forms', // Required for form submissions\n 'allow-same-origin', // Required for Blob URL correctness\n 'allow-modals', // Required for dialogs/alerts\n 'allow-popups', // Required for opening links\n 'allow-downloads' // Required for file downloads\n].join(' ');\n\n/** Supported MCP App URI schemes */\nconst MCP_URI_SCHEMES = ['ui://', 'mcp-app://'] as const;\n\n// ============================================\n// AppHost Class\n// ============================================\n\n/**\n * Host for MCP Apps embedded in iframes.\n * Manages secure communication between the app and the MCP server.\n */\nexport class AppHost {\n private bridge: AppBridge;\n private sessionId?: string;\n private resourceCache = new Map<string, Promise<ResourceResponse | null>>();\n private debug: boolean;\n\n /** Callback for app messages (e.g., chat messages from the app) */\n public onAppMessage?: (params: AppMessageParams) => void;\n\n constructor(\n private readonly client: AppHostClient,\n private readonly iframe: HTMLIFrameElement,\n options?: AppHostOptions\n ) {\n this.debug = options?.debug ?? false;\n this.configureSandbox();\n this.bridge = this.initializeBridge();\n }\n\n // ============================================\n // Public API\n // ============================================\n\n /**\n * Start the host. This prepares the bridge handlers but doesn't connect yet.\n * The actual connection happens in launch() after HTML is loaded.\n * @returns Promise that resolves immediately (bridge connects during launch)\n */\n async start(): Promise<void> {\n // Bridge handlers are already registered in constructor.\n // Connection happens in launch() after HTML is loaded.\n this.log('Host started, ready to launch');\n }\n\n /**\n * Preload UI resources to enable instant app loading.\n * Call this when tools are discovered to cache their UI resources.\n */\n preload(tools: Array<{ _meta?: unknown }>): void {\n for (const tool of tools) {\n const uri = this.extractUiResourceUri(tool);\n if (!uri || this.resourceCache.has(uri)) continue;\n\n const promise = this.preloadResource(uri);\n this.resourceCache.set(uri, promise);\n }\n }\n\n /**\n * Launch an MCP App from a URL or MCP resource URI.\n * Loads the HTML first, then establishes bridge connection.\n */\n async launch(url: string, sessionId?: string): Promise<void> {\n if (sessionId) this.sessionId = sessionId;\n\n // Set up initialization promise BEFORE connecting\n const initializedPromise = this.onAppReady();\n\n // Load HTML into iframe first\n if (this.isMcpUri(url)) {\n await this.launchMcpApp(url);\n } else {\n this.iframe.src = url;\n }\n\n // Wait for iframe to load before connecting bridge\n await this.onIframeReady();\n\n // Connect the bridge (HTML is loaded, contentWindow is ready)\n await this.connectBridge();\n\n // Wait for app to signal it's initialized (with timeout)\n this.log('Waiting for app initialization');\n await Promise.race([\n initializedPromise,\n new Promise<void>((resolve) => setTimeout(() => {\n this.log('Initialization timeout - continuing anyway', 'warn');\n resolve();\n }, 3000))\n ]);\n this.log('App launched and ready');\n }\n\n /**\n * Wait for app to signal initialization complete\n */\n private onAppReady(): Promise<void> {\n return new Promise<void>((resolve) => {\n const originalHandler = this.bridge.oninitialized;\n this.bridge.oninitialized = (...args) => {\n this.log('App initialized');\n resolve();\n this.bridge.oninitialized = originalHandler;\n originalHandler?.(...args);\n };\n });\n }\n\n /**\n * Wait for iframe to finish loading\n */\n private onIframeReady(): Promise<void> {\n return new Promise((resolve) => {\n if (this.iframe.contentDocument?.readyState === 'complete') {\n resolve();\n return;\n }\n this.iframe.addEventListener('load', () => resolve(), { once: true });\n });\n }\n\n /**\n * Send tool input arguments to the MCP App.\n * Call this after launch() when tool input is available.\n */\n sendToolInput(args: Record<string, unknown>): void {\n this.log('Sending tool input to app');\n this.bridge.sendToolInput({ arguments: args });\n }\n\n /**\n * Send tool result to the MCP App.\n * Call this when the tool call completes.\n */\n sendToolResult(result: unknown): void {\n this.log('Sending tool result to app');\n this.bridge.sendToolResult(result as any);\n }\n\n /**\n * Send tool cancellation to the MCP App.\n * Call this when the tool call is cancelled or fails.\n */\n sendToolCancelled(reason: string): void {\n this.log('Sending tool cancellation to app');\n this.bridge.sendToolCancelled({ reason });\n }\n\n // ============================================\n // Private: Initialization\n // ============================================\n\n private configureSandbox(): void {\n if (this.iframe.sandbox.value !== SANDBOX_PERMISSIONS) {\n this.iframe.sandbox.value = SANDBOX_PERMISSIONS;\n }\n }\n\n private initializeBridge(): AppBridge {\n const bridge = new AppBridge(\n null,\n HOST_INFO,\n {\n openLinks: {},\n serverTools: {},\n logging: {},\n // Declare support for model context updates\n updateModelContext: { text: {} },\n },\n {\n // Initial host context\n hostContext: {\n theme: 'dark',\n platform: 'web',\n containerDimensions: { maxHeight: 6000 },\n displayMode: 'inline',\n availableDisplayModes: ['inline', 'fullscreen'],\n },\n }\n );\n\n // Register handlers - must be done BEFORE connect()\n bridge.oncalltool = (params) => this.handleToolCall(params);\n bridge.onopenlink = this.handleOpenLink.bind(this);\n bridge.onmessage = this.handleMessage.bind(this);\n bridge.onloggingmessage = (params) => this.log(`App log [${params.level}]: ${params.data}`);\n bridge.onupdatemodelcontext = async () => ({});\n bridge.onsizechange = async ({ width, height }) => {\n if (height !== undefined) this.iframe.style.height = `${height}px`;\n if (width !== undefined) this.iframe.style.minWidth = `min(${width}px, 100%)`;\n return {};\n };\n bridge.onrequestdisplaymode = async (params) => ({\n mode: params.mode === 'fullscreen' ? 'fullscreen' : 'inline'\n });\n\n return bridge;\n }\n\n private async connectBridge(): Promise<void> {\n this.log('Connecting bridge to iframe');\n\n const transport = new PostMessageTransport(\n this.iframe.contentWindow!,\n this.iframe.contentWindow!\n );\n\n try {\n await this.bridge.connect(transport);\n this.log('Bridge connected successfully');\n } catch (error) {\n this.log('Bridge connection failed', 'error');\n throw error;\n }\n }\n\n // ============================================\n // Private: Bridge Event Handlers\n // ============================================\n\n private async handleToolCall(params: ToolCallParams) {\n if (!this.client.isConnected()) {\n throw new Error('Client disconnected');\n }\n\n const sessionId = await this.getSessionId();\n if (!sessionId) {\n throw new Error('No active session');\n }\n\n const result = await this.client.callTool(\n sessionId,\n params.name,\n params.arguments ?? {}\n );\n return result as any;\n }\n\n private async handleOpenLink(params: { url: string }): Promise<Record<string, never>> {\n window.open(params.url, '_blank', 'noopener,noreferrer');\n return {};\n }\n\n private async handleMessage(params: AppMessageParams): Promise<Record<string, never>> {\n this.onAppMessage?.(params);\n return {};\n }\n\n // ============================================\n // Private: Resource Loading\n // ============================================\n\n private async launchMcpApp(uri: string): Promise<void> {\n if (!this.client.isConnected()) {\n throw new Error('Client must be connected');\n }\n\n const sessionId = await this.getSessionId();\n if (!sessionId) {\n throw new Error('No active session');\n }\n\n // Fetch resource using cache hierarchy: SSEClient cache → local cache → direct fetch\n const response = await this.fetchResourceWithCache(sessionId, uri);\n if (!response?.contents?.length) {\n throw new Error(`Empty resource: ${uri}`);\n }\n\n const content = response.contents[0];\n const html = this.decodeContent(content);\n if (!html) {\n throw new Error(`Invalid content in resource: ${uri}`);\n }\n\n // Render via Blob URL for clean isolation\n const blob = new Blob([html], { type: 'text/html' });\n this.iframe.src = URL.createObjectURL(blob);\n }\n\n private async fetchResourceWithCache(sessionId: string, uri: string): Promise<ResourceResponse> {\n // Priority 1: SSEClient's built-in cache (best performance)\n if (this.hasClientCache()) {\n return (this.client as any).getOrFetchResource(sessionId, uri);\n }\n\n // Priority 2: Local preload cache\n const cached = this.resourceCache.get(uri);\n if (cached) {\n const result = await cached;\n if (result) return result;\n }\n\n // Priority 3: Direct fetch\n return this.client.readResource(sessionId, uri) as Promise<ResourceResponse>;\n }\n\n private async preloadResource(uri: string): Promise<ResourceResponse | null> {\n try {\n const sessionId = await this.getSessionId();\n if (!sessionId) return null;\n return await this.client.readResource(sessionId, uri) as ResourceResponse;\n } catch (error) {\n this.log(`Preload failed for ${uri}`, 'warn');\n return null;\n }\n }\n\n // ============================================\n // Private: Utilities\n // ============================================\n\n private async getSessionId(): Promise<string | undefined> {\n if (this.sessionId) return this.sessionId;\n const result = await this.client.getSessions();\n return result.sessions?.[0]?.sessionId;\n }\n\n private isMcpUri(url: string): boolean {\n return MCP_URI_SCHEMES.some(scheme => url.startsWith(scheme));\n }\n\n private hasClientCache(): boolean {\n return 'getOrFetchResource' in this.client &&\n typeof (this.client as any).getOrFetchResource === 'function';\n }\n\n private extractUiResourceUri(tool: { _meta?: unknown }): string | undefined {\n const meta = tool._meta as { ui?: { resourceUri?: string; uri?: string } } | undefined;\n if (!meta?.ui) return undefined;\n return meta.ui.resourceUri ?? meta.ui.uri;\n }\n\n private decodeContent(content: ResourceContent): string | undefined {\n if (content.blob) {\n return atob(content.blob);\n }\n return content.text;\n }\n\n private log(message: string, level: 'info' | 'warn' | 'error' = 'info'): void {\n if (!this.debug && level === 'info') return;\n\n const prefix = '[AppHost]';\n switch (level) {\n case 'warn':\n console.warn(prefix, message);\n break;\n case 'error':\n console.error(prefix, message);\n break;\n default:\n console.log(prefix, message);\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/client/core/sse-client.ts","../../src/client/core/app-host.ts"],"names":["data"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\r\n * Stateless RPC-over-stream client for MCP connections.\r\n *\r\n * Uses single POST requests with `Accept: text/event-stream` for every RPC call.\r\n * Progress events and the final rpc-response are delivered in the same response.\r\n */\r\n\r\nimport { nanoid } from 'nanoid';\r\nimport type {\r\n McpConnectionEvent,\r\n McpObservabilityEvent,\r\n McpAppsUIEvent\r\n} from '../../shared/events.js';\r\nimport type {\r\n McpRpcRequest,\r\n McpRpcResponse,\r\n McpRpcMethod,\r\n McpRpcParams,\r\n ConnectParams,\r\n SessionListResult,\r\n ConnectResult,\r\n DisconnectResult,\r\n RestoreSessionResult,\r\n FinishAuthResult,\r\n ListToolsRpcResult,\r\n ListPromptsResult,\r\n ListResourcesResult,\r\n} from '../../shared/types.js';\r\n\r\nexport interface SSEClientOptions {\r\n /** MCP endpoint URL */\r\n url: string;\r\n\r\n /** User/Client identifier */\r\n identity: string;\r\n\r\n /** Optional auth token for authenticated requests */\r\n authToken?: string;\r\n\r\n /** Callback for MCP connection state changes */\r\n onConnectionEvent?: (event: McpConnectionEvent) => void;\r\n\r\n /** Callback for observability/logging events */\r\n onObservabilityEvent?: (event: McpObservabilityEvent) => void;\r\n\r\n /** Callback for connection status changes */\r\n onStatusChange?: (status: ConnectionStatus) => void;\r\n\r\n /** Callback for MCP App UI events */\r\n onEvent?: (event: McpAppsUIEvent) => void;\r\n\r\n /** Enable debug logging @default false */\r\n debug?: boolean;\r\n}\r\n\r\nexport type ConnectionStatus = 'connecting' | 'connected' | 'disconnected' | 'error';\r\n\r\nconst CONNECTION_EVENT_INTERVAL_MS = 300;\r\n\r\ninterface ToolUiMetadata {\r\n resourceUri?: string;\r\n uri?: string;\r\n visibility?: string[];\r\n}\r\n\r\nexport class SSEClient {\r\n private resourceCache = new Map<string, Promise<unknown>>();\r\n private connected = false;\r\n\r\n constructor(private readonly options: SSEClientOptions) {}\r\n\r\n connect(): void {\r\n if (this.connected) {\r\n return;\r\n }\r\n this.connected = true;\r\n this.options.onStatusChange?.('connected');\r\n this.log('RPC mode: post_stream');\r\n }\r\n\r\n disconnect(): void {\r\n this.connected = false;\r\n this.options.onStatusChange?.('disconnected');\r\n }\r\n\r\n isConnected(): boolean {\r\n return this.connected;\r\n }\r\n\r\n async getSessions(): Promise<SessionListResult> {\r\n return this.sendRequest<SessionListResult>('getSessions');\r\n }\r\n\r\n async connectToServer(params: ConnectParams): Promise<ConnectResult> {\r\n return this.sendRequest<ConnectResult>('connect', params);\r\n }\r\n\r\n async disconnectFromServer(sessionId: string): Promise<DisconnectResult> {\r\n return this.sendRequest<DisconnectResult>('disconnect', { sessionId });\r\n }\r\n\r\n async listTools(sessionId: string): Promise<ListToolsRpcResult> {\r\n return this.sendRequest<ListToolsRpcResult>('listTools', { sessionId });\r\n }\r\n\r\n async callTool(\r\n sessionId: string,\r\n toolName: string,\r\n toolArgs: Record<string, unknown>\r\n ): Promise<unknown> {\r\n const result = await this.sendRequest('callTool', { sessionId, toolName, toolArgs });\r\n this.emitUiEventIfPresent(result, sessionId, toolName);\r\n return result;\r\n }\r\n\r\n async restoreSession(sessionId: string): Promise<RestoreSessionResult> {\r\n return this.sendRequest<RestoreSessionResult>('restoreSession', { sessionId });\r\n }\r\n\r\n async finishAuth(sessionId: string, code: string): Promise<FinishAuthResult> {\r\n return this.sendRequest<FinishAuthResult>('finishAuth', { sessionId, code });\r\n }\r\n\r\n async listPrompts(sessionId: string): Promise<ListPromptsResult> {\r\n return this.sendRequest<ListPromptsResult>('listPrompts', { sessionId });\r\n }\r\n\r\n async getPrompt(sessionId: string, name: string, args?: Record<string, string>): Promise<unknown> {\r\n return this.sendRequest('getPrompt', { sessionId, name, args });\r\n }\r\n\r\n async listResources(sessionId: string): Promise<ListResourcesResult> {\r\n return this.sendRequest<ListResourcesResult>('listResources', { sessionId });\r\n }\r\n\r\n async readResource(sessionId: string, uri: string): Promise<unknown> {\r\n return this.sendRequest('readResource', { sessionId, uri });\r\n }\r\n\r\n preloadToolUiResources(sessionId: string, tools: Array<{ name: string; _meta?: unknown }>): void {\r\n for (const tool of tools) {\r\n const uri = this.extractUiResourceUri(tool);\r\n if (!uri || this.resourceCache.has(uri)) continue;\r\n const promise = this.sendRequest('readResource', { sessionId, uri }).catch((err) => {\r\n this.log(`Failed to preload resource ${uri}: ${err.message}`, 'warn');\r\n this.resourceCache.delete(uri);\r\n return null;\r\n });\r\n this.resourceCache.set(uri, promise);\r\n }\r\n }\r\n\r\n getOrFetchResource(sessionId: string, uri: string): Promise<unknown> {\r\n const cached = this.resourceCache.get(uri);\r\n if (cached) return cached;\r\n const promise = this.sendRequest('readResource', { sessionId, uri });\r\n this.resourceCache.set(uri, promise);\r\n return promise;\r\n }\r\n\r\n hasPreloadedResource(uri: string): boolean {\r\n return this.resourceCache.has(uri);\r\n }\r\n\r\n clearResourceCache(): void {\r\n this.resourceCache.clear();\r\n }\r\n\r\n private async sendRequest<T = unknown>(method: McpRpcMethod, params?: McpRpcParams): Promise<T> {\r\n if (!this.connected) {\r\n this.connect();\r\n }\r\n\r\n this.log(`RPC request via post_stream: ${method}`);\r\n\r\n const request: McpRpcRequest = {\r\n id: `rpc_${nanoid(10)}`,\r\n method,\r\n params,\r\n };\r\n\r\n const response = await fetch(this.buildUrl(), {\r\n method: 'POST',\r\n headers: this.buildHeaders(),\r\n body: JSON.stringify(request),\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\r\n }\r\n\r\n const contentType = (response.headers.get('content-type') || '').toLowerCase();\r\n if (!contentType.includes('text/event-stream')) {\r\n const data = await response.json() as McpRpcResponse;\r\n return this.parseRpcResponse<T>(data);\r\n }\r\n\r\n const data = await this.readRpcResponseFromStream(response, {\r\n delayConnectionEvents:\r\n method === 'connect' ||\r\n method === 'restoreSession' ||\r\n method === 'finishAuth',\r\n });\r\n return this.parseRpcResponse<T>(data);\r\n }\r\n\r\n private async readRpcResponseFromStream(\r\n response: Response,\r\n options: { delayConnectionEvents?: boolean } = {}\r\n ): Promise<McpRpcResponse> {\r\n if (!response.body) {\r\n throw new Error('Streaming response body is missing');\r\n }\r\n\r\n const reader = response.body.getReader();\r\n const decoder = new TextDecoder();\r\n let buffer = '';\r\n let rpcResponse: McpRpcResponse | null = null;\r\n\r\n const dispatchBlock = async (block: string) => {\r\n const lines = block.split('\\n');\r\n let eventName = 'message';\r\n const dataLines: string[] = [];\r\n\r\n for (const rawLine of lines) {\r\n const line = rawLine.replace(/\\r$/, '');\r\n if (!line || line.startsWith(':')) continue;\r\n if (line.startsWith('event:')) {\r\n eventName = line.slice('event:'.length).trim();\r\n continue;\r\n }\r\n if (line.startsWith('data:')) {\r\n dataLines.push(line.slice('data:'.length).trimStart());\r\n }\r\n }\r\n\r\n if (!dataLines.length) return;\r\n const payloadText = dataLines.join('\\n');\r\n let payload: unknown = payloadText;\r\n try {\r\n payload = JSON.parse(payloadText);\r\n } catch {\r\n // Keep raw text\r\n }\r\n\r\n switch (eventName) {\r\n case 'connected':\r\n this.options.onStatusChange?.('connected');\r\n break;\r\n case 'connection':\r\n this.options.onConnectionEvent?.(payload as McpConnectionEvent);\r\n if (options.delayConnectionEvents) {\r\n await this.sleep(CONNECTION_EVENT_INTERVAL_MS);\r\n }\r\n break;\r\n case 'observability':\r\n this.options.onObservabilityEvent?.(payload as McpObservabilityEvent);\r\n break;\r\n case 'rpc-response':\r\n rpcResponse = payload as McpRpcResponse;\r\n break;\r\n default:\r\n break;\r\n }\r\n };\r\n\r\n while (true) {\r\n const { value, done } = await reader.read();\r\n if (done) break;\r\n buffer += decoder.decode(value, { stream: true });\r\n\r\n let separatorMatch = buffer.match(/\\r?\\n\\r?\\n/);\r\n while (separatorMatch && separatorMatch.index !== undefined) {\r\n const separatorIndex = separatorMatch.index;\r\n const separatorLength = separatorMatch[0].length;\r\n const block = buffer.slice(0, separatorIndex);\r\n buffer = buffer.slice(separatorIndex + separatorLength);\r\n await dispatchBlock(block);\r\n separatorMatch = buffer.match(/\\r?\\n\\r?\\n/);\r\n }\r\n }\r\n\r\n if (buffer.trim()) {\r\n await dispatchBlock(buffer);\r\n }\r\n\r\n if (!rpcResponse) {\r\n throw new Error('Missing rpc-response event in streamed RPC result');\r\n }\r\n\r\n return rpcResponse;\r\n }\r\n\r\n private sleep(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n }\r\n\r\n private parseRpcResponse<T>(data: McpRpcResponse): T {\r\n if ('result' in data) {\r\n return data.result as T;\r\n }\r\n if ('error' in data && data.error) {\r\n throw new Error(data.error.message || 'Unknown RPC error');\r\n }\r\n // JSON omits `result` when it is `undefined` (response becomes `{ id: ... }`).\r\n // Treat that shape as a successful void result.\r\n if (data && typeof data === 'object' && 'id' in data) {\r\n return undefined as T;\r\n }\r\n throw new Error('Invalid RPC response format');\r\n }\r\n\r\n private buildUrl(): string {\r\n const url = new URL(this.options.url, globalThis.location?.origin);\r\n url.searchParams.set('identity', this.options.identity);\r\n if (this.options.authToken) {\r\n url.searchParams.set('token', this.options.authToken);\r\n }\r\n return url.toString();\r\n }\r\n\r\n private buildHeaders(): HeadersInit {\r\n const headers: HeadersInit = {\r\n 'Content-Type': 'application/json',\r\n 'Accept': 'text/event-stream',\r\n };\r\n if (this.options.authToken) {\r\n headers['Authorization'] = `Bearer ${this.options.authToken}`;\r\n }\r\n return headers;\r\n }\r\n\r\n private extractUiResourceUri(tool: { name: string; _meta?: unknown }): string | undefined {\r\n const meta = (tool._meta as { ui?: ToolUiMetadata })?.ui;\r\n if (!meta || typeof meta !== 'object') return undefined;\r\n if (meta.visibility && !meta.visibility.includes('app')) return undefined;\r\n return meta.resourceUri ?? meta.uri;\r\n }\r\n\r\n private emitUiEventIfPresent(result: unknown, sessionId: string, toolName: string): void {\r\n const meta = (result as { _meta?: { ui?: ToolUiMetadata } })?._meta;\r\n const resourceUri = meta?.ui?.resourceUri ?? (meta as any)?.['ui/resourceUri'];\r\n\r\n if (resourceUri) {\r\n this.options.onEvent?.({\r\n type: 'mcp-apps-ui',\r\n sessionId,\r\n resourceUri,\r\n toolName,\r\n result,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n }\r\n\r\n private log(message: string, level: 'info' | 'warn' | 'error' = 'info'): void {\r\n if (!this.options.debug && level === 'info') return;\r\n\r\n const prefix = '[SSEClient]';\r\n switch (level) {\r\n case 'warn':\r\n console.warn(prefix, message);\r\n break;\r\n case 'error':\r\n console.error(prefix, message);\r\n break;\r\n default:\r\n console.log(prefix, message);\r\n }\r\n }\r\n}\r\n","/**\r\n * MCP App Host\r\n *\r\n * Bridges the gap between an iframe (MCP App) and the SSEClient (MCP Server).\r\n * Handles secure iframe sandboxing, resource loading, and bi-directional\r\n * communication via the AppBridge protocol.\r\n *\r\n * Key features:\r\n * - Secure iframe sandboxing with minimal permissions\r\n * - Resource preloading for instant MCP App UI loading\r\n * - Cache-aware resource fetching (SSEClient cache → local cache → direct fetch)\r\n * - Support for ui:// and mcp-app:// resource URIs\r\n */\r\n\r\nimport { AppBridge, PostMessageTransport } from '@modelcontextprotocol/ext-apps/app-bridge';\r\nimport type { AppHostClient } from './types';\r\n\r\n// ============================================\r\n// Types & Interfaces\r\n// ============================================\r\n\r\nexport interface AppHostOptions {\r\n /** Enable debug logging @default false */\r\n debug?: boolean;\r\n}\r\n\r\nexport interface AppMessageParams {\r\n role: string;\r\n content: unknown;\r\n}\r\n\r\ninterface ToolCallParams {\r\n name: string;\r\n arguments?: Record<string, unknown>;\r\n}\r\n\r\ninterface ResourceContent {\r\n blob?: string;\r\n text?: string;\r\n}\r\n\r\ninterface ResourceResponse {\r\n contents: ResourceContent[];\r\n}\r\n\r\n// ============================================\r\n// Constants\r\n// ============================================\r\n\r\nconst HOST_INFO = { name: 'mcp-ts-host', version: '1.0.0' };\r\n\r\n/** Sandbox permissions - minimal set required for MCP Apps to function */\r\nconst SANDBOX_PERMISSIONS = [\r\n 'allow-scripts', // Required for app JavaScript execution\r\n 'allow-forms', // Required for form submissions\r\n 'allow-same-origin', // Required for Blob URL correctness\r\n 'allow-modals', // Required for dialogs/alerts\r\n 'allow-popups', // Required for opening links\r\n 'allow-downloads' // Required for file downloads\r\n].join(' ');\r\n\r\n/** Supported MCP App URI schemes */\r\nconst MCP_URI_SCHEMES = ['ui://', 'mcp-app://'] as const;\r\n\r\n// ============================================\r\n// AppHost Class\r\n// ============================================\r\n\r\n/**\r\n * Host for MCP Apps embedded in iframes.\r\n * Manages secure communication between the app and the MCP server.\r\n */\r\nexport class AppHost {\r\n private bridge: AppBridge;\r\n private sessionId?: string;\r\n private resourceCache = new Map<string, Promise<ResourceResponse | null>>();\r\n private debug: boolean;\r\n\r\n /** Callback for app messages (e.g., chat messages from the app) */\r\n public onAppMessage?: (params: AppMessageParams) => void;\r\n\r\n constructor(\r\n private readonly client: AppHostClient,\r\n private readonly iframe: HTMLIFrameElement,\r\n options?: AppHostOptions\r\n ) {\r\n this.debug = options?.debug ?? false;\r\n this.configureSandbox();\r\n this.bridge = this.initializeBridge();\r\n }\r\n\r\n // ============================================\r\n // Public API\r\n // ============================================\r\n\r\n /**\r\n * Start the host. This prepares the bridge handlers but doesn't connect yet.\r\n * The actual connection happens in launch() after HTML is loaded.\r\n * @returns Promise that resolves immediately (bridge connects during launch)\r\n */\r\n async start(): Promise<void> {\r\n // Bridge handlers are already registered in constructor.\r\n // Connection happens in launch() after HTML is loaded.\r\n this.log('Host started, ready to launch');\r\n }\r\n\r\n /**\r\n * Preload UI resources to enable instant app loading.\r\n * Call this when tools are discovered to cache their UI resources.\r\n */\r\n preload(tools: Array<{ _meta?: unknown }>): void {\r\n for (const tool of tools) {\r\n const uri = this.extractUiResourceUri(tool);\r\n if (!uri || this.resourceCache.has(uri)) continue;\r\n\r\n const promise = this.preloadResource(uri);\r\n this.resourceCache.set(uri, promise);\r\n }\r\n }\r\n\r\n /**\r\n * Launch an MCP App from a URL or MCP resource URI.\r\n * Loads the HTML first, then establishes bridge connection.\r\n */\r\n async launch(url: string, sessionId?: string): Promise<void> {\r\n if (sessionId) this.sessionId = sessionId;\r\n\r\n // Set up initialization promise BEFORE connecting\r\n const initializedPromise = this.onAppReady();\r\n\r\n // Load HTML into iframe first\r\n if (this.isMcpUri(url)) {\r\n await this.launchMcpApp(url);\r\n } else {\r\n this.iframe.src = url;\r\n }\r\n\r\n // Wait for iframe to load before connecting bridge\r\n await this.onIframeReady();\r\n\r\n // Connect the bridge (HTML is loaded, contentWindow is ready)\r\n await this.connectBridge();\r\n\r\n // Wait for app to signal it's initialized (with timeout)\r\n this.log('Waiting for app initialization');\r\n await Promise.race([\r\n initializedPromise,\r\n new Promise<void>((resolve) => setTimeout(() => {\r\n this.log('Initialization timeout - continuing anyway', 'warn');\r\n resolve();\r\n }, 3000))\r\n ]);\r\n this.log('App launched and ready');\r\n }\r\n\r\n /**\r\n * Wait for app to signal initialization complete\r\n */\r\n private onAppReady(): Promise<void> {\r\n return new Promise<void>((resolve) => {\r\n const originalHandler = this.bridge.oninitialized;\r\n this.bridge.oninitialized = (...args) => {\r\n this.log('App initialized');\r\n resolve();\r\n this.bridge.oninitialized = originalHandler;\r\n originalHandler?.(...args);\r\n };\r\n });\r\n }\r\n\r\n /**\r\n * Wait for iframe to finish loading\r\n */\r\n private onIframeReady(): Promise<void> {\r\n return new Promise((resolve) => {\r\n if (this.iframe.contentDocument?.readyState === 'complete') {\r\n resolve();\r\n return;\r\n }\r\n this.iframe.addEventListener('load', () => resolve(), { once: true });\r\n });\r\n }\r\n\r\n /**\r\n * Send tool input arguments to the MCP App.\r\n * Call this after launch() when tool input is available.\r\n */\r\n sendToolInput(args: Record<string, unknown>): void {\r\n this.log('Sending tool input to app');\r\n this.bridge.sendToolInput({ arguments: args });\r\n }\r\n\r\n /**\r\n * Send tool result to the MCP App.\r\n * Call this when the tool call completes.\r\n */\r\n sendToolResult(result: unknown): void {\r\n this.log('Sending tool result to app');\r\n this.bridge.sendToolResult(result as any);\r\n }\r\n\r\n /**\r\n * Send tool cancellation to the MCP App.\r\n * Call this when the tool call is cancelled or fails.\r\n */\r\n sendToolCancelled(reason: string): void {\r\n this.log('Sending tool cancellation to app');\r\n this.bridge.sendToolCancelled({ reason });\r\n }\r\n\r\n // ============================================\r\n // Private: Initialization\r\n // ============================================\r\n\r\n private configureSandbox(): void {\r\n if (this.iframe.sandbox.value !== SANDBOX_PERMISSIONS) {\r\n this.iframe.sandbox.value = SANDBOX_PERMISSIONS;\r\n }\r\n }\r\n\r\n private initializeBridge(): AppBridge {\r\n const bridge = new AppBridge(\r\n null,\r\n HOST_INFO,\r\n {\r\n openLinks: {},\r\n serverTools: {},\r\n logging: {},\r\n // Declare support for model context updates\r\n updateModelContext: { text: {} },\r\n },\r\n {\r\n // Initial host context\r\n hostContext: {\r\n theme: 'dark',\r\n platform: 'web',\r\n containerDimensions: { maxHeight: 6000 },\r\n displayMode: 'inline',\r\n availableDisplayModes: ['inline', 'fullscreen'],\r\n },\r\n }\r\n );\r\n\r\n // Register handlers - must be done BEFORE connect()\r\n bridge.oncalltool = (params) => this.handleToolCall(params);\r\n bridge.onopenlink = this.handleOpenLink.bind(this);\r\n bridge.onmessage = this.handleMessage.bind(this);\r\n bridge.onloggingmessage = (params) => this.log(`App log [${params.level}]: ${params.data}`);\r\n bridge.onupdatemodelcontext = async () => ({});\r\n bridge.onsizechange = async ({ width, height }) => {\r\n if (height !== undefined) this.iframe.style.height = `${height}px`;\r\n if (width !== undefined) this.iframe.style.minWidth = `min(${width}px, 100%)`;\r\n return {};\r\n };\r\n bridge.onrequestdisplaymode = async (params) => ({\r\n mode: params.mode === 'fullscreen' ? 'fullscreen' : 'inline'\r\n });\r\n\r\n return bridge;\r\n }\r\n\r\n private async connectBridge(): Promise<void> {\r\n this.log('Connecting bridge to iframe');\r\n\r\n const transport = new PostMessageTransport(\r\n this.iframe.contentWindow!,\r\n this.iframe.contentWindow!\r\n );\r\n\r\n try {\r\n await this.bridge.connect(transport);\r\n this.log('Bridge connected successfully');\r\n } catch (error) {\r\n this.log('Bridge connection failed', 'error');\r\n throw error;\r\n }\r\n }\r\n\r\n // ============================================\r\n // Private: Bridge Event Handlers\r\n // ============================================\r\n\r\n private async handleToolCall(params: ToolCallParams) {\r\n if (!this.client.isConnected()) {\r\n throw new Error('Client disconnected');\r\n }\r\n\r\n const sessionId = await this.getSessionId();\r\n if (!sessionId) {\r\n throw new Error('No active session');\r\n }\r\n\r\n const result = await this.client.callTool(\r\n sessionId,\r\n params.name,\r\n params.arguments ?? {}\r\n );\r\n return result as any;\r\n }\r\n\r\n private async handleOpenLink(params: { url: string }): Promise<Record<string, never>> {\r\n window.open(params.url, '_blank', 'noopener,noreferrer');\r\n return {};\r\n }\r\n\r\n private async handleMessage(params: AppMessageParams): Promise<Record<string, never>> {\r\n this.onAppMessage?.(params);\r\n return {};\r\n }\r\n\r\n // ============================================\r\n // Private: Resource Loading\r\n // ============================================\r\n\r\n private async launchMcpApp(uri: string): Promise<void> {\r\n if (!this.client.isConnected()) {\r\n throw new Error('Client must be connected');\r\n }\r\n\r\n const sessionId = await this.getSessionId();\r\n if (!sessionId) {\r\n throw new Error('No active session');\r\n }\r\n\r\n // Fetch resource using cache hierarchy: SSEClient cache → local cache → direct fetch\r\n const response = await this.fetchResourceWithCache(sessionId, uri);\r\n if (!response?.contents?.length) {\r\n throw new Error(`Empty resource: ${uri}`);\r\n }\r\n\r\n const content = response.contents[0];\r\n const html = this.decodeContent(content);\r\n if (!html) {\r\n throw new Error(`Invalid content in resource: ${uri}`);\r\n }\r\n\r\n // Render via Blob URL for clean isolation\r\n const blob = new Blob([html], { type: 'text/html' });\r\n this.iframe.src = URL.createObjectURL(blob);\r\n }\r\n\r\n private async fetchResourceWithCache(sessionId: string, uri: string): Promise<ResourceResponse> {\r\n // Priority 1: SSEClient's built-in cache (best performance)\r\n if (this.hasClientCache()) {\r\n return (this.client as any).getOrFetchResource(sessionId, uri);\r\n }\r\n\r\n // Priority 2: Local preload cache\r\n const cached = this.resourceCache.get(uri);\r\n if (cached) {\r\n const result = await cached;\r\n if (result) return result;\r\n }\r\n\r\n // Priority 3: Direct fetch\r\n return this.client.readResource(sessionId, uri) as Promise<ResourceResponse>;\r\n }\r\n\r\n private async preloadResource(uri: string): Promise<ResourceResponse | null> {\r\n try {\r\n const sessionId = await this.getSessionId();\r\n if (!sessionId) return null;\r\n return await this.client.readResource(sessionId, uri) as ResourceResponse;\r\n } catch (error) {\r\n this.log(`Preload failed for ${uri}`, 'warn');\r\n return null;\r\n }\r\n }\r\n\r\n // ============================================\r\n // Private: Utilities\r\n // ============================================\r\n\r\n private async getSessionId(): Promise<string | undefined> {\r\n if (this.sessionId) return this.sessionId;\r\n const result = await this.client.getSessions();\r\n return result.sessions?.[0]?.sessionId;\r\n }\r\n\r\n private isMcpUri(url: string): boolean {\r\n return MCP_URI_SCHEMES.some(scheme => url.startsWith(scheme));\r\n }\r\n\r\n private hasClientCache(): boolean {\r\n return 'getOrFetchResource' in this.client &&\r\n typeof (this.client as any).getOrFetchResource === 'function';\r\n }\r\n\r\n private extractUiResourceUri(tool: { _meta?: unknown }): string | undefined {\r\n const meta = tool._meta as { ui?: { resourceUri?: string; uri?: string } } | undefined;\r\n if (!meta?.ui) return undefined;\r\n return meta.ui.resourceUri ?? meta.ui.uri;\r\n }\r\n\r\n private decodeContent(content: ResourceContent): string | undefined {\r\n if (content.blob) {\r\n return atob(content.blob);\r\n }\r\n return content.text;\r\n }\r\n\r\n private log(message: string, level: 'info' | 'warn' | 'error' = 'info'): void {\r\n if (!this.debug && level === 'info') return;\r\n\r\n const prefix = '[AppHost]';\r\n switch (level) {\r\n case 'warn':\r\n console.warn(prefix, message);\r\n break;\r\n case 'error':\r\n console.error(prefix, message);\r\n break;\r\n default:\r\n console.log(prefix, message);\r\n }\r\n }\r\n}\r\n"]}
1
+ {"version":3,"sources":["../../src/client/core/sse-client.ts","../../src/client/core/app-host.ts"],"names":["data"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Stateless RPC-over-stream client for MCP connections.\n *\n * Uses single POST requests with `Accept: text/event-stream` for every RPC call.\n * Progress events and the final rpc-response are delivered in the same response.\n */\n\nimport { nanoid } from 'nanoid';\nimport type {\n McpConnectionEvent,\n McpObservabilityEvent,\n McpAppsUIEvent\n} from '../../shared/events.js';\nimport type {\n McpRpcRequest,\n McpRpcResponse,\n McpRpcMethod,\n McpRpcParams,\n ConnectParams,\n SessionListResult,\n ConnectResult,\n DisconnectResult,\n RestoreSessionResult,\n FinishAuthResult,\n ListToolsRpcResult,\n ListPromptsResult,\n ListResourcesResult,\n} from '../../shared/types.js';\n\nexport interface SSEClientOptions {\n /** MCP endpoint URL */\n url: string;\n\n /** User/Client identifier */\n identity: string;\n\n /** Optional auth token for authenticated requests */\n authToken?: string;\n\n /** Callback for MCP connection state changes */\n onConnectionEvent?: (event: McpConnectionEvent) => void;\n\n /** Callback for observability/logging events */\n onObservabilityEvent?: (event: McpObservabilityEvent) => void;\n\n /** Callback for connection status changes */\n onStatusChange?: (status: ConnectionStatus) => void;\n\n /** Callback for MCP App UI events */\n onEvent?: (event: McpAppsUIEvent) => void;\n\n /** Enable debug logging @default false */\n debug?: boolean;\n}\n\nexport type ConnectionStatus = 'connecting' | 'connected' | 'disconnected' | 'error';\n\nconst CONNECTION_EVENT_INTERVAL_MS = 300;\n\ninterface ToolUiMetadata {\n resourceUri?: string;\n uri?: string;\n visibility?: string[];\n}\n\nexport class SSEClient {\n private resourceCache = new Map<string, Promise<unknown>>();\n private connected = false;\n\n constructor(private readonly options: SSEClientOptions) {}\n\n connect(): void {\n if (this.connected) {\n return;\n }\n this.connected = true;\n this.options.onStatusChange?.('connected');\n this.log('RPC mode: post_stream');\n }\n\n disconnect(): void {\n this.connected = false;\n this.options.onStatusChange?.('disconnected');\n }\n\n isConnected(): boolean {\n return this.connected;\n }\n\n async getSessions(): Promise<SessionListResult> {\n return this.sendRequest<SessionListResult>('getSessions');\n }\n\n async connectToServer(params: ConnectParams): Promise<ConnectResult> {\n return this.sendRequest<ConnectResult>('connect', params);\n }\n\n async disconnectFromServer(sessionId: string): Promise<DisconnectResult> {\n return this.sendRequest<DisconnectResult>('disconnect', { sessionId });\n }\n\n async listTools(sessionId: string): Promise<ListToolsRpcResult> {\n return this.sendRequest<ListToolsRpcResult>('listTools', { sessionId });\n }\n\n async callTool(\n sessionId: string,\n toolName: string,\n toolArgs: Record<string, unknown>\n ): Promise<unknown> {\n const result = await this.sendRequest('callTool', { sessionId, toolName, toolArgs });\n this.emitUiEventIfPresent(result, sessionId, toolName);\n return result;\n }\n\n async restoreSession(sessionId: string): Promise<RestoreSessionResult> {\n return this.sendRequest<RestoreSessionResult>('restoreSession', { sessionId });\n }\n\n async finishAuth(sessionId: string, code: string): Promise<FinishAuthResult> {\n return this.sendRequest<FinishAuthResult>('finishAuth', { sessionId, code });\n }\n\n async listPrompts(sessionId: string): Promise<ListPromptsResult> {\n return this.sendRequest<ListPromptsResult>('listPrompts', { sessionId });\n }\n\n async getPrompt(sessionId: string, name: string, args?: Record<string, string>): Promise<unknown> {\n return this.sendRequest('getPrompt', { sessionId, name, args });\n }\n\n async listResources(sessionId: string): Promise<ListResourcesResult> {\n return this.sendRequest<ListResourcesResult>('listResources', { sessionId });\n }\n\n async readResource(sessionId: string, uri: string): Promise<unknown> {\n return this.sendRequest('readResource', { sessionId, uri });\n }\n\n preloadToolUiResources(sessionId: string, tools: Array<{ name: string; _meta?: unknown }>): void {\n for (const tool of tools) {\n const uri = this.extractUiResourceUri(tool);\n if (!uri || this.resourceCache.has(uri)) continue;\n const promise = this.sendRequest('readResource', { sessionId, uri }).catch((err) => {\n this.log(`Failed to preload resource ${uri}: ${err.message}`, 'warn');\n this.resourceCache.delete(uri);\n return null;\n });\n this.resourceCache.set(uri, promise);\n }\n }\n\n getOrFetchResource(sessionId: string, uri: string): Promise<unknown> {\n const cached = this.resourceCache.get(uri);\n if (cached) return cached;\n const promise = this.sendRequest('readResource', { sessionId, uri });\n this.resourceCache.set(uri, promise);\n return promise;\n }\n\n hasPreloadedResource(uri: string): boolean {\n return this.resourceCache.has(uri);\n }\n\n clearResourceCache(): void {\n this.resourceCache.clear();\n }\n\n private async sendRequest<T = unknown>(method: McpRpcMethod, params?: McpRpcParams): Promise<T> {\n if (!this.connected) {\n this.connect();\n }\n\n this.log(`RPC request via post_stream: ${method}`);\n\n const request: McpRpcRequest = {\n id: `rpc_${nanoid(10)}`,\n method,\n params,\n };\n\n const response = await fetch(this.buildUrl(), {\n method: 'POST',\n headers: this.buildHeaders(),\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const contentType = (response.headers.get('content-type') || '').toLowerCase();\n if (!contentType.includes('text/event-stream')) {\n const data = await response.json() as McpRpcResponse;\n return this.parseRpcResponse<T>(data);\n }\n\n const data = await this.readRpcResponseFromStream(response, {\n delayConnectionEvents:\n method === 'connect' ||\n method === 'restoreSession' ||\n method === 'finishAuth',\n });\n return this.parseRpcResponse<T>(data);\n }\n\n private async readRpcResponseFromStream(\n response: Response,\n options: { delayConnectionEvents?: boolean } = {}\n ): Promise<McpRpcResponse> {\n if (!response.body) {\n throw new Error('Streaming response body is missing');\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n let rpcResponse: McpRpcResponse | null = null;\n\n const dispatchBlock = async (block: string) => {\n const lines = block.split('\\n');\n let eventName = 'message';\n const dataLines: string[] = [];\n\n for (const rawLine of lines) {\n const line = rawLine.replace(/\\r$/, '');\n if (!line || line.startsWith(':')) continue;\n if (line.startsWith('event:')) {\n eventName = line.slice('event:'.length).trim();\n continue;\n }\n if (line.startsWith('data:')) {\n dataLines.push(line.slice('data:'.length).trimStart());\n }\n }\n\n if (!dataLines.length) return;\n const payloadText = dataLines.join('\\n');\n let payload: unknown = payloadText;\n try {\n payload = JSON.parse(payloadText);\n } catch {\n // Keep raw text\n }\n\n switch (eventName) {\n case 'connected':\n this.options.onStatusChange?.('connected');\n break;\n case 'connection':\n this.options.onConnectionEvent?.(payload as McpConnectionEvent);\n if (options.delayConnectionEvents) {\n await this.sleep(CONNECTION_EVENT_INTERVAL_MS);\n }\n break;\n case 'observability':\n this.options.onObservabilityEvent?.(payload as McpObservabilityEvent);\n break;\n case 'rpc-response':\n rpcResponse = payload as McpRpcResponse;\n break;\n default:\n break;\n }\n };\n\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n\n let separatorMatch = buffer.match(/\\r?\\n\\r?\\n/);\n while (separatorMatch && separatorMatch.index !== undefined) {\n const separatorIndex = separatorMatch.index;\n const separatorLength = separatorMatch[0].length;\n const block = buffer.slice(0, separatorIndex);\n buffer = buffer.slice(separatorIndex + separatorLength);\n await dispatchBlock(block);\n separatorMatch = buffer.match(/\\r?\\n\\r?\\n/);\n }\n }\n\n if (buffer.trim()) {\n await dispatchBlock(buffer);\n }\n\n if (!rpcResponse) {\n throw new Error('Missing rpc-response event in streamed RPC result');\n }\n\n return rpcResponse;\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n private parseRpcResponse<T>(data: McpRpcResponse): T {\n if ('result' in data) {\n return data.result as T;\n }\n if ('error' in data && data.error) {\n throw new Error(data.error.message || 'Unknown RPC error');\n }\n // JSON omits `result` when it is `undefined` (response becomes `{ id: ... }`).\n // Treat that shape as a successful void result.\n if (data && typeof data === 'object' && 'id' in data) {\n return undefined as T;\n }\n throw new Error('Invalid RPC response format');\n }\n\n private buildUrl(): string {\n const url = new URL(this.options.url, globalThis.location?.origin);\n url.searchParams.set('identity', this.options.identity);\n if (this.options.authToken) {\n url.searchParams.set('token', this.options.authToken);\n }\n return url.toString();\n }\n\n private buildHeaders(): HeadersInit {\n const headers: HeadersInit = {\n 'Content-Type': 'application/json',\n 'Accept': 'text/event-stream',\n };\n if (this.options.authToken) {\n headers['Authorization'] = `Bearer ${this.options.authToken}`;\n }\n return headers;\n }\n\n private extractUiResourceUri(tool: { name: string; _meta?: unknown }): string | undefined {\n const meta = (tool._meta as { ui?: ToolUiMetadata })?.ui;\n if (!meta || typeof meta !== 'object') return undefined;\n if (meta.visibility && !meta.visibility.includes('app')) return undefined;\n return meta.resourceUri ?? meta.uri;\n }\n\n private emitUiEventIfPresent(result: unknown, sessionId: string, toolName: string): void {\n const meta = (result as { _meta?: { ui?: ToolUiMetadata } })?._meta;\n const resourceUri = meta?.ui?.resourceUri ?? (meta as any)?.['ui/resourceUri'];\n\n if (resourceUri) {\n this.options.onEvent?.({\n type: 'mcp-apps-ui',\n sessionId,\n resourceUri,\n toolName,\n result,\n timestamp: Date.now(),\n });\n }\n }\n\n private log(message: string, level: 'info' | 'warn' | 'error' = 'info'): void {\n if (!this.options.debug && level === 'info') return;\n\n const prefix = '[SSEClient]';\n switch (level) {\n case 'warn':\n console.warn(prefix, message);\n break;\n case 'error':\n console.error(prefix, message);\n break;\n default:\n console.log(prefix, message);\n }\n }\n}\n","/**\n * MCP App Host\n *\n * Bridges the gap between an iframe (MCP App) and the SSEClient (MCP Server).\n * Handles secure iframe sandboxing, resource loading, and bi-directional\n * communication via the AppBridge protocol.\n *\n * Key features:\n * - Secure iframe sandboxing with minimal permissions\n * - Resource preloading for instant MCP App UI loading\n * - Cache-aware resource fetching (SSEClient cache → local cache → direct fetch)\n * - Support for ui:// and mcp-app:// resource URIs\n */\n\nimport { AppBridge, PostMessageTransport } from '@modelcontextprotocol/ext-apps/app-bridge';\nimport type { AppHostClient } from './types';\n\n// ============================================\n// Types & Interfaces\n// ============================================\n\nexport interface AppHostOptions {\n /** Enable debug logging @default false */\n debug?: boolean;\n}\n\nexport interface AppMessageParams {\n role: string;\n content: unknown;\n}\n\ninterface ToolCallParams {\n name: string;\n arguments?: Record<string, unknown>;\n}\n\ninterface ResourceContent {\n blob?: string;\n text?: string;\n}\n\ninterface ResourceResponse {\n contents: ResourceContent[];\n}\n\n// ============================================\n// Constants\n// ============================================\n\nconst HOST_INFO = { name: 'mcp-ts-host', version: '1.0.0' };\n\n/** Sandbox permissions - minimal set required for MCP Apps to function */\nconst SANDBOX_PERMISSIONS = [\n 'allow-scripts', // Required for app JavaScript execution\n 'allow-forms', // Required for form submissions\n 'allow-same-origin', // Required for Blob URL correctness\n 'allow-modals', // Required for dialogs/alerts\n 'allow-popups', // Required for opening links\n 'allow-downloads' // Required for file downloads\n].join(' ');\n\n/** Supported MCP App URI schemes */\nconst MCP_URI_SCHEMES = ['ui://', 'mcp-app://'] as const;\n\n// ============================================\n// AppHost Class\n// ============================================\n\n/**\n * Host for MCP Apps embedded in iframes.\n * Manages secure communication between the app and the MCP server.\n */\nexport class AppHost {\n private bridge: AppBridge;\n private sessionId?: string;\n private resourceCache = new Map<string, Promise<ResourceResponse | null>>();\n private debug: boolean;\n\n /** Callback for app messages (e.g., chat messages from the app) */\n public onAppMessage?: (params: AppMessageParams) => void;\n\n constructor(\n private readonly client: AppHostClient,\n private readonly iframe: HTMLIFrameElement,\n options?: AppHostOptions\n ) {\n this.debug = options?.debug ?? false;\n this.configureSandbox();\n this.bridge = this.initializeBridge();\n }\n\n // ============================================\n // Public API\n // ============================================\n\n /**\n * Start the host. This prepares the bridge handlers but doesn't connect yet.\n * The actual connection happens in launch() after HTML is loaded.\n * @returns Promise that resolves immediately (bridge connects during launch)\n */\n async start(): Promise<void> {\n // Bridge handlers are already registered in constructor.\n // Connection happens in launch() after HTML is loaded.\n this.log('Host started, ready to launch');\n }\n\n /**\n * Preload UI resources to enable instant app loading.\n * Call this when tools are discovered to cache their UI resources.\n */\n preload(tools: Array<{ _meta?: unknown }>): void {\n for (const tool of tools) {\n const uri = this.extractUiResourceUri(tool);\n if (!uri || this.resourceCache.has(uri)) continue;\n\n const promise = this.preloadResource(uri);\n this.resourceCache.set(uri, promise);\n }\n }\n\n /**\n * Launch an MCP App from a URL or MCP resource URI.\n * Loads the HTML first, then establishes bridge connection.\n */\n async launch(url: string, sessionId?: string): Promise<void> {\n if (sessionId) this.sessionId = sessionId;\n\n // Set up initialization promise BEFORE connecting\n const initializedPromise = this.onAppReady();\n\n // Load HTML into iframe first\n if (this.isMcpUri(url)) {\n await this.launchMcpApp(url);\n } else {\n this.iframe.src = url;\n }\n\n // Wait for iframe to load before connecting bridge\n await this.onIframeReady();\n\n // Connect the bridge (HTML is loaded, contentWindow is ready)\n await this.connectBridge();\n\n // Wait for app to signal it's initialized (with timeout)\n this.log('Waiting for app initialization');\n await Promise.race([\n initializedPromise,\n new Promise<void>((resolve) => setTimeout(() => {\n this.log('Initialization timeout - continuing anyway', 'warn');\n resolve();\n }, 3000))\n ]);\n this.log('App launched and ready');\n }\n\n /**\n * Wait for app to signal initialization complete\n */\n private onAppReady(): Promise<void> {\n return new Promise<void>((resolve) => {\n const originalHandler = this.bridge.oninitialized;\n this.bridge.oninitialized = (...args) => {\n this.log('App initialized');\n resolve();\n this.bridge.oninitialized = originalHandler;\n originalHandler?.(...args);\n };\n });\n }\n\n /**\n * Wait for iframe to finish loading\n */\n private onIframeReady(): Promise<void> {\n return new Promise((resolve) => {\n if (this.iframe.contentDocument?.readyState === 'complete') {\n resolve();\n return;\n }\n this.iframe.addEventListener('load', () => resolve(), { once: true });\n });\n }\n\n /**\n * Send tool input arguments to the MCP App.\n * Call this after launch() when tool input is available.\n */\n sendToolInput(args: Record<string, unknown>): void {\n this.log('Sending tool input to app');\n this.bridge.sendToolInput({ arguments: args });\n }\n\n /**\n * Send tool result to the MCP App.\n * Call this when the tool call completes.\n */\n sendToolResult(result: unknown): void {\n this.log('Sending tool result to app');\n this.bridge.sendToolResult(result as any);\n }\n\n /**\n * Send tool cancellation to the MCP App.\n * Call this when the tool call is cancelled or fails.\n */\n sendToolCancelled(reason: string): void {\n this.log('Sending tool cancellation to app');\n this.bridge.sendToolCancelled({ reason });\n }\n\n // ============================================\n // Private: Initialization\n // ============================================\n\n private configureSandbox(): void {\n if (this.iframe.sandbox.value !== SANDBOX_PERMISSIONS) {\n this.iframe.sandbox.value = SANDBOX_PERMISSIONS;\n }\n }\n\n private initializeBridge(): AppBridge {\n const bridge = new AppBridge(\n null,\n HOST_INFO,\n {\n openLinks: {},\n serverTools: {},\n logging: {},\n // Declare support for model context updates\n updateModelContext: { text: {} },\n },\n {\n // Initial host context\n hostContext: {\n theme: 'dark',\n platform: 'web',\n containerDimensions: { maxHeight: 6000 },\n displayMode: 'inline',\n availableDisplayModes: ['inline', 'fullscreen'],\n },\n }\n );\n\n // Register handlers - must be done BEFORE connect()\n bridge.oncalltool = (params) => this.handleToolCall(params);\n bridge.onopenlink = this.handleOpenLink.bind(this);\n bridge.onmessage = this.handleMessage.bind(this);\n bridge.onloggingmessage = (params) => this.log(`App log [${params.level}]: ${params.data}`);\n bridge.onupdatemodelcontext = async () => ({});\n bridge.onsizechange = async ({ width, height }) => {\n if (height !== undefined) this.iframe.style.height = `${height}px`;\n if (width !== undefined) this.iframe.style.minWidth = `min(${width}px, 100%)`;\n return {};\n };\n bridge.onrequestdisplaymode = async (params) => ({\n mode: params.mode === 'fullscreen' ? 'fullscreen' : 'inline'\n });\n\n return bridge;\n }\n\n private async connectBridge(): Promise<void> {\n this.log('Connecting bridge to iframe');\n\n const transport = new PostMessageTransport(\n this.iframe.contentWindow!,\n this.iframe.contentWindow!\n );\n\n try {\n await this.bridge.connect(transport);\n this.log('Bridge connected successfully');\n } catch (error) {\n this.log('Bridge connection failed', 'error');\n throw error;\n }\n }\n\n // ============================================\n // Private: Bridge Event Handlers\n // ============================================\n\n private async handleToolCall(params: ToolCallParams) {\n if (!this.client.isConnected()) {\n throw new Error('Client disconnected');\n }\n\n const sessionId = await this.getSessionId();\n if (!sessionId) {\n throw new Error('No active session');\n }\n\n const result = await this.client.callTool(\n sessionId,\n params.name,\n params.arguments ?? {}\n );\n return result as any;\n }\n\n private async handleOpenLink(params: { url: string }): Promise<Record<string, never>> {\n window.open(params.url, '_blank', 'noopener,noreferrer');\n return {};\n }\n\n private async handleMessage(params: AppMessageParams): Promise<Record<string, never>> {\n this.onAppMessage?.(params);\n return {};\n }\n\n // ============================================\n // Private: Resource Loading\n // ============================================\n\n private async launchMcpApp(uri: string): Promise<void> {\n if (!this.client.isConnected()) {\n throw new Error('Client must be connected');\n }\n\n const sessionId = await this.getSessionId();\n if (!sessionId) {\n throw new Error('No active session');\n }\n\n // Fetch resource using cache hierarchy: SSEClient cache → local cache → direct fetch\n const response = await this.fetchResourceWithCache(sessionId, uri);\n if (!response?.contents?.length) {\n throw new Error(`Empty resource: ${uri}`);\n }\n\n const content = response.contents[0];\n const html = this.decodeContent(content);\n if (!html) {\n throw new Error(`Invalid content in resource: ${uri}`);\n }\n\n // Render via Blob URL for clean isolation\n const blob = new Blob([html], { type: 'text/html' });\n this.iframe.src = URL.createObjectURL(blob);\n }\n\n private async fetchResourceWithCache(sessionId: string, uri: string): Promise<ResourceResponse> {\n // Priority 1: SSEClient's built-in cache (best performance)\n if (this.hasClientCache()) {\n return (this.client as any).getOrFetchResource(sessionId, uri);\n }\n\n // Priority 2: Local preload cache\n const cached = this.resourceCache.get(uri);\n if (cached) {\n const result = await cached;\n if (result) return result;\n }\n\n // Priority 3: Direct fetch\n return this.client.readResource(sessionId, uri) as Promise<ResourceResponse>;\n }\n\n private async preloadResource(uri: string): Promise<ResourceResponse | null> {\n try {\n const sessionId = await this.getSessionId();\n if (!sessionId) return null;\n return await this.client.readResource(sessionId, uri) as ResourceResponse;\n } catch (error) {\n this.log(`Preload failed for ${uri}`, 'warn');\n return null;\n }\n }\n\n // ============================================\n // Private: Utilities\n // ============================================\n\n private async getSessionId(): Promise<string | undefined> {\n if (this.sessionId) return this.sessionId;\n const result = await this.client.getSessions();\n return result.sessions?.[0]?.sessionId;\n }\n\n private isMcpUri(url: string): boolean {\n return MCP_URI_SCHEMES.some(scheme => url.startsWith(scheme));\n }\n\n private hasClientCache(): boolean {\n return 'getOrFetchResource' in this.client &&\n typeof (this.client as any).getOrFetchResource === 'function';\n }\n\n private extractUiResourceUri(tool: { _meta?: unknown }): string | undefined {\n const meta = tool._meta as { ui?: { resourceUri?: string; uri?: string } } | undefined;\n if (!meta?.ui) return undefined;\n return meta.ui.resourceUri ?? meta.ui.uri;\n }\n\n private decodeContent(content: ResourceContent): string | undefined {\n if (content.blob) {\n return atob(content.blob);\n }\n return content.text;\n }\n\n private log(message: string, level: 'info' | 'warn' | 'error' = 'info'): void {\n if (!this.debug && level === 'info') return;\n\n const prefix = '[AppHost]';\n switch (level) {\n case 'warn':\n console.warn(prefix, message);\n break;\n case 'error':\n console.error(prefix, message);\n break;\n default:\n console.log(prefix, message);\n }\n }\n}\n"]}
@@ -172,10 +172,11 @@ declare function useMcp(options: UseMcpOptions): McpClient$1;
172
172
  /**
173
173
  * Hook to host an MCP App in a React component
174
174
  *
175
- * Optimized for instant loading:
176
- * - Creates AppHost synchronously
177
- * - Starts bridge connection immediately
178
- * - Returns host before connection completes (ready to call launch)
175
+ * Initialization is async but optimized for instant availability:
176
+ * - Constructor runs synchronously (sandbox + bridge handler setup)
177
+ * - Host is set in state immediately so launch() can be called right away
178
+ * - start() is a lightweight no-op reserved for future async pre-init work
179
+ * - The real async work (iframe load, bridge connect) happens inside launch()
179
180
  *
180
181
  * @param client - Connected SSEClient instance
181
182
  * @param iframeRef - Reference to the iframe element
@@ -222,42 +223,23 @@ interface McpAppMetadata {
222
223
  resourceUri: string;
223
224
  sessionId: string;
224
225
  }
226
+ /** Props for {@link useMcpApps}'s `McpAppRenderer` (client is supplied via the hook). */
225
227
  interface McpAppRendererProps {
226
- metadata: McpAppMetadata;
228
+ name: string;
227
229
  input?: Record<string, unknown>;
228
230
  result?: unknown;
229
231
  status: 'executing' | 'inProgress' | 'complete' | 'idle';
230
- sseClient?: SSEClient | null;
231
232
  /** Custom CSS class for the container */
232
233
  className?: string;
233
234
  }
234
235
  /**
235
- * Simple hook to get MCP app metadata
236
- *
237
- * @param mcpClient - The MCP client from useMcp() or context
238
- * @returns Object with getAppMetadata function and McpAppRenderer component
239
- *
240
- * @example
241
- * ```tsx
242
- * function ToolRenderer(props) {
243
- * const { getAppMetadata, McpAppRenderer } = useMcpApps(mcpClient);
244
- * const metadata = getAppMetadata(props.name);
236
+ * Helpers scoped to one `mcpClient`. Pass the client here once; `McpAppRenderer` only needs per-tool props (`name`, `input`, `result`, `status`).
245
237
  *
246
- * if (!metadata) return null;
247
- * return (
248
- * <McpAppRenderer
249
- * metadata={metadata}
250
- * input={props.args}
251
- * result={props.result}
252
- * status={props.status}
253
- * />
254
- * );
255
- * }
256
- * ```
238
+ * @param mcpClient - From `useMcp()` or context (for example `useMcpContext()`).
257
239
  */
258
240
  declare function useMcpApps(mcpClient: McpClient | null): {
259
241
  getAppMetadata: (toolName: string) => McpAppMetadata | undefined;
260
242
  McpAppRenderer: React$1.NamedExoticComponent<McpAppRendererProps>;
261
243
  };
262
244
 
263
- export { AppHost, type McpClient$1 as McpClient, type McpConnection, McpConnectionEvent, McpConnectionState, SSEClient, ToolInfo, type UseMcpOptions, useAppHost, useMcp, useMcpApps };
245
+ export { AppHost, type McpAppMetadata, type McpAppRendererProps, type McpClient$1 as McpClient, type McpConnection, McpConnectionEvent, McpConnectionState, SSEClient, ToolInfo, type UseMcpOptions, useAppHost, useMcp, useMcpApps };
@@ -172,10 +172,11 @@ declare function useMcp(options: UseMcpOptions): McpClient$1;
172
172
  /**
173
173
  * Hook to host an MCP App in a React component
174
174
  *
175
- * Optimized for instant loading:
176
- * - Creates AppHost synchronously
177
- * - Starts bridge connection immediately
178
- * - Returns host before connection completes (ready to call launch)
175
+ * Initialization is async but optimized for instant availability:
176
+ * - Constructor runs synchronously (sandbox + bridge handler setup)
177
+ * - Host is set in state immediately so launch() can be called right away
178
+ * - start() is a lightweight no-op reserved for future async pre-init work
179
+ * - The real async work (iframe load, bridge connect) happens inside launch()
179
180
  *
180
181
  * @param client - Connected SSEClient instance
181
182
  * @param iframeRef - Reference to the iframe element
@@ -222,42 +223,23 @@ interface McpAppMetadata {
222
223
  resourceUri: string;
223
224
  sessionId: string;
224
225
  }
226
+ /** Props for {@link useMcpApps}'s `McpAppRenderer` (client is supplied via the hook). */
225
227
  interface McpAppRendererProps {
226
- metadata: McpAppMetadata;
228
+ name: string;
227
229
  input?: Record<string, unknown>;
228
230
  result?: unknown;
229
231
  status: 'executing' | 'inProgress' | 'complete' | 'idle';
230
- sseClient?: SSEClient | null;
231
232
  /** Custom CSS class for the container */
232
233
  className?: string;
233
234
  }
234
235
  /**
235
- * Simple hook to get MCP app metadata
236
- *
237
- * @param mcpClient - The MCP client from useMcp() or context
238
- * @returns Object with getAppMetadata function and McpAppRenderer component
239
- *
240
- * @example
241
- * ```tsx
242
- * function ToolRenderer(props) {
243
- * const { getAppMetadata, McpAppRenderer } = useMcpApps(mcpClient);
244
- * const metadata = getAppMetadata(props.name);
236
+ * Helpers scoped to one `mcpClient`. Pass the client here once; `McpAppRenderer` only needs per-tool props (`name`, `input`, `result`, `status`).
245
237
  *
246
- * if (!metadata) return null;
247
- * return (
248
- * <McpAppRenderer
249
- * metadata={metadata}
250
- * input={props.args}
251
- * result={props.result}
252
- * status={props.status}
253
- * />
254
- * );
255
- * }
256
- * ```
238
+ * @param mcpClient - From `useMcp()` or context (for example `useMcpContext()`).
257
239
  */
258
240
  declare function useMcpApps(mcpClient: McpClient | null): {
259
241
  getAppMetadata: (toolName: string) => McpAppMetadata | undefined;
260
242
  McpAppRenderer: React$1.NamedExoticComponent<McpAppRendererProps>;
261
243
  };
262
244
 
263
- export { AppHost, type McpClient$1 as McpClient, type McpConnection, McpConnectionEvent, McpConnectionState, SSEClient, ToolInfo, type UseMcpOptions, useAppHost, useMcp, useMcpApps };
245
+ export { AppHost, type McpAppMetadata, type McpAppRendererProps, type McpClient$1 as McpClient, type McpConnection, McpConnectionEvent, McpConnectionState, SSEClient, ToolInfo, type UseMcpOptions, useAppHost, useMcp, useMcpApps };