@modelcontextprotocol/ext-apps
Advanced tools
| /** | ||
| * Type-checked code examples for the patterns documentation. | ||
| * | ||
| * These examples are included in {@link ./patterns.md} via `@includeCode` tags. | ||
| * Each function's region markers define the code snippet that appears in the docs. | ||
| * | ||
| * @module | ||
| */ | ||
| export {}; |
| /** | ||
| * Type-checked examples for {@link AppBridge `AppBridge`}. | ||
| * | ||
| * These examples are included in the API documentation via `@includeCode` tags. | ||
| * Each function's region markers define the code snippet that appears in the docs. | ||
| * | ||
| * @module | ||
| */ | ||
| export {}; |
| /** | ||
| * Type-checked examples for {@link App `App`} and constants in {@link ./app.ts `app.ts`}. | ||
| * | ||
| * These examples are included in the API documentation via `@includeCode` tags. | ||
| * Each function's region markers define the code snippet that appears in the docs. | ||
| * | ||
| * @module | ||
| */ | ||
| export {}; |
| /** | ||
| * Type-checked examples for {@link PostMessageTransport `PostMessageTransport`}. | ||
| * | ||
| * These examples are included in the API documentation via `@includeCode` tags. | ||
| * Each function's region markers define the code snippet that appears in the docs. | ||
| * | ||
| * @module | ||
| */ | ||
| export {}; |
| /** | ||
| * Type-checked examples for the React module overview. | ||
| * | ||
| * @module | ||
| */ | ||
| export {}; |
| /** | ||
| * Type-checked examples for the useApp hook. | ||
| * | ||
| * @module | ||
| */ | ||
| export {}; |
| /** | ||
| * Type-checked examples for the useAutoResize hook. | ||
| * | ||
| * @module | ||
| */ | ||
| export {}; |
| /** | ||
| * Type-checked examples for the useDocumentTheme hook. | ||
| * | ||
| * @module | ||
| */ | ||
| export {}; |
| /** | ||
| * Type-checked examples for the useHostStyles hooks. | ||
| * | ||
| * @module | ||
| */ | ||
| export {}; |
| /** | ||
| * Type-checked examples for {@link registerAppTool `registerAppTool`} and {@link registerAppResource `registerAppResource`}. | ||
| * | ||
| * These examples are included in the API documentation via `@includeCode` tags. | ||
| * Each function's region markers define the code snippet that appears in the docs. | ||
| * | ||
| * @module | ||
| */ | ||
| export {}; |
| /** | ||
| * Type-checked examples for style utilities in {@link ./styles.ts `styles.ts`}. | ||
| * | ||
| * These examples are included in the API documentation via `@includeCode` tags. | ||
| * Each function's region markers define the code snippet that appears in the docs. | ||
| * | ||
| * @module | ||
| */ | ||
| export {}; |
+187
-194
@@ -52,8 +52,8 @@ import { Client } from "@modelcontextprotocol/sdk/client/index.js"; | ||
| /** | ||
| * Options for configuring {@link AppBridge} behavior. | ||
| * Options for configuring {@link AppBridge `AppBridge`} behavior. | ||
| * | ||
| * @property hostContext - Optional initial host context to provide to the Guest UI | ||
| * @property hostContext - Optional initial host context to provide to the view | ||
| * | ||
| * @see `ProtocolOptions` from @modelcontextprotocol/sdk for available options | ||
| * @see {@link McpUiHostContext} for the hostContext structure | ||
| * @see {@link McpUiHostContext `McpUiHostContext`} for the hostContext structure | ||
| */ | ||
@@ -81,8 +81,8 @@ export type HostOptions = ProtocolOptions & { | ||
| /** | ||
| * Host-side bridge for communicating with a single Guest UI ({@link app!App}). | ||
| * Host-side bridge for communicating with a single View ({@link app!App `App`}). | ||
| * | ||
| * `AppBridge` extends the MCP SDK's `Protocol` class and acts as a proxy between | ||
| * the host application and a Guest UI running in an iframe. When an MCP client | ||
| * the host application and a view running in an iframe. When an MCP client | ||
| * is provided to the constructor, it automatically forwards MCP server capabilities | ||
| * (tools, resources, prompts) to the Guest UI. It also handles the initialization | ||
| * (tools, resources, prompts) to the view. It also handles the initialization | ||
| * handshake. | ||
@@ -92,7 +92,7 @@ * | ||
| * | ||
| * **Guest UI ↔ AppBridge ↔ Host ↔ MCP Server** | ||
| * **View ↔ AppBridge ↔ Host ↔ MCP Server** | ||
| * | ||
| * The bridge proxies requests from the Guest UI to the MCP server and forwards | ||
| * The bridge proxies requests from the view to the MCP server and forwards | ||
| * responses back. It also sends host-initiated notifications like tool input | ||
| * and results to the Guest UI. | ||
| * and results to the view. | ||
| * | ||
@@ -103,11 +103,8 @@ * ## Lifecycle | ||
| * 2. **Connect**: Call `connect()` with transport to establish communication | ||
| * 3. **Wait for init**: Guest UI sends initialize request, bridge responds | ||
| * 4. **Send data**: Call {@link sendToolInput}, {@link sendToolResult}, etc. | ||
| * 5. **Teardown**: Call {@link teardownResource} before unmounting iframe | ||
| * 3. **Wait for init**: View sends initialize request, bridge responds | ||
| * 4. **Send data**: Call {@link sendToolInput `sendToolInput`}, {@link sendToolResult `sendToolResult`}, etc. | ||
| * 5. **Teardown**: Call {@link teardownResource `teardownResource`} before unmounting iframe | ||
| * | ||
| * @example Basic usage | ||
| * ```typescript | ||
| * import { AppBridge, PostMessageTransport } from '@modelcontextprotocol/ext-apps/app-bridge'; | ||
| * import { Client } from '@modelcontextprotocol/sdk/client/index.js'; | ||
| * | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_basicUsage" | ||
| * // Create MCP client for the server | ||
@@ -120,11 +117,11 @@ * const client = new Client({ | ||
| * | ||
| * // Create bridge for the Guest UI | ||
| * // Create bridge for the View | ||
| * const bridge = new AppBridge( | ||
| * client, | ||
| * { name: "MyHost", version: "1.0.0" }, | ||
| * { openLinks: {}, serverTools: {}, logging: {} } | ||
| * { openLinks: {}, serverTools: {}, logging: {} }, | ||
| * ); | ||
| * | ||
| * // Set up iframe and connect | ||
| * const iframe = document.getElementById('app') as HTMLIFrameElement; | ||
| * const iframe = document.getElementById("app") as HTMLIFrameElement; | ||
| * const transport = new PostMessageTransport( | ||
@@ -136,3 +133,3 @@ * iframe.contentWindow!, | ||
| * bridge.oninitialized = () => { | ||
| * console.log("Guest UI initialized"); | ||
| * console.log("View initialized"); | ||
| * // Now safe to send tool input | ||
@@ -156,5 +153,5 @@ * bridge.sendToolInput({ arguments: { location: "NYC" } }); | ||
| * @param _client - MCP client connected to the server, or `null`. When provided, | ||
| * {@link connect} will automatically set up forwarding of MCP requests/notifications | ||
| * between the Guest UI and the server. When `null`, you must register handlers | ||
| * manually using the {@link oncalltool}, {@link onlistresources}, etc. setters. | ||
| * {@link connect `connect`} will automatically set up forwarding of MCP requests/notifications | ||
| * between the View and the server. When `null`, you must register handlers | ||
| * manually using the {@link oncalltool `oncalltool`}, {@link onlistresources `onlistresources`}, etc. setters. | ||
| * @param _hostInfo - Host application identification (name and version) | ||
@@ -165,7 +162,7 @@ * @param _capabilities - Features and capabilities the host supports | ||
| * @example With MCP client (automatic forwarding) | ||
| * ```typescript | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_constructor_withMcpClient" | ||
| * const bridge = new AppBridge( | ||
| * mcpClient, | ||
| * { name: "MyHost", version: "1.0.0" }, | ||
| * { openLinks: {}, serverTools: {}, logging: {} } | ||
| * { openLinks: {}, serverTools: {}, logging: {} }, | ||
| * ); | ||
@@ -175,9 +172,12 @@ * ``` | ||
| * @example Without MCP client (manual handlers) | ||
| * ```typescript | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_constructor_withoutMcpClient" | ||
| * const bridge = new AppBridge( | ||
| * null, | ||
| * { name: "MyHost", version: "1.0.0" }, | ||
| * { openLinks: {}, serverTools: {}, logging: {} } | ||
| * { openLinks: {}, serverTools: {}, logging: {} }, | ||
| * ); | ||
| * bridge.oncalltool = async (params, extra) => { ... }; | ||
| * bridge.oncalltool = async (params, extra) => { | ||
| * // Handle tool calls manually | ||
| * return { content: [] }; | ||
| * }; | ||
| * ``` | ||
@@ -187,16 +187,16 @@ */ | ||
| /** | ||
| * Get the Guest UI's capabilities discovered during initialization. | ||
| * Get the view's capabilities discovered during initialization. | ||
| * | ||
| * Returns the capabilities that the Guest UI advertised during its | ||
| * Returns the capabilities that the view advertised during its | ||
| * initialization request. Returns `undefined` if called before | ||
| * initialization completes. | ||
| * | ||
| * @returns Guest UI capabilities, or `undefined` if not yet initialized | ||
| * @returns view capabilities, or `undefined` if not yet initialized | ||
| * | ||
| * @example Check Guest UI capabilities after initialization | ||
| * ```typescript | ||
| * @example Check view capabilities after initialization | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_getAppCapabilities_checkAfterInit" | ||
| * bridge.oninitialized = () => { | ||
| * const caps = bridge.getAppCapabilities(); | ||
| * if (caps?.tools) { | ||
| * console.log("Guest UI provides tools"); | ||
| * console.log("View provides tools"); | ||
| * } | ||
@@ -206,19 +206,19 @@ * }; | ||
| * | ||
| * @see {@link McpUiAppCapabilities} for the capabilities structure | ||
| * @see {@link McpUiAppCapabilities `McpUiAppCapabilities`} for the capabilities structure | ||
| */ | ||
| getAppCapabilities(): McpUiAppCapabilities | undefined; | ||
| /** | ||
| * Get the Guest UI's implementation info discovered during initialization. | ||
| * Get the view's implementation info discovered during initialization. | ||
| * | ||
| * Returns the Guest UI's name and version as provided in its initialization | ||
| * Returns the view's name and version as provided in its initialization | ||
| * request. Returns `undefined` if called before initialization completes. | ||
| * | ||
| * @returns Guest UI implementation info, or `undefined` if not yet initialized | ||
| * @returns view implementation info, or `undefined` if not yet initialized | ||
| * | ||
| * @example Log Guest UI information after initialization | ||
| * ```typescript | ||
| * @example Log view information after initialization | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_getAppVersion_logAfterInit" | ||
| * bridge.oninitialized = () => { | ||
| * const appInfo = bridge.getAppVersion(); | ||
| * if (appInfo) { | ||
| * console.log(`Guest UI: ${appInfo.name} v${appInfo.version}`); | ||
| * console.log(`View: ${appInfo.name} v${appInfo.version}`); | ||
| * } | ||
@@ -230,6 +230,6 @@ * }; | ||
| /** | ||
| * Optional handler for ping requests from the Guest UI. | ||
| * Optional handler for ping requests from the view. | ||
| * | ||
| * The Guest UI can send standard MCP `ping` requests to verify the connection | ||
| * is alive. The {@link AppBridge} automatically responds with an empty object, but this | ||
| * The View can send standard MCP `ping` requests to verify the connection | ||
| * is alive. The {@link AppBridge `AppBridge`} automatically responds with an empty object, but this | ||
| * handler allows the host to observe or log ping activity. | ||
@@ -244,5 +244,5 @@ * | ||
| * @example | ||
| * ```typescript | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_onping_handleRequest" | ||
| * bridge.onping = (params, extra) => { | ||
| * console.log("Received ping from Guest UI"); | ||
| * console.log("Received ping from view"); | ||
| * }; | ||
@@ -253,13 +253,13 @@ * ``` | ||
| /** | ||
| * Register a handler for size change notifications from the Guest UI. | ||
| * Register a handler for size change notifications from the view. | ||
| * | ||
| * The Guest UI sends `ui/notifications/size-changed` when its rendered content | ||
| * The view sends `ui/notifications/size-changed` when its rendered content | ||
| * size changes, typically via `ResizeObserver`. Set this callback to dynamically | ||
| * adjust the iframe container dimensions based on the Guest UI's content. | ||
| * adjust the iframe container dimensions based on the view's content. | ||
| * | ||
| * Note: This is for Guest UI → Host communication. To notify the Guest UI of | ||
| * host container dimension changes, use {@link setHostContext}. | ||
| * Note: This is for View → Host communication. To notify the View of | ||
| * host container dimension changes, use {@link setHostContext `setHostContext`}. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_onsizechange_handleResize" | ||
| * bridge.onsizechange = ({ width, height }) => { | ||
@@ -275,4 +275,4 @@ * if (width != null) { | ||
| * | ||
| * @see {@link McpUiSizeChangedNotification} for the notification type | ||
| * @see {@link app!App.sendSizeChanged} - the Guest UI method that sends these notifications | ||
| * @see {@link McpUiSizeChangedNotification `McpUiSizeChangedNotification`} for the notification type | ||
| * @see {@link app!App.sendSizeChanged `App.sendSizeChanged`} - the View method that sends these notifications | ||
| */ | ||
@@ -288,3 +288,3 @@ set onsizechange(callback: (params: McpUiSizeChangedNotification["params"]) => void); | ||
| * | ||
| * When this fires, the host should call {@link sendSandboxResourceReady} with | ||
| * When this fires, the host should call {@link sendSandboxResourceReady `sendSandboxResourceReady`} with | ||
| * the HTML content to load into the inner sandboxed iframe. | ||
@@ -308,16 +308,16 @@ * | ||
| * @internal | ||
| * @see {@link McpUiSandboxProxyReadyNotification} for the notification type | ||
| * @see {@link sendSandboxResourceReady} for sending content to the sandbox | ||
| * @see {@link McpUiSandboxProxyReadyNotification `McpUiSandboxProxyReadyNotification`} for the notification type | ||
| * @see {@link sendSandboxResourceReady `sendSandboxResourceReady`} for sending content to the sandbox | ||
| */ | ||
| set onsandboxready(callback: (params: McpUiSandboxProxyReadyNotification["params"]) => void); | ||
| /** | ||
| * Called when the Guest UI completes initialization. | ||
| * Called when the view completes initialization. | ||
| * | ||
| * Set this callback to be notified when the Guest UI has finished its | ||
| * Set this callback to be notified when the view has finished its | ||
| * initialization handshake and is ready to receive tool input and other data. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_oninitialized_sendToolInput" | ||
| * bridge.oninitialized = () => { | ||
| * console.log("Guest UI ready"); | ||
| * console.log("View ready"); | ||
| * bridge.sendToolInput({ arguments: toolArgs }); | ||
@@ -327,10 +327,10 @@ * }; | ||
| * | ||
| * @see {@link McpUiInitializedNotification} for the notification type | ||
| * @see {@link sendToolInput} for sending tool arguments to the Guest UI | ||
| * @see {@link McpUiInitializedNotification `McpUiInitializedNotification`} for the notification type | ||
| * @see {@link sendToolInput `sendToolInput`} for sending tool arguments to the View | ||
| */ | ||
| set oninitialized(callback: (params: McpUiInitializedNotification["params"]) => void); | ||
| /** | ||
| * Register a handler for message requests from the Guest UI. | ||
| * Register a handler for message requests from the view. | ||
| * | ||
| * The Guest UI sends `ui/message` requests when it wants to add a message to | ||
| * The view sends `ui/message` requests when it wants to add a message to | ||
| * the host's chat interface. This enables interactive apps to communicate with | ||
@@ -351,3 +351,3 @@ * the user through the conversation thread. | ||
| * @example | ||
| * ```typescript | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_onmessage_logMessage" | ||
| * bridge.onmessage = async ({ role, content }, extra) => { | ||
@@ -364,10 +364,10 @@ * try { | ||
| * | ||
| * @see {@link McpUiMessageRequest} for the request type | ||
| * @see {@link McpUiMessageResult} for the result type | ||
| * @see {@link McpUiMessageRequest `McpUiMessageRequest`} for the request type | ||
| * @see {@link McpUiMessageResult `McpUiMessageResult`} for the result type | ||
| */ | ||
| set onmessage(callback: (params: McpUiMessageRequest["params"], extra: RequestHandlerExtra) => Promise<McpUiMessageResult>); | ||
| /** | ||
| * Register a handler for external link requests from the Guest UI. | ||
| * Register a handler for external link requests from the view. | ||
| * | ||
| * The Guest UI sends `ui/open-link` requests when it wants to open an external | ||
| * The view sends `ui/open-link` requests when it wants to open an external | ||
| * URL in the host's default browser. The handler should validate the URL and | ||
@@ -388,3 +388,3 @@ * open it according to the host's security policy and user preferences. | ||
| * @example | ||
| * ```typescript | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_onopenlink_handleRequest" | ||
| * bridge.onopenlink = async ({ url }, extra) => { | ||
@@ -398,3 +398,3 @@ * if (!isAllowedDomain(url)) { | ||
| * message: `Open external link?\n${url}`, | ||
| * buttons: ["Open", "Cancel"] | ||
| * buttons: ["Open", "Cancel"], | ||
| * }); | ||
@@ -411,10 +411,10 @@ * | ||
| * | ||
| * @see {@link McpUiOpenLinkRequest} for the request type | ||
| * @see {@link McpUiOpenLinkResult} for the result type | ||
| * @see {@link McpUiOpenLinkRequest `McpUiOpenLinkRequest`} for the request type | ||
| * @see {@link McpUiOpenLinkResult `McpUiOpenLinkResult`} for the result type | ||
| */ | ||
| set onopenlink(callback: (params: McpUiOpenLinkRequest["params"], extra: RequestHandlerExtra) => Promise<McpUiOpenLinkResult>); | ||
| /** | ||
| * Register a handler for display mode change requests from the Guest UI. | ||
| * Register a handler for display mode change requests from the view. | ||
| * | ||
| * The Guest UI sends `ui/request-display-mode` requests when it wants to change | ||
| * The view sends `ui/request-display-mode` requests when it wants to change | ||
| * its display mode (e.g., from "inline" to "fullscreen"). The handler should | ||
@@ -436,12 +436,7 @@ * check if the requested mode is in `availableDisplayModes` from the host context, | ||
| * @example | ||
| * ```typescript | ||
| * let currentDisplayMode: McpUiDisplayMode = "inline"; | ||
| * | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_onrequestdisplaymode_handleRequest" | ||
| * bridge.onrequestdisplaymode = async ({ mode }, extra) => { | ||
| * const availableModes = hostContext.availableDisplayModes ?? ["inline"]; | ||
| * if (availableModes.includes(mode)) { | ||
| * if (availableDisplayModes.includes(mode)) { | ||
| * currentDisplayMode = mode; | ||
| * return { mode }; | ||
| * } | ||
| * // Return current mode if requested mode not available | ||
| * return { mode: currentDisplayMode }; | ||
@@ -451,10 +446,10 @@ * }; | ||
| * | ||
| * @see {@link McpUiRequestDisplayModeRequest} for the request type | ||
| * @see {@link McpUiRequestDisplayModeResult} for the result type | ||
| * @see {@link McpUiRequestDisplayModeRequest `McpUiRequestDisplayModeRequest`} for the request type | ||
| * @see {@link McpUiRequestDisplayModeResult `McpUiRequestDisplayModeResult`} for the result type | ||
| */ | ||
| set onrequestdisplaymode(callback: (params: McpUiRequestDisplayModeRequest["params"], extra: RequestHandlerExtra) => Promise<McpUiRequestDisplayModeResult>); | ||
| /** | ||
| * Register a handler for logging messages from the Guest UI. | ||
| * Register a handler for logging messages from the view. | ||
| * | ||
| * The Guest UI sends standard MCP `notifications/message` (logging) notifications | ||
| * The view sends standard MCP `notifications/message` (logging) notifications | ||
| * to report debugging information, errors, warnings, and other telemetry to the | ||
@@ -473,8 +468,7 @@ * host. The host can display these in a console, log them to a file, or send | ||
| * @example | ||
| * ```typescript | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_onloggingmessage_handleLog" | ||
| * bridge.onloggingmessage = ({ level, logger, data }) => { | ||
| * const prefix = logger ? `[${logger}]` : "[Guest UI]"; | ||
| * console[level === "error" ? "error" : "log"]( | ||
| * `${prefix} ${level.toUpperCase()}:`, | ||
| * data | ||
| * `[${logger ?? "View"}] ${level.toUpperCase()}:`, | ||
| * data, | ||
| * ); | ||
@@ -486,6 +480,6 @@ * }; | ||
| /** | ||
| * Register a handler for model context updates from the Guest UI. | ||
| * Register a handler for model context updates from the view. | ||
| * | ||
| * The Guest UI sends `ui/update-model-context` requests to update the Host's | ||
| * model context. Each request overwrites the previous context stored by the Guest UI. | ||
| * The view sends `ui/update-model-context` requests to update the Host's | ||
| * model context. Each request overwrites the previous context stored by the view. | ||
| * Unlike logging messages, context updates are intended to be available to | ||
@@ -499,11 +493,9 @@ * the model in future turns. Unlike messages, context updates do not trigger follow-ups. | ||
| * @example | ||
| * ```typescript | ||
| * bridge.onupdatemodelcontext = async ({ content, structuredContent }, extra) => { | ||
| * // Update the model context with the new snapshot | ||
| * modelContext = { | ||
| * type: "app_context", | ||
| * content, | ||
| * structuredContent, | ||
| * timestamp: Date.now() | ||
| * }; | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_onupdatemodelcontext_storeContext" | ||
| * bridge.onupdatemodelcontext = async ( | ||
| * { content, structuredContent }, | ||
| * extra, | ||
| * ) => { | ||
| * // Store the context snapshot for inclusion in the next model request | ||
| * modelContextManager.update({ content, structuredContent }); | ||
| * return {}; | ||
@@ -513,9 +505,9 @@ * }; | ||
| * | ||
| * @see {@link McpUiUpdateModelContextRequest} for the request type | ||
| * @see {@link McpUiUpdateModelContextRequest `McpUiUpdateModelContextRequest`} for the request type | ||
| */ | ||
| set onupdatemodelcontext(callback: (params: McpUiUpdateModelContextRequest["params"], extra: RequestHandlerExtra) => Promise<EmptyResult>); | ||
| /** | ||
| * Register a handler for tool call requests from the Guest UI. | ||
| * Register a handler for tool call requests from the view. | ||
| * | ||
| * The Guest UI sends `tools/call` requests to execute MCP server tools. This | ||
| * The view sends `tools/call` requests to execute MCP server tools. This | ||
| * handler allows the host to intercept and process these requests, typically | ||
@@ -530,8 +522,8 @@ * by forwarding them to the MCP server. | ||
| * @example | ||
| * ```typescript | ||
| * bridge.oncalltool = async ({ name, arguments: args }, extra) => { | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_oncalltool_forwardToServer" | ||
| * bridge.oncalltool = async (params, extra) => { | ||
| * return mcpClient.request( | ||
| * { method: "tools/call", params: { name, arguments: args } }, | ||
| * { method: "tools/call", params }, | ||
| * CallToolResultSchema, | ||
| * { signal: extra.signal } | ||
| * { signal: extra.signal }, | ||
| * ); | ||
@@ -546,6 +538,6 @@ * }; | ||
| /** | ||
| * Notify the Guest UI that the MCP server's tool list has changed. | ||
| * Notify the view that the MCP server's tool list has changed. | ||
| * | ||
| * The host sends `notifications/tools/list_changed` to the Guest UI when it | ||
| * receives this notification from the MCP server. This allows the Guest UI | ||
| * The host sends `notifications/tools/list_changed` to the view when it | ||
| * receives this notification from the MCP server. This allows the view | ||
| * to refresh its tool cache or UI accordingly. | ||
@@ -567,5 +559,5 @@ * | ||
| /** | ||
| * Register a handler for list resources requests from the Guest UI. | ||
| * Register a handler for list resources requests from the view. | ||
| * | ||
| * The Guest UI sends `resources/list` requests to enumerate available MCP | ||
| * The view sends `resources/list` requests to enumerate available MCP | ||
| * resources. This handler allows the host to intercept and process these | ||
@@ -580,3 +572,3 @@ * requests, typically by forwarding them to the MCP server. | ||
| * @example | ||
| * ```typescript | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_onlistresources_returnResources" | ||
| * bridge.onlistresources = async (params, extra) => { | ||
@@ -586,3 +578,3 @@ * return mcpClient.request( | ||
| * ListResourcesResultSchema, | ||
| * { signal: extra.signal } | ||
| * { signal: extra.signal }, | ||
| * ); | ||
@@ -597,5 +589,5 @@ * }; | ||
| /** | ||
| * Register a handler for list resource templates requests from the Guest UI. | ||
| * Register a handler for list resource templates requests from the view. | ||
| * | ||
| * The Guest UI sends `resources/templates/list` requests to enumerate available | ||
| * The view sends `resources/templates/list` requests to enumerate available | ||
| * MCP resource templates. This handler allows the host to intercept and process | ||
@@ -625,5 +617,5 @@ * these requests, typically by forwarding them to the MCP server. | ||
| /** | ||
| * Register a handler for read resource requests from the Guest UI. | ||
| * Register a handler for read resource requests from the view. | ||
| * | ||
| * The Guest UI sends `resources/read` requests to retrieve the contents of an | ||
| * The view sends `resources/read` requests to retrieve the contents of an | ||
| * MCP resource. This handler allows the host to intercept and process these | ||
@@ -638,8 +630,8 @@ * requests, typically by forwarding them to the MCP server. | ||
| * @example | ||
| * ```typescript | ||
| * bridge.onreadresource = async ({ uri }, extra) => { | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_onreadresource_returnResource" | ||
| * bridge.onreadresource = async (params, extra) => { | ||
| * return mcpClient.request( | ||
| * { method: "resources/read", params: { uri } }, | ||
| * { method: "resources/read", params }, | ||
| * ReadResourceResultSchema, | ||
| * { signal: extra.signal } | ||
| * { signal: extra.signal }, | ||
| * ); | ||
@@ -654,6 +646,6 @@ * }; | ||
| /** | ||
| * Notify the Guest UI that the MCP server's resource list has changed. | ||
| * Notify the view that the MCP server's resource list has changed. | ||
| * | ||
| * The host sends `notifications/resources/list_changed` to the Guest UI when it | ||
| * receives this notification from the MCP server. This allows the Guest UI | ||
| * The host sends `notifications/resources/list_changed` to the view when it | ||
| * receives this notification from the MCP server. This allows the view | ||
| * to refresh its resource cache or UI accordingly. | ||
@@ -675,5 +667,5 @@ * | ||
| /** | ||
| * Register a handler for list prompts requests from the Guest UI. | ||
| * Register a handler for list prompts requests from the view. | ||
| * | ||
| * The Guest UI sends `prompts/list` requests to enumerate available MCP | ||
| * The view sends `prompts/list` requests to enumerate available MCP | ||
| * prompts. This handler allows the host to intercept and process these | ||
@@ -688,3 +680,3 @@ * requests, typically by forwarding them to the MCP server. | ||
| * @example | ||
| * ```typescript | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_onlistprompts_returnPrompts" | ||
| * bridge.onlistprompts = async (params, extra) => { | ||
@@ -694,3 +686,3 @@ * return mcpClient.request( | ||
| * ListPromptsResultSchema, | ||
| * { signal: extra.signal } | ||
| * { signal: extra.signal }, | ||
| * ); | ||
@@ -705,6 +697,6 @@ * }; | ||
| /** | ||
| * Notify the Guest UI that the MCP server's prompt list has changed. | ||
| * Notify the view that the MCP server's prompt list has changed. | ||
| * | ||
| * The host sends `notifications/prompts/list_changed` to the Guest UI when it | ||
| * receives this notification from the MCP server. This allows the Guest UI | ||
| * The host sends `notifications/prompts/list_changed` to the view when it | ||
| * receives this notification from the MCP server. This allows the view | ||
| * to refresh its prompt cache or UI accordingly. | ||
@@ -755,3 +747,3 @@ * | ||
| * | ||
| * @see {@link McpUiHostCapabilities} for the capabilities structure | ||
| * @see {@link McpUiHostCapabilities `McpUiHostCapabilities`} for the capabilities structure | ||
| */ | ||
@@ -765,3 +757,3 @@ getCapabilities(): McpUiHostCapabilities; | ||
| /** | ||
| * Update the host context and notify the Guest UI of changes. | ||
| * Update the host context and notify the view of changes. | ||
| * | ||
@@ -773,3 +765,3 @@ * Compares fields present in the new context with the current context and sends a | ||
| * | ||
| * Common use cases include notifying the Guest UI when: | ||
| * Common use cases include notifying the view when: | ||
| * - Theme changes (light/dark mode toggle) | ||
@@ -783,3 +775,3 @@ * - Viewport size changes (window resize) | ||
| * @example Update theme when user toggles dark mode | ||
| * ```typescript | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_setHostContext_updateTheme" | ||
| * bridge.setHostContext({ theme: "dark" }); | ||
@@ -789,17 +781,17 @@ * ``` | ||
| * @example Update multiple context fields | ||
| * ```typescript | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_setHostContext_updateMultiple" | ||
| * bridge.setHostContext({ | ||
| * theme: "dark", | ||
| * containerDimensions: { maxHeight: 600, width: 800 } | ||
| * containerDimensions: { maxHeight: 600, width: 800 }, | ||
| * }); | ||
| * ``` | ||
| * | ||
| * @see {@link McpUiHostContext} for the context structure | ||
| * @see {@link McpUiHostContextChangedNotification} for the notification type | ||
| * @see {@link McpUiHostContext `McpUiHostContext`} for the context structure | ||
| * @see {@link McpUiHostContextChangedNotification `McpUiHostContextChangedNotification`} for the notification type | ||
| */ | ||
| setHostContext(hostContext: McpUiHostContext): void; | ||
| /** | ||
| * Low-level method to notify the Guest UI of host context changes. | ||
| * Low-level method to notify the view of host context changes. | ||
| * | ||
| * Most hosts should use {@link setHostContext} instead, which automatically | ||
| * Most hosts should use {@link setHostContext `setHostContext`} instead, which automatically | ||
| * detects changes and calls this method with only the modified fields. | ||
@@ -812,7 +804,7 @@ * Use this directly only when you need fine-grained control over change detection. | ||
| /** | ||
| * Send complete tool arguments to the Guest UI. | ||
| * Send complete tool arguments to the view. | ||
| * | ||
| * The host MUST send this notification after the Guest UI completes initialization | ||
| * (after {@link oninitialized} callback fires) and complete tool arguments become available. | ||
| * This notification is sent exactly once and is required before {@link sendToolResult}. | ||
| * The host MUST send this notification after the View completes initialization | ||
| * (after {@link oninitialized `oninitialized`} callback fires) and complete tool arguments become available. | ||
| * This notification is sent exactly once and is required before {@link sendToolResult `sendToolResult`}. | ||
| * | ||
@@ -822,6 +814,6 @@ * @param params - Complete tool call arguments | ||
| * @example | ||
| * ```typescript | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_sendToolInput_afterInit" | ||
| * bridge.oninitialized = () => { | ||
| * bridge.sendToolInput({ | ||
| * arguments: { location: "New York", units: "metric" } | ||
| * arguments: { location: "New York", units: "metric" }, | ||
| * }); | ||
@@ -831,16 +823,16 @@ * }; | ||
| * | ||
| * @see {@link McpUiToolInputNotification} for the notification type | ||
| * @see {@link oninitialized} for the initialization callback | ||
| * @see {@link sendToolResult} for sending results after execution | ||
| * @see {@link McpUiToolInputNotification `McpUiToolInputNotification`} for the notification type | ||
| * @see {@link oninitialized `oninitialized`} for the initialization callback | ||
| * @see {@link sendToolResult `sendToolResult`} for sending results after execution | ||
| */ | ||
| sendToolInput(params: McpUiToolInputNotification["params"]): Promise<void>; | ||
| /** | ||
| * Send streaming partial tool arguments to the Guest UI. | ||
| * Send streaming partial tool arguments to the view. | ||
| * | ||
| * The host MAY send this notification zero or more times while tool arguments | ||
| * are being streamed, before {@link sendToolInput} is called with complete | ||
| * are being streamed, before {@link sendToolInput `sendToolInput`} is called with complete | ||
| * arguments. This enables progressive rendering of tool arguments in the | ||
| * Guest UI. | ||
| * view. | ||
| * | ||
| * The arguments represent best-effort recovery of incomplete JSON. Guest UIs | ||
| * The arguments represent best-effort recovery of incomplete JSON. views | ||
| * SHOULD handle missing or changing fields gracefully between notifications. | ||
@@ -851,3 +843,3 @@ * | ||
| * @example Stream partial arguments as they arrive | ||
| * ```typescript | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_sendToolInputPartial_streaming" | ||
| * // As streaming progresses... | ||
@@ -859,16 +851,18 @@ * bridge.sendToolInputPartial({ arguments: { loc: "N" } }); | ||
| * // When complete, send final input | ||
| * bridge.sendToolInput({ arguments: { location: "New York", units: "metric" } }); | ||
| * bridge.sendToolInput({ | ||
| * arguments: { location: "New York", units: "metric" }, | ||
| * }); | ||
| * ``` | ||
| * | ||
| * @see {@link McpUiToolInputPartialNotification} for the notification type | ||
| * @see {@link sendToolInput} for sending complete arguments | ||
| * @see {@link McpUiToolInputPartialNotification `McpUiToolInputPartialNotification`} for the notification type | ||
| * @see {@link sendToolInput `sendToolInput`} for sending complete arguments | ||
| */ | ||
| sendToolInputPartial(params: McpUiToolInputPartialNotification["params"]): Promise<void>; | ||
| /** | ||
| * Send tool execution result to the Guest UI. | ||
| * Send tool execution result to the view. | ||
| * | ||
| * The host MUST send this notification when tool execution completes successfully, | ||
| * provided the UI is still displayed. If the UI was closed before execution | ||
| * provided the view is still displayed. If the view was closed before execution | ||
| * completes, the host MAY skip this notification. This must be sent after | ||
| * {@link sendToolInput}. | ||
| * {@link sendToolInput `sendToolInput`}. | ||
| * | ||
@@ -878,8 +872,6 @@ * @param params - Standard MCP tool execution result | ||
| * @example | ||
| * ```typescript | ||
| * import { CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js'; | ||
| * | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_sendToolResult_afterExecution" | ||
| * const result = await mcpClient.request( | ||
| * { method: "tools/call", params: { name: "get_weather", arguments: args } }, | ||
| * CallToolResultSchema | ||
| * CallToolResultSchema, | ||
| * ); | ||
@@ -889,12 +881,12 @@ * bridge.sendToolResult(result); | ||
| * | ||
| * @see {@link McpUiToolResultNotification} for the notification type | ||
| * @see {@link sendToolInput} for sending tool arguments before results | ||
| * @see {@link McpUiToolResultNotification `McpUiToolResultNotification`} for the notification type | ||
| * @see {@link sendToolInput `sendToolInput`} for sending tool arguments before results | ||
| */ | ||
| sendToolResult(params: McpUiToolResultNotification["params"]): Promise<void>; | ||
| /** | ||
| * Notify the Guest UI that tool execution was cancelled. | ||
| * Notify the view that tool execution was cancelled. | ||
| * | ||
| * The host MUST send this notification if tool execution was cancelled for any | ||
| * reason, including user action, sampling error, classifier intervention, or | ||
| * any other interruption. This allows the Guest UI to update its state and | ||
| * any other interruption. This allows the view to update its state and | ||
| * display appropriate feedback to the user. | ||
@@ -906,3 +898,3 @@ * | ||
| * @example User-initiated cancellation | ||
| * ```typescript | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_sendToolCancelled_userInitiated" | ||
| * // User clicked "Cancel" button | ||
@@ -913,3 +905,3 @@ * bridge.sendToolCancelled({ reason: "User cancelled the operation" }); | ||
| * @example System-level cancellation | ||
| * ```typescript | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_sendToolCancelled_systemLevel" | ||
| * // Sampling error or timeout | ||
@@ -922,5 +914,5 @@ * bridge.sendToolCancelled({ reason: "Request timeout after 30 seconds" }); | ||
| * | ||
| * @see {@link McpUiToolCancelledNotification} for the notification type | ||
| * @see {@link sendToolResult} for sending successful results | ||
| * @see {@link sendToolInput} for sending tool arguments | ||
| * @see {@link McpUiToolCancelledNotification `McpUiToolCancelledNotification`} for the notification type | ||
| * @see {@link sendToolResult `sendToolResult`} for sending successful results | ||
| * @see {@link sendToolInput `sendToolInput`} for sending tool arguments | ||
| */ | ||
@@ -941,10 +933,10 @@ sendToolCancelled(params: McpUiToolCancelledNotification["params"]): Promise<void>; | ||
| * @internal | ||
| * @see {@link onsandboxready} for handling the sandbox proxy ready notification | ||
| * @see {@link onsandboxready `onsandboxready`} for handling the sandbox proxy ready notification | ||
| */ | ||
| sendSandboxResourceReady(params: McpUiSandboxResourceReadyNotification["params"]): Promise<void>; | ||
| /** | ||
| * Request graceful shutdown of the Guest UI. | ||
| * Request graceful shutdown of the view. | ||
| * | ||
| * The host MUST send this request before tearing down the UI resource (before | ||
| * unmounting the iframe). This gives the Guest UI an opportunity to save state, | ||
| * unmounting the iframe). This gives the view an opportunity to save state, | ||
| * cancel pending operations, or show confirmation dialogs. | ||
@@ -956,9 +948,9 @@ * | ||
| * @param options - Request options (timeout, etc.) | ||
| * @returns Promise resolving when Guest UI confirms readiness for teardown | ||
| * @returns Promise resolving when view confirms readiness for teardown | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_teardownResource_gracefulShutdown" | ||
| * try { | ||
| * await bridge.teardownResource({}); | ||
| * // Guest UI is ready, safe to unmount iframe | ||
| * // View is ready, safe to unmount iframe | ||
| * iframe.remove(); | ||
@@ -971,10 +963,10 @@ * } catch (error) { | ||
| teardownResource(params: McpUiResourceTeardownRequest["params"], options?: RequestOptions): Promise<Record<string, unknown>>; | ||
| /** @deprecated Use {@link teardownResource} instead */ | ||
| /** @deprecated Use {@link teardownResource `teardownResource`} instead */ | ||
| sendResourceTeardown: AppBridge["teardownResource"]; | ||
| /** | ||
| * Connect to the Guest UI via transport and optionally set up message forwarding. | ||
| * Connect to the view via transport and optionally set up message forwarding. | ||
| * | ||
| * This method establishes the transport connection. If an MCP client was passed | ||
| * to the constructor, it also automatically sets up request/notification forwarding | ||
| * based on the MCP server's capabilities, proxying the following to the Guest UI: | ||
| * based on the MCP server's capabilities, proxying the following to the view: | ||
| * - Tools (tools/call, notifications/tools/list_changed) | ||
@@ -985,9 +977,9 @@ * - Resources (resources/list, resources/read, resources/templates/list, notifications/resources/list_changed) | ||
| * If no client was passed to the constructor, no automatic forwarding is set up | ||
| * and you must register handlers manually using the {@link oncalltool}, {@link onlistresources}, | ||
| * and you must register handlers manually using the {@link oncalltool `oncalltool`}, {@link onlistresources `onlistresources`}, | ||
| * etc. setters. | ||
| * | ||
| * After calling connect, wait for the {@link oninitialized} callback before sending | ||
| * tool input and other data to the Guest UI. | ||
| * After calling connect, wait for the {@link oninitialized `oninitialized`} callback before sending | ||
| * tool input and other data to the View. | ||
| * | ||
| * @param transport - Transport layer (typically {@link PostMessageTransport}) | ||
| * @param transport - Transport layer (typically {@link PostMessageTransport `PostMessageTransport`}) | ||
| * @returns Promise resolving when connection is established | ||
@@ -1001,3 +993,3 @@ * | ||
| * @example With MCP client (automatic forwarding) | ||
| * ```typescript | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_connect_withMcpClient" | ||
| * const bridge = new AppBridge(mcpClient, hostInfo, capabilities); | ||
@@ -1010,3 +1002,3 @@ * const transport = new PostMessageTransport( | ||
| * bridge.oninitialized = () => { | ||
| * console.log("Guest UI ready"); | ||
| * console.log("View ready"); | ||
| * bridge.sendToolInput({ arguments: toolArgs }); | ||
@@ -1019,3 +1011,3 @@ * }; | ||
| * @example Without MCP client (manual handlers) | ||
| * ```typescript | ||
| * ```ts source="./app-bridge.examples.ts#AppBridge_connect_withoutMcpClient" | ||
| * const bridge = new AppBridge(null, hostInfo, capabilities); | ||
@@ -1026,2 +1018,3 @@ * | ||
| * // Custom tool call handling | ||
| * return { content: [] }; | ||
| * }; | ||
@@ -1028,0 +1021,0 @@ * |
+224
-197
@@ -10,28 +10,33 @@ import { type RequestOptions, Protocol, ProtocolOptions } from "@modelcontextprotocol/sdk/shared/protocol.js"; | ||
| /** | ||
| * Metadata key for associating a resource URI with a tool call. | ||
| * Metadata key for associating a UI resource URI with a tool. | ||
| * | ||
| * MCP servers include this key in tool call result metadata to indicate which | ||
| * UI resource should be displayed for the tool. When hosts receive a tool result | ||
| * containing this metadata, they resolve and render the corresponding {@link App}. | ||
| * MCP servers include this key in tool definition metadata (via `tools/list`) | ||
| * to indicate which UI resource should be displayed when the tool is called. | ||
| * When hosts see a tool with this metadata, they fetch and render the | ||
| * corresponding {@link App `App`}. | ||
| * | ||
| * **Note**: This constant is provided for reference. MCP servers set this metadata | ||
| * in their tool handlers; App developers typically don't need to use it directly. | ||
| * **Note**: This constant is provided for reference. App developers typically | ||
| * don't need to use it directly. Prefer using {@link server-helpers!registerAppTool `registerAppTool`} | ||
| * with the `_meta.ui.resourceUri` format instead. | ||
| * | ||
| * @example How MCP servers use this key (server-side, not in Apps) | ||
| * ```typescript | ||
| * // In an MCP server's tool handler: | ||
| * return { | ||
| * content: [{ type: "text", text: "Result" }], | ||
| * _meta: { | ||
| * [RESOURCE_URI_META_KEY]: "ui://weather/forecast" | ||
| * } | ||
| * }; | ||
| * ```ts source="./app.examples.ts#RESOURCE_URI_META_KEY_serverSide" | ||
| * server.registerTool( | ||
| * "weather", | ||
| * { | ||
| * description: "Get weather forecast", | ||
| * _meta: { | ||
| * [RESOURCE_URI_META_KEY]: "ui://weather/forecast", | ||
| * }, | ||
| * }, | ||
| * handler, | ||
| * ); | ||
| * ``` | ||
| * | ||
| * @example How hosts check for this metadata (host-side) | ||
| * ```typescript | ||
| * const result = await mcpClient.callTool({ name: "weather", arguments: {} }); | ||
| * const uiUri = result._meta?.[RESOURCE_URI_META_KEY]; | ||
| * if (uiUri) { | ||
| * // Load and display the UI resource | ||
| * ```ts source="./app.examples.ts#RESOURCE_URI_META_KEY_hostSide" | ||
| * // Check tool definition metadata (from tools/list response): | ||
| * const uiUri = tool._meta?.[RESOURCE_URI_META_KEY]; | ||
| * if (typeof uiUri === "string" && uiUri.startsWith("ui://")) { | ||
| * // Fetch the resource and display the UI | ||
| * } | ||
@@ -46,7 +51,7 @@ * ``` | ||
| * | ||
| * Used by {@link server-helpers!registerAppResource} as the default MIME type for app resources. | ||
| * Used by {@link server-helpers!registerAppResource `registerAppResource`} as the default MIME type for app resources. | ||
| */ | ||
| export declare const RESOURCE_MIME_TYPE = "text/html;profile=mcp-app"; | ||
| /** | ||
| * Options for configuring {@link App} behavior. | ||
| * Options for configuring {@link App `App`} behavior. | ||
| * | ||
@@ -61,3 +66,3 @@ * Extends `ProtocolOptions` from the MCP SDK with `App`-specific configuration. | ||
| * | ||
| * When enabled, the {@link App} monitors `document.body` and `document.documentElement` | ||
| * When enabled, the {@link App `App`} monitors `document.body` and `document.documentElement` | ||
| * for size changes and automatically sends `ui/notifications/size-changed` | ||
@@ -81,3 +86,3 @@ * notifications to the host. | ||
| * | ||
| * Guest UIs (Apps) act as MCP clients connecting to the host via {@link PostMessageTransport}. | ||
| * Views (Apps) act as MCP clients connecting to the host via {@link PostMessageTransport `PostMessageTransport`}. | ||
| * The host proxies requests to the actual MCP server and forwards | ||
@@ -115,15 +120,9 @@ * responses back to the App. | ||
| * @example Basic usage with PostMessageTransport | ||
| * ```typescript | ||
| * import { | ||
| * App, | ||
| * PostMessageTransport, | ||
| * McpUiToolInputNotificationSchema | ||
| * } from '@modelcontextprotocol/ext-apps'; | ||
| * | ||
| * ```ts source="./app.examples.ts#App_basicUsage" | ||
| * const app = new App( | ||
| * { name: "WeatherApp", version: "1.0.0" }, | ||
| * {} // capabilities | ||
| * {}, // capabilities | ||
| * ); | ||
| * | ||
| * // Register notification handler using setter (simpler) | ||
| * // Register handlers before connecting to ensure no notifications are missed | ||
| * app.ontoolinput = (params) => { | ||
@@ -133,20 +132,4 @@ * console.log("Tool arguments:", params.arguments); | ||
| * | ||
| * // OR using inherited setNotificationHandler (more explicit) | ||
| * app.setNotificationHandler( | ||
| * McpUiToolInputNotificationSchema, | ||
| * (notification) => { | ||
| * console.log("Tool arguments:", notification.params.arguments); | ||
| * } | ||
| * ); | ||
| * | ||
| * await app.connect(new PostMessageTransport(window.parent, window.parent)); | ||
| * await app.connect(); | ||
| * ``` | ||
| * | ||
| * @example Sending a message to the host's chat | ||
| * ```typescript | ||
| * await app.sendMessage({ | ||
| * role: "user", | ||
| * content: [{ type: "text", text: "Weather updated!" }] | ||
| * }); | ||
| * ``` | ||
| */ | ||
@@ -168,7 +151,7 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult> { | ||
| * @example | ||
| * ```typescript | ||
| * ```ts source="./app.examples.ts#App_constructor_basic" | ||
| * const app = new App( | ||
| * { name: "MyApp", version: "1.0.0" }, | ||
| * { tools: { listChanged: true } }, // capabilities | ||
| * { autoResize: true } // options | ||
| * { autoResize: true }, // options | ||
| * ); | ||
@@ -182,3 +165,3 @@ * ``` | ||
| * Returns the capabilities that the host advertised during the | ||
| * {@link connect} handshake. Returns `undefined` if called before | ||
| * {@link connect `connect`} handshake. Returns `undefined` if called before | ||
| * connection is established. | ||
@@ -189,10 +172,5 @@ * | ||
| * @example Check host capabilities after connection | ||
| * ```typescript | ||
| * await app.connect(transport); | ||
| * const caps = app.getHostCapabilities(); | ||
| * if (caps === undefined) { | ||
| * console.error("Not connected"); | ||
| * return; | ||
| * } | ||
| * if (caps.serverTools) { | ||
| * ```ts source="./app.examples.ts#App_getHostCapabilities_checkAfterConnection" | ||
| * await app.connect(); | ||
| * if (app.getHostCapabilities()?.serverTools) { | ||
| * console.log("Host supports server tool calls"); | ||
@@ -202,4 +180,4 @@ * } | ||
| * | ||
| * @see {@link connect} for the initialization handshake | ||
| * @see {@link McpUiHostCapabilities} for the capabilities structure | ||
| * @see {@link connect `connect`} for the initialization handshake | ||
| * @see {@link McpUiHostCapabilities `McpUiHostCapabilities`} for the capabilities structure | ||
| */ | ||
@@ -211,3 +189,3 @@ getHostCapabilities(): McpUiHostCapabilities | undefined; | ||
| * Returns the host's name and version as advertised during the | ||
| * {@link connect} handshake. Returns `undefined` if called before | ||
| * {@link connect `connect`} handshake. Returns `undefined` if called before | ||
| * connection is established. | ||
@@ -218,13 +196,9 @@ * | ||
| * @example Log host information after connection | ||
| * ```typescript | ||
| * ```ts source="./app.examples.ts#App_getHostVersion_logAfterConnection" | ||
| * await app.connect(transport); | ||
| * const host = app.getHostVersion(); | ||
| * if (host === undefined) { | ||
| * console.error("Not connected"); | ||
| * return; | ||
| * } | ||
| * console.log(`Connected to ${host.name} v${host.version}`); | ||
| * const { name, version } = app.getHostVersion() ?? {}; | ||
| * console.log(`Connected to ${name} v${version}`); | ||
| * ``` | ||
| * | ||
| * @see {@link connect} for the initialization handshake | ||
| * @see {@link connect `connect`} for the initialization handshake | ||
| */ | ||
@@ -245,13 +219,9 @@ getHostVersion(): Implementation | undefined; | ||
| * @example Access host context after connection | ||
| * ```typescript | ||
| * ```ts source="./app.examples.ts#App_getHostContext_accessAfterConnection" | ||
| * await app.connect(transport); | ||
| * const context = app.getHostContext(); | ||
| * if (context === undefined) { | ||
| * console.error("Not connected"); | ||
| * return; | ||
| * } | ||
| * if (context.theme === "dark") { | ||
| * if (context?.theme === "dark") { | ||
| * document.body.classList.add("dark-theme"); | ||
| * } | ||
| * if (context.toolInfo) { | ||
| * if (context?.toolInfo) { | ||
| * console.log("Tool:", context.toolInfo.tool.name); | ||
@@ -261,5 +231,5 @@ * } | ||
| * | ||
| * @see {@link connect} for the initialization handshake | ||
| * @see {@link onhostcontextchanged} for context change notifications | ||
| * @see {@link McpUiHostContext} for the context structure | ||
| * @see {@link connect `connect`} for the initialization handshake | ||
| * @see {@link onhostcontextchanged `onhostcontextchanged`} for context change notifications | ||
| * @see {@link McpUiHostContext `McpUiHostContext`} for the context structure | ||
| */ | ||
@@ -277,8 +247,8 @@ getHostContext(): McpUiHostContext | undefined; | ||
| * | ||
| * Register handlers before calling {@link connect} to avoid missing notifications. | ||
| * Register handlers before calling {@link connect `connect`} to avoid missing notifications. | ||
| * | ||
| * @param callback - Function called with the tool input params ({@link McpUiToolInputNotification.params}) | ||
| * @param callback - Function called with the tool input params ({@link McpUiToolInputNotification.params `McpUiToolInputNotification.params`}) | ||
| * | ||
| * @example Using the setter (simpler) | ||
| * ```typescript | ||
| * @example | ||
| * ```ts source="./app.examples.ts#App_ontoolinput_setter" | ||
| * // Register before connecting to ensure no notifications are missed | ||
@@ -289,17 +259,7 @@ * app.ontoolinput = (params) => { | ||
| * }; | ||
| * await app.connect(transport); | ||
| * await app.connect(); | ||
| * ``` | ||
| * | ||
| * @example Using setNotificationHandler (more explicit) | ||
| * ```typescript | ||
| * app.setNotificationHandler( | ||
| * McpUiToolInputNotificationSchema, | ||
| * (notification) => { | ||
| * console.log("Tool:", notification.params.arguments); | ||
| * } | ||
| * ); | ||
| * ``` | ||
| * | ||
| * @see {@link setNotificationHandler} for the underlying method | ||
| * @see {@link McpUiToolInputNotification} for the notification structure | ||
| * @see {@link setNotificationHandler `setNotificationHandler`} for the underlying method | ||
| * @see {@link McpUiToolInputNotification `McpUiToolInputNotification`} for the notification structure | ||
| */ | ||
@@ -314,20 +274,42 @@ set ontoolinput(callback: (params: McpUiToolInputNotification["params"]) => void); | ||
| * | ||
| * **Important:** Partial arguments are "healed" JSON — the host closes unclosed | ||
| * brackets/braces to produce valid JSON. This means objects may be incomplete | ||
| * (e.g., the last item in an array may be truncated). Use partial data only | ||
| * for preview UI, not for critical operations. | ||
| * | ||
| * This setter is a convenience wrapper around `setNotificationHandler()` that | ||
| * automatically handles the notification schema and extracts the params for you. | ||
| * | ||
| * Register handlers before calling {@link connect} to avoid missing notifications. | ||
| * Register handlers before calling {@link connect `connect`} to avoid missing notifications. | ||
| * | ||
| * @param callback - Function called with each partial tool input update ({@link McpUiToolInputPartialNotification.params}) | ||
| * @param callback - Function called with each partial tool input update ({@link McpUiToolInputPartialNotification.params `McpUiToolInputPartialNotification.params`}) | ||
| * | ||
| * @example Progressive rendering of tool arguments | ||
| * ```typescript | ||
| * ```ts source="./app.examples.ts#App_ontoolinputpartial_progressiveRendering" | ||
| * let toolInputs: Record<string, unknown> | null = null; | ||
| * let toolInputsPartial: Record<string, unknown> | null = null; | ||
| * | ||
| * app.ontoolinputpartial = (params) => { | ||
| * console.log("Partial args:", params.arguments); | ||
| * // Update your UI progressively as arguments stream in | ||
| * toolInputsPartial = params.arguments as Record<string, unknown>; | ||
| * render(); | ||
| * }; | ||
| * | ||
| * app.ontoolinput = (params) => { | ||
| * toolInputs = params.arguments as Record<string, unknown>; | ||
| * toolInputsPartial = null; | ||
| * render(); | ||
| * }; | ||
| * | ||
| * function render() { | ||
| * if (toolInputs) { | ||
| * renderFinalUI(toolInputs); | ||
| * } else { | ||
| * renderLoadingUI(toolInputsPartial); // e.g., shimmer with partial preview | ||
| * } | ||
| * } | ||
| * ``` | ||
| * | ||
| * @see {@link setNotificationHandler} for the underlying method | ||
| * @see {@link McpUiToolInputPartialNotification} for the notification structure | ||
| * @see {@link ontoolinput} for the complete tool input handler | ||
| * @see {@link setNotificationHandler `setNotificationHandler`} for the underlying method | ||
| * @see {@link McpUiToolInputPartialNotification `McpUiToolInputPartialNotification`} for the notification structure | ||
| * @see {@link ontoolinput `ontoolinput`} for the complete tool input handler | ||
| */ | ||
@@ -345,21 +327,20 @@ set ontoolinputpartial(callback: (params: McpUiToolInputPartialNotification["params"]) => void); | ||
| * | ||
| * Register handlers before calling {@link connect} to avoid missing notifications. | ||
| * Register handlers before calling {@link connect `connect`} to avoid missing notifications. | ||
| * | ||
| * @param callback - Function called with the tool result ({@link McpUiToolResultNotification.params}) | ||
| * @param callback - Function called with the tool result ({@link McpUiToolResultNotification.params `McpUiToolResultNotification.params`}) | ||
| * | ||
| * @example Display tool execution results | ||
| * ```typescript | ||
| * ```ts source="./app.examples.ts#App_ontoolresult_displayResults" | ||
| * app.ontoolresult = (params) => { | ||
| * if (params.content) { | ||
| * if (params.isError) { | ||
| * console.error("Tool execution failed:", params.content); | ||
| * } else if (params.content) { | ||
| * console.log("Tool output:", params.content); | ||
| * } | ||
| * if (params.isError) { | ||
| * console.error("Tool execution failed"); | ||
| * } | ||
| * }; | ||
| * ``` | ||
| * | ||
| * @see {@link setNotificationHandler} for the underlying method | ||
| * @see {@link McpUiToolResultNotification} for the notification structure | ||
| * @see {@link ontoolinput} for the initial tool input handler | ||
| * @see {@link setNotificationHandler `setNotificationHandler`} for the underlying method | ||
| * @see {@link McpUiToolResultNotification `McpUiToolResultNotification`} for the notification structure | ||
| * @see {@link ontoolinput `ontoolinput`} for the initial tool input handler | ||
| */ | ||
@@ -378,17 +359,17 @@ set ontoolresult(callback: (params: McpUiToolResultNotification["params"]) => void); | ||
| * | ||
| * Register handlers before calling {@link connect} to avoid missing notifications. | ||
| * Register handlers before calling {@link connect `connect`} to avoid missing notifications. | ||
| * | ||
| * @param callback - Function called when tool execution is cancelled. Receives optional cancellation reason — see {@link McpUiToolCancelledNotification.params}. | ||
| * @param callback - Function called when tool execution is cancelled. Receives optional cancellation reason — see {@link McpUiToolCancelledNotification.params `McpUiToolCancelledNotification.params`}. | ||
| * | ||
| * @example Handle tool cancellation | ||
| * ```typescript | ||
| * ```ts source="./app.examples.ts#App_ontoolcancelled_handleCancellation" | ||
| * app.ontoolcancelled = (params) => { | ||
| * console.log("Tool cancelled:", params.reason); | ||
| * showCancelledMessage(params.reason ?? "Operation was cancelled"); | ||
| * // Update your UI to show cancellation state | ||
| * }; | ||
| * ``` | ||
| * | ||
| * @see {@link setNotificationHandler} for the underlying method | ||
| * @see {@link McpUiToolCancelledNotification} for the notification structure | ||
| * @see {@link ontoolresult} for successful tool completion | ||
| * @see {@link setNotificationHandler `setNotificationHandler`} for the underlying method | ||
| * @see {@link McpUiToolCancelledNotification `McpUiToolCancelledNotification`} for the notification structure | ||
| * @see {@link ontoolresult `ontoolresult`} for successful tool completion | ||
| */ | ||
@@ -408,6 +389,6 @@ set ontoolcancelled(callback: (params: McpUiToolCancelledNotification["params"]) => void); | ||
| * Notification params are automatically merged into the internal host context | ||
| * before the callback is invoked. This means {@link getHostContext} will | ||
| * before the callback is invoked. This means {@link getHostContext `getHostContext`} will | ||
| * return the updated values even before your callback runs. | ||
| * | ||
| * Register handlers before calling {@link connect} to avoid missing notifications. | ||
| * Register handlers before calling {@link connect `connect`} to avoid missing notifications. | ||
| * | ||
@@ -417,3 +398,3 @@ * @param callback - Function called with the updated host context | ||
| * @example Respond to theme changes | ||
| * ```typescript | ||
| * ```ts source="./app.examples.ts#App_onhostcontextchanged_respondToTheme" | ||
| * app.onhostcontextchanged = (params) => { | ||
@@ -428,5 +409,5 @@ * if (params.theme === "dark") { | ||
| * | ||
| * @see {@link setNotificationHandler} for the underlying method | ||
| * @see {@link McpUiHostContextChangedNotification} for the notification structure | ||
| * @see {@link McpUiHostContext} for the full context structure | ||
| * @see {@link setNotificationHandler `setNotificationHandler`} for the underlying method | ||
| * @see {@link McpUiHostContextChangedNotification `McpUiHostContextChangedNotification`} for the notification structure | ||
| * @see {@link McpUiHostContext `McpUiHostContext`} for the full context structure | ||
| */ | ||
@@ -447,3 +428,3 @@ set onhostcontextchanged(callback: (params: McpUiHostContextChangedNotification["params"]) => void); | ||
| * | ||
| * Register handlers before calling {@link connect} to avoid missing requests. | ||
| * Register handlers before calling {@link connect `connect`} to avoid missing requests. | ||
| * | ||
@@ -454,3 +435,3 @@ * @param callback - Function called when teardown is requested. | ||
| * @example Perform cleanup before teardown | ||
| * ```typescript | ||
| * ```ts source="./app.examples.ts#App_onteardown_performCleanup" | ||
| * app.onteardown = async () => { | ||
@@ -464,4 +445,4 @@ * await saveState(); | ||
| * | ||
| * @see {@link setRequestHandler} for the underlying method | ||
| * @see {@link McpUiResourceTeardownRequest} for the request structure | ||
| * @see {@link setRequestHandler `setRequestHandler`} for the underlying method | ||
| * @see {@link McpUiResourceTeardownRequest `McpUiResourceTeardownRequest`} for the request structure | ||
| */ | ||
@@ -481,3 +462,3 @@ set onteardown(callback: (params: McpUiResourceTeardownRequest["params"], extra: RequestHandlerExtra) => McpUiResourceTeardownResult | Promise<McpUiResourceTeardownResult>); | ||
| * | ||
| * Register handlers before calling {@link connect} to avoid missing requests. | ||
| * Register handlers before calling {@link connect `connect`} to avoid missing requests. | ||
| * | ||
@@ -489,3 +470,3 @@ * @param callback - Async function that executes the tool and returns the result. | ||
| * @example Handle tool calls from the host | ||
| * ```typescript | ||
| * ```ts source="./app.examples.ts#App_oncalltool_handleFromHost" | ||
| * app.oncalltool = async (params, extra) => { | ||
@@ -500,3 +481,3 @@ * if (params.name === "greet") { | ||
| * | ||
| * @see {@link setRequestHandler} for the underlying method | ||
| * @see {@link setRequestHandler `setRequestHandler`} for the underlying method | ||
| */ | ||
@@ -516,3 +497,3 @@ set oncalltool(callback: (params: CallToolRequest["params"], extra: RequestHandlerExtra) => Promise<CallToolResult>); | ||
| * | ||
| * Register handlers before calling {@link connect} to avoid missing requests. | ||
| * Register handlers before calling {@link connect `connect`} to avoid missing requests. | ||
| * | ||
@@ -524,6 +505,6 @@ * @param callback - Async function that returns tool names as strings (simplified | ||
| * @example Return available tools | ||
| * ```typescript | ||
| * ```ts source="./app.examples.ts#App_onlisttools_returnTools" | ||
| * app.onlisttools = async (params, extra) => { | ||
| * return { | ||
| * tools: ["calculate", "convert", "format"] | ||
| * tools: ["greet", "calculate", "format"], | ||
| * }; | ||
@@ -533,4 +514,4 @@ * }; | ||
| * | ||
| * @see {@link setRequestHandler} for the underlying method | ||
| * @see {@link oncalltool} for handling tool execution | ||
| * @see {@link setRequestHandler `setRequestHandler`} for the underlying method | ||
| * @see {@link oncalltool `oncalltool`} for handling tool execution | ||
| */ | ||
@@ -584,7 +565,7 @@ set onlisttools(callback: (params: ListToolsRequest["params"], extra: RequestHandlerExtra) => Promise<{ | ||
| * @example Fetch updated weather data | ||
| * ```typescript | ||
| * ```ts source="./app.examples.ts#App_callServerTool_fetchWeather" | ||
| * try { | ||
| * const result = await app.callServerTool({ | ||
| * name: "get_weather", | ||
| * arguments: { location: "Tokyo" } | ||
| * arguments: { location: "Tokyo" }, | ||
| * }); | ||
@@ -610,20 +591,43 @@ * if (result.isError) { | ||
| * @param options - Request options (timeout, etc.) | ||
| * @returns Result indicating success or error (no message content returned) | ||
| * @returns Result with optional `isError` flag indicating host rejection | ||
| * | ||
| * @throws {Error} If the host rejects the message | ||
| * @throws {Error} If the request times out or the connection is lost | ||
| * | ||
| * @example Send a text message from user interaction | ||
| * ```typescript | ||
| * ```ts source="./app.examples.ts#App_sendMessage_textFromInteraction" | ||
| * try { | ||
| * await app.sendMessage({ | ||
| * const result = await app.sendMessage({ | ||
| * role: "user", | ||
| * content: [{ type: "text", text: "Show me details for item #42" }] | ||
| * content: [{ type: "text", text: "Show me details for item #42" }], | ||
| * }); | ||
| * if (result.isError) { | ||
| * console.error("Host rejected the message"); | ||
| * // Handle rejection appropriately for your app | ||
| * } | ||
| * } catch (error) { | ||
| * console.error("Failed to send message:", error); | ||
| * // Handle error appropriately for your app | ||
| * // Handle transport/protocol error | ||
| * } | ||
| * ``` | ||
| * | ||
| * @see {@link McpUiMessageRequest} for request structure | ||
| * @example Send follow-up message after offloading large data to model context | ||
| * ```ts source="./app.examples.ts#App_sendMessage_withLargeContext" | ||
| * const markdown = `--- | ||
| * word-count: ${fullTranscript.split(/\s+/).length} | ||
| * speaker-names: ${speakerNames.join(", ")} | ||
| * --- | ||
| * | ||
| * ${fullTranscript}`; | ||
| * | ||
| * // Offload long transcript to model context | ||
| * await app.updateModelContext({ content: [{ type: "text", text: markdown }] }); | ||
| * | ||
| * // Send brief trigger message | ||
| * await app.sendMessage({ | ||
| * role: "user", | ||
| * content: [{ type: "text", text: "Summarize the key points" }], | ||
| * }); | ||
| * ``` | ||
| * | ||
| * @see {@link McpUiMessageRequest `McpUiMessageRequest`} for request structure | ||
| */ | ||
@@ -643,7 +647,7 @@ sendMessage(params: McpUiMessageRequest["params"], options?: RequestOptions): Promise<{ | ||
| * @example Log app state for debugging | ||
| * ```typescript | ||
| * ```ts source="./app.examples.ts#App_sendLog_debugState" | ||
| * app.sendLog({ | ||
| * level: "info", | ||
| * data: "Weather data refreshed", | ||
| * logger: "WeatherApp" | ||
| * logger: "WeatherApp", | ||
| * }); | ||
@@ -658,9 +662,8 @@ * ``` | ||
| * | ||
| * Unlike `sendLog`, which is for debugging/telemetry, context updates | ||
| * are intended to be available to the model in future reasoning, | ||
| * without requiring a follow-up action (like `sendMessage`). | ||
| * Context updates are intended to be available to the model in future | ||
| * turns, without triggering an immediate model response (unlike {@link sendMessage `sendMessage`}). | ||
| * | ||
| * The host will typically defer sending the context to the model until the | ||
| * next user message (including `ui/message`), and will only send the last | ||
| * update received. Each call overwrites any previous context update. | ||
| * next user message — either from the actual user or via `sendMessage`. Only | ||
| * the last update is sent; each call overwrites any previous context. | ||
| * | ||
@@ -671,15 +674,37 @@ * @param params - Context content and/or structured content | ||
| * @throws {Error} If the host rejects the context update (e.g., unsupported content type) | ||
| * @throws {Error} If the request times out or the connection is lost | ||
| * | ||
| * @example Update model context with current app state | ||
| * ```typescript | ||
| * ```ts source="./app.examples.ts#App_updateModelContext_appState" | ||
| * const markdown = `--- | ||
| * item-count: ${itemList.length} | ||
| * total-cost: ${totalCost} | ||
| * currency: ${currency} | ||
| * --- | ||
| * | ||
| * User is viewing their shopping cart with ${itemList.length} items selected: | ||
| * | ||
| * ${itemList.map((item) => `- ${item}`).join("\n")}`; | ||
| * | ||
| * await app.updateModelContext({ | ||
| * content: [{ type: "text", text: "User selected 3 items totaling $150.00" }] | ||
| * content: [{ type: "text", text: markdown }], | ||
| * }); | ||
| * ``` | ||
| * | ||
| * @example Update with structured content | ||
| * ```typescript | ||
| * await app.updateModelContext({ | ||
| * structuredContent: { selectedItems: 3, total: 150.00, currency: "USD" } | ||
| * }); | ||
| * @example Report runtime error to model | ||
| * ```ts source="./app.examples.ts#App_updateModelContext_reportError" | ||
| * try { | ||
| * const _stream = await navigator.mediaDevices.getUserMedia({ audio: true }); | ||
| * // ... use _stream for transcription | ||
| * } catch (err) { | ||
| * // Inform the model that the app is in a degraded state | ||
| * await app.updateModelContext({ | ||
| * content: [ | ||
| * { | ||
| * type: "text", | ||
| * text: "Error: transcription unavailable", | ||
| * }, | ||
| * ], | ||
| * }); | ||
| * } | ||
| * ``` | ||
@@ -702,22 +727,22 @@ * | ||
| * The host may deny this request based on user preferences or security policy. | ||
| * Apps should handle rejection gracefully. | ||
| * Apps should handle rejection gracefully by checking `result.isError`. | ||
| * | ||
| * @param params - URL to open | ||
| * @param options - Request options (timeout, etc.) | ||
| * @returns Result indicating success or error | ||
| * @returns Result with `isError: true` if the host denied the request (e.g., blocked domain, user cancelled) | ||
| * | ||
| * @throws {Error} If the host denies the request (e.g., blocked domain, user cancelled) | ||
| * @throws {Error} If the request times out or the connection is lost | ||
| * | ||
| * @example Open documentation link | ||
| * ```typescript | ||
| * try { | ||
| * await app.openLink({ url: "https://docs.example.com" }); | ||
| * } catch (error) { | ||
| * console.error("Failed to open link:", error); | ||
| * ```ts source="./app.examples.ts#App_openLink_documentation" | ||
| * const { isError } = await app.openLink({ url: "https://docs.example.com" }); | ||
| * if (isError) { | ||
| * // Host denied the request (e.g., blocked domain, user cancelled) | ||
| * // Optionally show fallback: display URL for manual copy | ||
| * console.warn("Link request denied"); | ||
| * } | ||
| * ``` | ||
| * | ||
| * @see {@link McpUiOpenLinkRequest} for request structure | ||
| * @see {@link McpUiOpenLinkRequest `McpUiOpenLinkRequest`} for request structure | ||
| * @see {@link McpUiOpenLinkResult `McpUiOpenLinkResult`} for result structure | ||
| */ | ||
@@ -728,3 +753,3 @@ openLink(params: McpUiOpenLinkRequest["params"], options?: RequestOptions): Promise<{ | ||
| }>; | ||
| /** @deprecated Use {@link openLink} instead */ | ||
| /** @deprecated Use {@link openLink `openLink`} instead */ | ||
| sendOpenLink: App["openLink"]; | ||
@@ -743,13 +768,14 @@ /** | ||
| * | ||
| * @example Request fullscreen mode | ||
| * ```typescript | ||
| * const context = app.getHostContext(); | ||
| * if (context?.availableDisplayModes?.includes("fullscreen")) { | ||
| * const result = await app.requestDisplayMode({ mode: "fullscreen" }); | ||
| * console.log("Display mode set to:", result.mode); | ||
| * @example Toggle display mode | ||
| * ```ts source="./app.examples.ts#App_requestDisplayMode_toggle" | ||
| * const ctx = app.getHostContext(); | ||
| * if (ctx?.availableDisplayModes?.includes("fullscreen")) { | ||
| * const target = ctx.displayMode === "fullscreen" ? "inline" : "fullscreen"; | ||
| * const result = await app.requestDisplayMode({ mode: target }); | ||
| * console.log("Now in:", result.mode); | ||
| * } | ||
| * ``` | ||
| * | ||
| * @see {@link McpUiRequestDisplayModeRequest} for request structure | ||
| * @see {@link McpUiHostContext} for checking availableDisplayModes | ||
| * @see {@link McpUiRequestDisplayModeRequest `McpUiRequestDisplayModeRequest`} for request structure | ||
| * @see {@link McpUiHostContext `McpUiHostContext`} for checking availableDisplayModes | ||
| */ | ||
@@ -769,6 +795,6 @@ requestDisplayMode(params: McpUiRequestDisplayModeRequest["params"], options?: RequestOptions): Promise<{ | ||
| * @example Manually notify host of size change | ||
| * ```typescript | ||
| * ```ts source="./app.examples.ts#App_sendSizeChanged_manual" | ||
| * app.sendSizeChanged({ | ||
| * width: 400, | ||
| * height: 600 | ||
| * height: 600, | ||
| * }); | ||
@@ -779,3 +805,3 @@ * ``` | ||
| * | ||
| * @see {@link McpUiSizeChangedNotification} for notification structure | ||
| * @see {@link McpUiSizeChangedNotification `McpUiSizeChangedNotification`} for notification structure | ||
| */ | ||
@@ -797,4 +823,8 @@ sendSizeChanged(params: McpUiSizeChangedNotification["params"]): Promise<void>; | ||
| * @example Manual setup for custom scenarios | ||
| * ```typescript | ||
| * const app = new App(appInfo, capabilities, { autoResize: false }); | ||
| * ```ts source="./app.examples.ts#App_setupAutoResize_manual" | ||
| * const app = new App( | ||
| * { name: "MyApp", version: "1.0.0" }, | ||
| * {}, | ||
| * { autoResize: false }, | ||
| * ); | ||
| * await app.connect(transport); | ||
@@ -818,3 +848,3 @@ * | ||
| * 4. Sends `ui/notifications/initialized` notification | ||
| * 5. Sets up auto-resize using {@link setupSizeChangedNotifications} if enabled (default) | ||
| * 5. Sets up auto-resize using {@link setupSizeChangedNotifications `setupSizeChangedNotifications`} if enabled (default) | ||
| * | ||
@@ -824,3 +854,3 @@ * If initialization fails, the connection is automatically closed and an error | ||
| * | ||
| * @param transport - Transport layer (typically {@link PostMessageTransport}) | ||
| * @param transport - Transport layer (typically {@link PostMessageTransport `PostMessageTransport`}) | ||
| * @param options - Request options for the initialize request | ||
@@ -831,7 +861,4 @@ * | ||
| * @example Connect with PostMessageTransport | ||
| * ```typescript | ||
| * const app = new App( | ||
| * { name: "MyApp", version: "1.0.0" }, | ||
| * {} | ||
| * ); | ||
| * ```ts source="./app.examples.ts#App_connect_withPostMessageTransport" | ||
| * const app = new App({ name: "MyApp", version: "1.0.0" }, {}); | ||
| * | ||
@@ -846,7 +873,7 @@ * try { | ||
| * | ||
| * @see {@link McpUiInitializeRequest} for the initialization request structure | ||
| * @see {@link McpUiInitializedNotification} for the initialized notification | ||
| * @see {@link PostMessageTransport} for the typical transport implementation | ||
| * @see {@link McpUiInitializeRequest `McpUiInitializeRequest`} for the initialization request structure | ||
| * @see {@link McpUiInitializedNotification `McpUiInitializedNotification`} for the initialized notification | ||
| * @see {@link PostMessageTransport `PostMessageTransport`} for the typical transport implementation | ||
| */ | ||
| connect(transport?: Transport, options?: RequestOptions): Promise<void>; | ||
| } |
@@ -26,3 +26,3 @@ import { z } from "zod"; | ||
| * @description Request to open an external URL in the host's default browser. | ||
| * @see {@link app!App.openLink} for the method that sends this request | ||
| * @see {@link app!App.openLink `App.openLink`} for the method that sends this request | ||
| */ | ||
@@ -37,3 +37,3 @@ export declare const McpUiOpenLinkRequestSchema: z.ZodObject<{ | ||
| * @description Result from opening a URL. | ||
| * @see {@link McpUiOpenLinkRequest} | ||
| * @see {@link McpUiOpenLinkRequest `McpUiOpenLinkRequest`} | ||
| */ | ||
@@ -45,3 +45,3 @@ export declare const McpUiOpenLinkResultSchema: z.ZodObject<{ | ||
| * @description Result from sending a message. | ||
| * @see {@link McpUiMessageRequest} | ||
| * @see {@link McpUiMessageRequest `McpUiMessageRequest`} | ||
| */ | ||
@@ -81,4 +81,4 @@ export declare const McpUiMessageResultSchema: z.ZodObject<{ | ||
| /** | ||
| * @description Notification of UI size changes (Guest UI -> Host). | ||
| * @see {@link app!App.sendSizeChanged} for the method to send this from Guest UI | ||
| * @description Notification of UI size changes (View -> Host). | ||
| * @see {@link app!App.sendSizeChanged `App.sendSizeChanged`} for the method to send this from View | ||
| */ | ||
@@ -93,3 +93,3 @@ export declare const McpUiSizeChangedNotificationSchema: z.ZodObject<{ | ||
| /** | ||
| * @description Notification containing complete tool arguments (Host -> Guest UI). | ||
| * @description Notification containing complete tool arguments (Host -> View). | ||
| */ | ||
@@ -103,3 +103,3 @@ export declare const McpUiToolInputNotificationSchema: z.ZodObject<{ | ||
| /** | ||
| * @description Notification containing partial/streaming tool arguments (Host -> Guest UI). | ||
| * @description Notification containing partial/streaming tool arguments (Host -> View). | ||
| */ | ||
@@ -113,3 +113,3 @@ export declare const McpUiToolInputPartialNotificationSchema: z.ZodObject<{ | ||
| /** | ||
| * @description Notification that tool execution was cancelled (Host -> Guest UI). | ||
| * @description Notification that tool execution was cancelled (Host -> View). | ||
| * Host MUST send this if tool execution was cancelled for any reason (user action, | ||
@@ -140,4 +140,4 @@ * sampling error, classifier intervention, etc.). | ||
| /** | ||
| * @description Request for graceful shutdown of the Guest UI (Host -> Guest UI). | ||
| * @see {@link app-bridge!AppBridge.teardownResource} for the host method that sends this | ||
| * @description Request for graceful shutdown of the View (Host -> View). | ||
| * @see {@link app-bridge!AppBridge.teardownResource `AppBridge.teardownResource`} for the host method that sends this | ||
| */ | ||
@@ -150,3 +150,3 @@ export declare const McpUiResourceTeardownRequestSchema: z.ZodObject<{ | ||
| * @description Result from graceful shutdown request. | ||
| * @see {@link McpUiResourceTeardownRequest} | ||
| * @see {@link McpUiResourceTeardownRequest `McpUiResourceTeardownRequest`} | ||
| */ | ||
@@ -164,3 +164,3 @@ export declare const McpUiResourceTeardownResultSchema: z.ZodRecord<z.ZodString, z.ZodUnknown>; | ||
| * @description Capabilities supported by the host application. | ||
| * @see {@link McpUiInitializeResult} for the initialization result that includes these capabilities | ||
| * @see {@link McpUiInitializeResult `McpUiInitializeResult`} for the initialization result that includes these capabilities | ||
| */ | ||
@@ -209,4 +209,4 @@ export declare const McpUiHostCapabilitiesSchema: z.ZodObject<{ | ||
| /** | ||
| * @description Capabilities provided by the Guest UI ({@link app!App}). | ||
| * @see {@link McpUiInitializeRequest} for the initialization request that includes these capabilities | ||
| * @description Capabilities provided by the View ({@link app!App `App`}). | ||
| * @see {@link McpUiInitializeRequest `McpUiInitializeRequest`} for the initialization request that includes these capabilities | ||
| */ | ||
@@ -218,6 +218,7 @@ export declare const McpUiAppCapabilitiesSchema: z.ZodObject<{ | ||
| }, z.core.$strip>>; | ||
| availableDisplayModes: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodLiteral<"inline">, z.ZodLiteral<"fullscreen">, z.ZodLiteral<"pip">]>>>; | ||
| }, z.core.$strip>; | ||
| /** | ||
| * @description Notification that Guest UI has completed initialization (Guest UI -> Host). | ||
| * @see {@link app!App.connect} for the method that sends this notification | ||
| * @description Notification that View has completed initialization (View -> Host). | ||
| * @see {@link app!App.connect `App.connect`} for the method that sends this notification | ||
| */ | ||
@@ -251,3 +252,3 @@ export declare const McpUiInitializedNotificationSchema: z.ZodObject<{ | ||
| * which may differ from the requested mode if not supported. | ||
| * @see {@link app!App.requestDisplayMode} for the method that sends this request | ||
| * @see {@link app!App.requestDisplayMode `App.requestDisplayMode`} for the method that sends this request | ||
| */ | ||
@@ -262,3 +263,3 @@ export declare const McpUiRequestDisplayModeRequestSchema: z.ZodObject<{ | ||
| * @description Result from requesting a display mode change. | ||
| * @see {@link McpUiRequestDisplayModeRequest} | ||
| * @see {@link McpUiRequestDisplayModeRequest `McpUiRequestDisplayModeRequest`} | ||
| */ | ||
@@ -280,4 +281,14 @@ export declare const McpUiRequestDisplayModeResultSchema: z.ZodObject<{ | ||
| /** | ||
| * @description MCP Apps capability settings advertised by clients to servers. | ||
| * | ||
| * Clients advertise these capabilities via the `extensions` field in their | ||
| * capabilities during MCP initialization. Servers can check for MCP Apps | ||
| * support using {@link server-helpers!getUiCapability}. | ||
| */ | ||
| export declare const McpUiClientCapabilitiesSchema: z.ZodObject<{ | ||
| mimeTypes: z.ZodOptional<z.ZodArray<z.ZodString>>; | ||
| }, z.core.$strip>; | ||
| /** | ||
| * @description Request to send a message to the host's chat interface. | ||
| * @see {@link app!App.sendMessage} for the method that sends this request | ||
| * @see {@link app!App.sendMessage `App.sendMessage`} for the method that sends this request | ||
| */ | ||
@@ -401,3 +412,3 @@ export declare const McpUiMessageRequestSchema: z.ZodObject<{ | ||
| /** | ||
| * @description Notification containing tool execution result (Host -> Guest UI). | ||
| * @description Notification containing tool execution result (Host -> View). | ||
| */ | ||
@@ -504,3 +515,3 @@ export declare const McpUiToolResultNotificationSchema: z.ZodObject<{ | ||
| /** | ||
| * @description Rich context about the host environment provided to Guest UIs. | ||
| * @description Rich context about the host environment provided to views. | ||
| */ | ||
@@ -558,3 +569,3 @@ export declare const McpUiHostContextSchema: z.ZodObject<{ | ||
| displayMode: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"inline">, z.ZodLiteral<"fullscreen">, z.ZodLiteral<"pip">]>>; | ||
| availableDisplayModes: z.ZodOptional<z.ZodArray<z.ZodString>>; | ||
| availableDisplayModes: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodLiteral<"inline">, z.ZodLiteral<"fullscreen">, z.ZodLiteral<"pip">]>>>; | ||
| containerDimensions: z.ZodOptional<z.ZodIntersection<z.ZodUnion<readonly [z.ZodObject<{ | ||
@@ -585,4 +596,4 @@ height: z.ZodNumber; | ||
| /** | ||
| * @description Notification that host context has changed (Host -> Guest UI). | ||
| * @see {@link McpUiHostContext} for the full context structure | ||
| * @description Notification that host context has changed (Host -> View). | ||
| * @see {@link McpUiHostContext `McpUiHostContext`} for the full context structure | ||
| */ | ||
@@ -642,3 +653,3 @@ export declare const McpUiHostContextChangedNotificationSchema: z.ZodObject<{ | ||
| displayMode: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"inline">, z.ZodLiteral<"fullscreen">, z.ZodLiteral<"pip">]>>; | ||
| availableDisplayModes: z.ZodOptional<z.ZodArray<z.ZodString>>; | ||
| availableDisplayModes: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodLiteral<"inline">, z.ZodLiteral<"fullscreen">, z.ZodLiteral<"pip">]>>>; | ||
| containerDimensions: z.ZodOptional<z.ZodIntersection<z.ZodUnion<readonly [z.ZodObject<{ | ||
@@ -670,6 +681,6 @@ height: z.ZodNumber; | ||
| /** | ||
| * @description Request to update the agent's context without requiring a follow-up action (Guest UI -> Host). | ||
| * @description Request to update the agent's context without requiring a follow-up action (View -> Host). | ||
| * | ||
| * Unlike `notifications/message` which is for debugging/logging, this request is intended | ||
| * to update the Host's model context. Each request overwrites the previous context sent by the Guest UI. | ||
| * to update the Host's model context. Each request overwrites the previous context sent by the View. | ||
| * Unlike messages, context updates do not trigger follow-ups. | ||
@@ -680,3 +691,3 @@ * | ||
| * | ||
| * @see {@link app.App.updateModelContext} for the method that sends this request | ||
| * @see {@link app.App.updateModelContext `App.updateModelContext`} for the method that sends this request | ||
| */ | ||
@@ -776,4 +787,4 @@ export declare const McpUiUpdateModelContextRequestSchema: z.ZodObject<{ | ||
| /** | ||
| * @description Initialization request sent from Guest UI to Host. | ||
| * @see {@link app!App.connect} for the method that sends this request | ||
| * @description Initialization request sent from View to Host. | ||
| * @see {@link app!App.connect `App.connect`} for the method that sends this request | ||
| */ | ||
@@ -804,2 +815,3 @@ export declare const McpUiInitializeRequestSchema: z.ZodObject<{ | ||
| }, z.core.$strip>>; | ||
| availableDisplayModes: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodLiteral<"inline">, z.ZodLiteral<"fullscreen">, z.ZodLiteral<"pip">]>>>; | ||
| }, z.core.$strip>; | ||
@@ -810,4 +822,4 @@ protocolVersion: z.ZodString; | ||
| /** | ||
| * @description Initialization result returned from Host to Guest UI. | ||
| * @see {@link McpUiInitializeRequest} | ||
| * @description Initialization result returned from Host to View. | ||
| * @see {@link McpUiInitializeRequest `McpUiInitializeRequest`} | ||
| */ | ||
@@ -924,3 +936,3 @@ export declare const McpUiInitializeResultSchema: z.ZodObject<{ | ||
| displayMode: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"inline">, z.ZodLiteral<"fullscreen">, z.ZodLiteral<"pip">]>>; | ||
| availableDisplayModes: z.ZodOptional<z.ZodArray<z.ZodString>>; | ||
| availableDisplayModes: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodLiteral<"inline">, z.ZodLiteral<"fullscreen">, z.ZodLiteral<"pip">]>>>; | ||
| containerDimensions: z.ZodOptional<z.ZodIntersection<z.ZodUnion<readonly [z.ZodObject<{ | ||
@@ -927,0 +939,0 @@ height: z.ZodNumber; |
@@ -30,2 +30,3 @@ import { z } from "zod"; | ||
| export type McpUiToolMetaSchemaInferredType = z.infer<typeof generated.McpUiToolMetaSchema>; | ||
| export type McpUiClientCapabilitiesSchemaInferredType = z.infer<typeof generated.McpUiClientCapabilitiesSchema>; | ||
| export type McpUiMessageRequestSchemaInferredType = z.infer<typeof generated.McpUiMessageRequestSchema>; | ||
@@ -32,0 +33,0 @@ export type McpUiSandboxResourceReadyNotificationSchemaInferredType = z.infer<typeof generated.McpUiSandboxResourceReadyNotificationSchema>; |
@@ -13,3 +13,3 @@ import { JSONRPCMessage, MessageExtraInfo } from "@modelcontextprotocol/sdk/types.js"; | ||
| * The `eventSource` parameter is required and validates the message source window | ||
| * by checking `event.source`. For guest UIs, pass `window.parent`. | ||
| * by checking `event.source`. For views, pass `window.parent`. | ||
| * For hosts, pass `iframe.contentWindow` to validate the iframe source. | ||
@@ -19,4 +19,4 @@ * | ||
| * | ||
| * **Guest UI**: | ||
| * ```typescript | ||
| * **View**: | ||
| * ```ts source="./message-transport.examples.ts#PostMessageTransport_view" | ||
| * const transport = new PostMessageTransport(window.parent, window.parent); | ||
@@ -27,7 +27,7 @@ * await app.connect(transport); | ||
| * **Host**: | ||
| * ```typescript | ||
| * const iframe = document.getElementById('app-iframe') as HTMLIFrameElement; | ||
| * ```ts source="./message-transport.examples.ts#PostMessageTransport_host" | ||
| * const iframe = document.getElementById("app-iframe") as HTMLIFrameElement; | ||
| * const transport = new PostMessageTransport( | ||
| * iframe.contentWindow!, | ||
| * iframe.contentWindow! | ||
| * iframe.contentWindow!, | ||
| * ); | ||
@@ -37,4 +37,4 @@ * await bridge.connect(transport); | ||
| * | ||
| * @see {@link app!App.connect} for Guest UI usage | ||
| * @see {@link app-bridge!AppBridge.connect} for Host usage | ||
| * @see {@link app!App.connect `App.connect`} for View usage | ||
| * @see {@link app-bridge!AppBridge.connect `AppBridge.connect`} for Host usage | ||
| */ | ||
@@ -49,7 +49,7 @@ export declare class PostMessageTransport implements Transport { | ||
| * @param eventTarget - Target window to send messages to (default: `window.parent`) | ||
| * @param eventSource - Source window for message validation. For guests, pass | ||
| * @param eventSource - Source window for message validation. For views, pass | ||
| * `window.parent`. For hosts, pass `iframe.contentWindow`. | ||
| * | ||
| * @example Guest UI connecting to parent | ||
| * ```typescript | ||
| * @example View connecting to parent | ||
| * ```ts source="./message-transport.examples.ts#PostMessageTransport_constructor_view" | ||
| * const transport = new PostMessageTransport(window.parent, window.parent); | ||
@@ -59,7 +59,7 @@ * ``` | ||
| * @example Host connecting to iframe | ||
| * ```typescript | ||
| * const iframe = document.getElementById('app') as HTMLIFrameElement; | ||
| * ```ts source="./message-transport.examples.ts#PostMessageTransport_constructor_host" | ||
| * const iframe = document.getElementById("app-iframe") as HTMLIFrameElement; | ||
| * const transport = new PostMessageTransport( | ||
| * iframe.contentWindow!, | ||
| * iframe.contentWindow! | ||
| * iframe.contentWindow!, | ||
| * ); | ||
@@ -89,3 +89,3 @@ * ``` | ||
| * | ||
| * Removes the message event listener and calls the {@link onclose} callback if set. | ||
| * Removes the message event listener and calls the {@link onclose `onclose`} callback if set. | ||
| */ | ||
@@ -96,3 +96,3 @@ close(): Promise<void>; | ||
| * | ||
| * Set this handler to be notified when {@link close} is called. | ||
| * Set this handler to be notified when {@link close `close`} is called. | ||
| */ | ||
@@ -112,3 +112,3 @@ onclose?: () => void; | ||
| * | ||
| * This handler is invoked after message validation succeeds. The {@link start} | ||
| * This handler is invoked after message validation succeeds. The {@link start `start`} | ||
| * method must be called before messages will be received. | ||
@@ -115,0 +115,0 @@ * |
@@ -6,3 +6,3 @@ /** | ||
| * interactive MCP Apps using React. This is optional - the core SDK | ||
| * ({@link App}, {@link PostMessageTransport}) is framework-agnostic and can be | ||
| * ({@link App `App`}, {@link PostMessageTransport `PostMessageTransport`}) is framework-agnostic and can be | ||
| * used with any UI framework or vanilla JavaScript. | ||
@@ -12,7 +12,7 @@ * | ||
| * | ||
| * - {@link useApp} - React hook to create and connect an MCP App | ||
| * - {@link useHostStyleVariables} - React hook to apply host style variables and theme | ||
| * - {@link useHostFonts} - React hook to apply host fonts | ||
| * - {@link useDocumentTheme} - React hook for reactive document theme | ||
| * - {@link useAutoResize} - React hook for manual auto-resize control (rarely needed) | ||
| * - {@link useApp `useApp`} - React hook to create and connect an MCP App | ||
| * - {@link useHostStyleVariables `useHostStyleVariables`} - React hook to apply host style variables and theme | ||
| * - {@link useHostFonts `useHostFonts`} - React hook to apply host fonts | ||
| * - {@link useDocumentTheme `useDocumentTheme`} - React hook for reactive document theme | ||
| * - {@link useAutoResize `useAutoResize`} - React hook for manual auto-resize control (rarely needed) | ||
| * | ||
@@ -22,9 +22,7 @@ * @module @modelcontextprotocol/ext-apps/react | ||
| * @example Basic React App | ||
| * ```tsx | ||
| * import { useApp } from '@modelcontextprotocol/ext-apps/react'; | ||
| * | ||
| * ```tsx source="./index.examples.tsx#index_basicReactApp" | ||
| * function MyApp() { | ||
| * const { app, isConnected, error } = useApp({ | ||
| * appInfo: { name: "MyApp", version: "1.0.0" }, | ||
| * capabilities: {} | ||
| * capabilities: {}, | ||
| * }); | ||
@@ -31,0 +29,0 @@ * |
@@ -5,10 +5,10 @@ import { Implementation } from "@modelcontextprotocol/sdk/types.js"; | ||
| /** | ||
| * Options for configuring the {@link useApp} hook. | ||
| * Options for configuring the {@link useApp `useApp`} hook. | ||
| * | ||
| * Note: This interface does NOT expose {@link App} options like `autoResize`. | ||
| * Note: This interface does NOT expose {@link App `App`} options like `autoResize`. | ||
| * The hook creates the `App` with default options (`autoResize: true`). If you | ||
| * need custom `App` options, create the `App` manually instead of using this hook. | ||
| * | ||
| * @see {@link useApp} for the hook that uses these options | ||
| * @see {@link useAutoResize} for manual auto-resize control with custom `App` options | ||
| * @see {@link useApp `useApp`} for the hook that uses these options | ||
| * @see {@link useAutoResize `useAutoResize`} for manual auto-resize control with custom `App` options | ||
| */ | ||
@@ -23,3 +23,3 @@ export interface UseAppOptions { | ||
| /** | ||
| * Called after {@link App} is created but before connection. | ||
| * Called after {@link App `App`} is created but before connection. | ||
| * | ||
@@ -31,14 +31,13 @@ * Use this to register request/notification handlers that need to be in place | ||
| * | ||
| * @example Register a notification handler | ||
| * ```typescript | ||
| * import { McpUiToolInputNotificationSchema } from '@modelcontextprotocol/ext-apps/react'; | ||
| * | ||
| * onAppCreated: (app) => { | ||
| * app.setNotificationHandler( | ||
| * McpUiToolInputNotificationSchema, | ||
| * (notification) => { | ||
| * console.log("Tool input:", notification.params.arguments); | ||
| * } | ||
| * ); | ||
| * } | ||
| * @example Register an event handler | ||
| * ```tsx source="./useApp.examples.tsx#useApp_registerHandler" | ||
| * useApp({ | ||
| * appInfo: { name: "MyApp", version: "1.0.0" }, | ||
| * capabilities: {}, | ||
| * onAppCreated: (app) => { | ||
| * app.ontoolresult = (result) => { | ||
| * console.log("Tool result:", result); | ||
| * }; | ||
| * }, | ||
| * }); | ||
| * ``` | ||
@@ -49,6 +48,6 @@ */ | ||
| /** | ||
| * State returned by the {@link useApp} hook. | ||
| * State returned by the {@link useApp `useApp`} hook. | ||
| */ | ||
| export interface AppState { | ||
| /** The connected {@link App} instance, null during initialization */ | ||
| /** The connected {@link App `App`} instance, null during initialization */ | ||
| app: App | null; | ||
@@ -63,4 +62,4 @@ /** Whether initialization completed successfully */ | ||
| * | ||
| * This hook manages {@link App} creation and connection. It automatically | ||
| * creates a {@link PostMessageTransport} to window.parent and handles | ||
| * This hook manages {@link App `App`} creation and connection. It automatically | ||
| * creates a {@link PostMessageTransport `PostMessageTransport`} to window.parent and handles | ||
| * initialization. | ||
@@ -76,3 +75,3 @@ * | ||
| * issues during React Strict Mode's double-mount cycle. If you need to | ||
| * explicitly close the `App`, call {@link App.close} manually. | ||
| * explicitly close the `App`, call {@link App.close `App.close`} manually. | ||
| * | ||
@@ -84,7 +83,9 @@ * @param options - Configuration for the app | ||
| * | ||
| * @example Basic usage | ||
| * ```typescript | ||
| * import { useApp, McpUiToolInputNotificationSchema } from '@modelcontextprotocol/ext-apps/react'; | ||
| * @example Basic usage of useApp hook with common event handlers | ||
| * ```tsx source="./useApp.examples.tsx#useApp_basicUsage" | ||
| * function MyApp() { | ||
| * const [hostContext, setHostContext] = useState< | ||
| * McpUiHostContext | undefined | ||
| * >(undefined); | ||
| * | ||
| * function MyApp() { | ||
| * const { app, isConnected, error } = useApp({ | ||
@@ -94,9 +95,17 @@ * appInfo: { name: "MyApp", version: "1.0.0" }, | ||
| * onAppCreated: (app) => { | ||
| * // Register handlers before connection | ||
| * app.setNotificationHandler( | ||
| * McpUiToolInputNotificationSchema, | ||
| * (notification) => { | ||
| * console.log("Tool input:", notification.params.arguments); | ||
| * } | ||
| * ); | ||
| * app.ontoolinput = (input) => { | ||
| * console.log("Tool input:", input); | ||
| * }; | ||
| * app.ontoolresult = (result) => { | ||
| * console.log("Tool result:", result); | ||
| * }; | ||
| * app.ontoolcancelled = (params) => { | ||
| * console.log("Tool cancelled:", params.reason); | ||
| * }; | ||
| * app.onerror = (error) => { | ||
| * console.log("Error:", error); | ||
| * }; | ||
| * app.onhostcontextchanged = (params) => { | ||
| * setHostContext((prev) => ({ ...prev, ...params })); | ||
| * }; | ||
| * }, | ||
@@ -107,9 +116,9 @@ * }); | ||
| * if (!isConnected) return <div>Connecting...</div>; | ||
| * return <div>Connected!</div>; | ||
| * return <div>Theme: {hostContext?.theme}</div>; | ||
| * } | ||
| * ``` | ||
| * | ||
| * @see {@link App.connect} for the underlying connection method | ||
| * @see {@link useAutoResize} for manual auto-resize control when using custom App options | ||
| * @see {@link App.connect `App.connect`} for the underlying connection method | ||
| * @see {@link useAutoResize `useAutoResize`} for manual auto-resize control when using custom App options | ||
| */ | ||
| export declare function useApp({ appInfo, capabilities, onAppCreated, }: UseAppOptions): AppState; |
@@ -11,8 +11,8 @@ import { RefObject } from "react"; | ||
| * | ||
| * **Note**: This hook is rarely needed since the {@link useApp} hook automatically enables | ||
| * **Note**: This hook is rarely needed since the {@link useApp `useApp`} hook automatically enables | ||
| * auto-resize by default. This hook is provided for advanced cases where you | ||
| * create the {@link App} manually with `autoResize: false` and want to add auto-resize | ||
| * create the {@link App `App`} manually with `autoResize: false` and want to add auto-resize | ||
| * behavior later. | ||
| * | ||
| * @param app - The connected {@link App} instance, or null during initialization | ||
| * @param app - The connected {@link App `App`} instance, or null during initialization | ||
| * @param elementRef - Currently unused. The hook always observes `document.body` | ||
@@ -23,3 +23,3 @@ * and `document.documentElement` regardless of this value. Passing a ref will | ||
| * @example Manual App creation with custom auto-resize control | ||
| * ```tsx | ||
| * ```tsx source="./useAutoResize.examples.tsx#useAutoResize_manualApp" | ||
| * function MyComponent() { | ||
@@ -34,7 +34,8 @@ * // For custom App options, create App manually instead of using useApp | ||
| * {}, // capabilities | ||
| * { autoResize: false } // Disable default auto-resize | ||
| * { autoResize: false }, // Disable default auto-resize | ||
| * ); | ||
| * | ||
| * const transport = new PostMessageTransport(window.parent, window.parent); | ||
| * myApp.connect(transport) | ||
| * myApp | ||
| * .connect(transport) | ||
| * .then(() => setApp(myApp)) | ||
@@ -52,6 +53,6 @@ * .catch((err) => setError(err)); | ||
| * | ||
| * @see {@link App.setupSizeChangedNotifications} for the underlying implementation | ||
| * @see {@link useApp} which enables auto-resize by default | ||
| * @see {@link App} constructor for configuring `autoResize` option | ||
| * @see {@link App.setupSizeChangedNotifications `App.setupSizeChangedNotifications`} for the underlying implementation | ||
| * @see {@link useApp `useApp`} which enables auto-resize by default | ||
| * @see {@link App `App`} constructor for configuring `autoResize` option | ||
| */ | ||
| export declare function useAutoResize(app: App | null, elementRef?: RefObject<HTMLElement | null>): void; |
@@ -15,13 +15,7 @@ import { McpUiTheme } from "../types"; | ||
| * @example Conditionally render based on theme | ||
| * ```tsx | ||
| * import { useDocumentTheme } from '@modelcontextprotocol/ext-apps/react'; | ||
| * | ||
| * ```tsx source="./useDocumentTheme.examples.tsx#useDocumentTheme_conditionalRender" | ||
| * function MyApp() { | ||
| * const theme = useDocumentTheme(); | ||
| * | ||
| * return ( | ||
| * <div> | ||
| * {theme === 'dark' ? <DarkIcon /> : <LightIcon />} | ||
| * </div> | ||
| * ); | ||
| * return <div>{theme === "dark" ? <DarkIcon /> : <LightIcon />}</div>; | ||
| * } | ||
@@ -31,3 +25,3 @@ * ``` | ||
| * @example Use with theme-aware styling | ||
| * ```tsx | ||
| * ```tsx source="./useDocumentTheme.examples.tsx#useDocumentTheme_themedButton" | ||
| * function ThemedButton() { | ||
@@ -37,6 +31,8 @@ * const theme = useDocumentTheme(); | ||
| * return ( | ||
| * <button style={{ | ||
| * background: theme === 'dark' ? '#333' : '#fff', | ||
| * color: theme === 'dark' ? '#fff' : '#333', | ||
| * }}> | ||
| * <button | ||
| * style={{ | ||
| * background: theme === "dark" ? "#333" : "#fff", | ||
| * color: theme === "dark" ? "#fff" : "#333", | ||
| * }} | ||
| * > | ||
| * Click me | ||
@@ -48,5 +44,5 @@ * </button> | ||
| * | ||
| * @see {@link getDocumentTheme} for the underlying function | ||
| * @see {@link applyDocumentTheme} to set the theme | ||
| * @see {@link getDocumentTheme `getDocumentTheme`} for the underlying function | ||
| * @see {@link applyDocumentTheme `applyDocumentTheme`} to set the theme | ||
| */ | ||
| export declare function useDocumentTheme(): McpUiTheme; |
@@ -17,3 +17,3 @@ import { App } from "../app"; | ||
| * | ||
| * @param app - The connected {@link App} instance, or null during initialization | ||
| * @param app - The connected {@link App `App`} instance, or null during initialization | ||
| * @param initialContext - Initial host context from the connection (optional). | ||
@@ -23,7 +23,5 @@ * If provided, styles and theme will be applied immediately on mount. | ||
| * @example | ||
| * ```tsx | ||
| * import { useApp, useHostStyleVariables } from '@modelcontextprotocol/ext-apps/react'; | ||
| * | ||
| * ```tsx source="./useHostStyles.examples.tsx#useHostStyleVariables_basicUsage" | ||
| * function MyApp() { | ||
| * const { app, isConnected } = useApp({ | ||
| * const { app } = useApp({ | ||
| * appInfo: { name: "MyApp", version: "1.0.0" }, | ||
@@ -37,3 +35,3 @@ * capabilities: {}, | ||
| * return ( | ||
| * <div style={{ background: 'var(--color-background-primary)' }}> | ||
| * <div style={{ background: "var(--color-background-primary)" }}> | ||
| * Hello! | ||
@@ -45,6 +43,6 @@ * </div> | ||
| * | ||
| * @see {@link applyHostStyleVariables} for the underlying styles function | ||
| * @see {@link applyDocumentTheme} for the underlying theme function | ||
| * @see {@link useHostFonts} for applying host fonts | ||
| * @see {@link McpUiStyles} for available CSS variables | ||
| * @see {@link applyHostStyleVariables `applyHostStyleVariables`} for the underlying styles function | ||
| * @see {@link applyDocumentTheme `applyDocumentTheme`} for the underlying theme function | ||
| * @see {@link useHostFonts `useHostFonts`} for applying host fonts | ||
| * @see {@link McpUiStyles `McpUiStyles`} for available CSS variables | ||
| */ | ||
@@ -64,3 +62,3 @@ export declare function useHostStyleVariables(app: App | null, initialContext?: McpUiHostContext | null): void; | ||
| * | ||
| * @param app - The connected {@link App} instance, or null during initialization | ||
| * @param app - The connected {@link App `App`} instance, or null during initialization | ||
| * @param initialContext - Initial host context from the connection (optional). | ||
@@ -70,8 +68,5 @@ * If provided, fonts will be applied immediately on mount. | ||
| * @example Basic usage with useApp | ||
| * ```tsx | ||
| * import { useApp } from '@modelcontextprotocol/ext-apps/react'; | ||
| * import { useHostFonts } from '@modelcontextprotocol/ext-apps/react'; | ||
| * | ||
| * ```tsx source="./useHostStyles.examples.tsx#useHostFonts_basicUsage" | ||
| * function MyApp() { | ||
| * const { app, isConnected } = useApp({ | ||
| * const { app } = useApp({ | ||
| * appInfo: { name: "MyApp", version: "1.0.0" }, | ||
@@ -81,24 +76,11 @@ * capabilities: {}, | ||
| * | ||
| * // Automatically apply host fonts | ||
| * useHostFonts(app); | ||
| * // Apply host fonts - pass initial context to apply fonts from connect() immediately | ||
| * useHostFonts(app, app?.getHostContext()); | ||
| * | ||
| * return ( | ||
| * <div style={{ fontFamily: 'var(--font-sans)' }}> | ||
| * Hello! | ||
| * </div> | ||
| * ); | ||
| * return <div style={{ fontFamily: "var(--font-sans)" }}>Hello!</div>; | ||
| * } | ||
| * ``` | ||
| * | ||
| * @example With initial context | ||
| * ```tsx | ||
| * const [hostContext, setHostContext] = useState<McpUiHostContext | null>(null); | ||
| * | ||
| * // ... get initial context from app.connect() result | ||
| * | ||
| * useHostFonts(app, hostContext); | ||
| * ``` | ||
| * | ||
| * @see {@link applyHostFonts} for the underlying fonts function | ||
| * @see {@link useHostStyleVariables} for applying style variables and theme | ||
| * @see {@link applyHostFonts `applyHostFonts`} for the underlying fonts function | ||
| * @see {@link useHostStyleVariables `useHostStyleVariables`} for applying style variables and theme | ||
| */ | ||
@@ -109,6 +91,6 @@ export declare function useHostFonts(app: App | null, initialContext?: McpUiHostContext | null): void; | ||
| * | ||
| * This is a convenience hook that combines {@link useHostStyleVariables} and | ||
| * {@link useHostFonts}. Use the individual hooks if you need more control. | ||
| * This is a convenience hook that combines {@link useHostStyleVariables `useHostStyleVariables`} and | ||
| * {@link useHostFonts `useHostFonts`}. Use the individual hooks if you need more control. | ||
| * | ||
| * @param app - The connected {@link App} instance, or null during initialization | ||
| * @param app - The connected {@link App `App`} instance, or null during initialization | ||
| * @param initialContext - Initial host context from the connection (optional). | ||
@@ -118,14 +100,23 @@ * Pass `app?.getHostContext()` to apply styles immediately on mount. | ||
| * @example | ||
| * ```tsx | ||
| * ```tsx source="./useHostStyles.examples.tsx#useHostStyles_basicUsage" | ||
| * function MyApp() { | ||
| * const { app } = useApp({ appInfo, capabilities: {} }); | ||
| * const { app } = useApp({ | ||
| * appInfo: { name: "MyApp", version: "1.0.0" }, | ||
| * capabilities: {}, | ||
| * }); | ||
| * | ||
| * // Apply all host styles - pass initial context to apply styles from connect() immediately | ||
| * useHostStyles(app, app?.getHostContext()); | ||
| * | ||
| * return <div style={{ background: 'var(--color-background-primary)' }}>...</div>; | ||
| * return ( | ||
| * <div style={{ background: "var(--color-background-primary)" }}> | ||
| * Hello! | ||
| * </div> | ||
| * ); | ||
| * } | ||
| * ``` | ||
| * | ||
| * @see {@link useHostStyleVariables} for style variables and theme only | ||
| * @see {@link useHostFonts} for fonts only | ||
| * @see {@link useHostStyleVariables `useHostStyleVariables`} for style variables and theme only | ||
| * @see {@link useHostFonts `useHostFonts`} for fonts only | ||
| */ | ||
| export declare function useHostStyles(app: App | null, initialContext?: McpUiHostContext | null): void; |
+168
-87
@@ -5,4 +5,4 @@ /** | ||
| * Use these helpers instead of the base SDK's `registerTool` and `registerResource` when | ||
| * your tool should render an {@link app!App} in the client. They handle UI metadata normalization | ||
| * and provide sensible defaults for the MCP Apps MIME type ({@link RESOURCE_MIME_TYPE}). | ||
| * your tool should render an {@link app!App `App`} in the client. They handle UI metadata normalization | ||
| * and provide sensible defaults for the MCP Apps MIME type ({@link RESOURCE_MIME_TYPE `RESOURCE_MIME_TYPE`}). | ||
| * | ||
@@ -12,19 +12,28 @@ * @module server-helpers | ||
| * @example | ||
| * ```typescript | ||
| * import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE } from '@modelcontextprotocol/ext-apps/server'; | ||
| * ```ts source="./index.examples.ts#index_overview" | ||
| * // Register a tool that displays a view | ||
| * registerAppTool( | ||
| * server, | ||
| * "weather", | ||
| * { | ||
| * description: "Get weather forecast", | ||
| * _meta: { ui: { resourceUri: "ui://weather/view.html" } }, | ||
| * }, | ||
| * toolCallback, | ||
| * ); | ||
| * | ||
| * // Register a tool that displays a widget | ||
| * registerAppTool(server, "weather", { | ||
| * description: "Get weather forecast", | ||
| * _meta: { ui: { resourceUri: "ui://weather/widget.html" } }, | ||
| * }, handler); | ||
| * | ||
| * // Register the HTML resource the tool references | ||
| * registerAppResource(server, "Weather Widget", "ui://weather/widget.html", {}, readCallback); | ||
| * registerAppResource( | ||
| * server, | ||
| * "Weather View", | ||
| * "ui://weather/view.html", | ||
| * {}, | ||
| * readCallback, | ||
| * ); | ||
| * ``` | ||
| */ | ||
| import { RESOURCE_URI_META_KEY, RESOURCE_MIME_TYPE, McpUiResourceMeta, McpUiToolMeta } from "../app.js"; | ||
| import { RESOURCE_URI_META_KEY, RESOURCE_MIME_TYPE, McpUiResourceMeta, McpUiToolMeta, McpUiClientCapabilities } from "../app.js"; | ||
| import type { McpServer, RegisteredTool, ResourceMetadata, ToolCallback, ReadResourceCallback } from "@modelcontextprotocol/sdk/server/mcp.js"; | ||
| import type { AnySchema, ZodRawShapeCompat } from "@modelcontextprotocol/sdk/server/zod-compat.js"; | ||
| import type { ToolAnnotations } from "@modelcontextprotocol/sdk/types.js"; | ||
| import type { ClientCapabilities, ToolAnnotations } from "@modelcontextprotocol/sdk/types.js"; | ||
| export { RESOURCE_URI_META_KEY, RESOURCE_MIME_TYPE }; | ||
@@ -34,3 +43,3 @@ export type { ResourceMetadata, ToolCallback, ReadResourceCallback }; | ||
| * Base tool configuration matching the standard MCP server tool options. | ||
| * Extended by {@link McpUiAppToolConfig} to add UI metadata requirements. | ||
| * Extended by {@link McpUiAppToolConfig `McpUiAppToolConfig`} to add UI metadata requirements. | ||
| */ | ||
@@ -48,3 +57,3 @@ export interface ToolConfig { | ||
| * | ||
| * Extends {@link ToolConfig} with a required `_meta` field that specifies UI metadata. | ||
| * Extends {@link ToolConfig `ToolConfig`} with a required `_meta` field that specifies UI metadata. | ||
| * The UI resource can be specified in two ways: | ||
@@ -54,3 +63,3 @@ * - `_meta.ui.resourceUri` (preferred) | ||
| * | ||
| * @see {@link registerAppTool} for the recommended way to register app tools | ||
| * @see {@link registerAppTool `registerAppTool`} for the recommended way to register app tools | ||
| */ | ||
@@ -67,3 +76,3 @@ export interface McpUiAppToolConfig extends ToolConfig { | ||
| * | ||
| * @example "ui://weather/widget.html" | ||
| * @example "ui://weather/view.html" | ||
| * | ||
@@ -76,3 +85,3 @@ * @deprecated Use `_meta.ui.resourceUri` instead. | ||
| /** | ||
| * MCP App Resource configuration for {@link registerAppResource}. | ||
| * MCP App Resource configuration for {@link registerAppResource `registerAppResource`}. | ||
| * | ||
@@ -82,3 +91,3 @@ * Extends the base MCP SDK `ResourceMetadata` with optional UI metadata | ||
| * | ||
| * @see {@link registerAppResource} for usage | ||
| * @see {@link registerAppResource `registerAppResource`} for usage | ||
| */ | ||
@@ -111,55 +120,65 @@ export interface McpUiAppResourceConfig extends ResourceMetadata { | ||
| * @example Basic usage | ||
| * ```typescript | ||
| * import { registerAppTool } from '@modelcontextprotocol/ext-apps/server'; | ||
| * import { z } from 'zod'; | ||
| * | ||
| * registerAppTool(server, "get-weather", { | ||
| * title: "Get Weather", | ||
| * description: "Get current weather for a location", | ||
| * inputSchema: { location: z.string() }, | ||
| * _meta: { | ||
| * ui: { resourceUri: "ui://weather/widget.html" }, | ||
| * ```ts source="./index.examples.ts#registerAppTool_basicUsage" | ||
| * registerAppTool( | ||
| * server, | ||
| * "get-weather", | ||
| * { | ||
| * title: "Get Weather", | ||
| * description: "Get current weather for a location", | ||
| * inputSchema: { location: z.string() }, | ||
| * _meta: { | ||
| * ui: { resourceUri: "ui://weather/view.html" }, | ||
| * }, | ||
| * }, | ||
| * }, async (args) => { | ||
| * const weather = await fetchWeather(args.location); | ||
| * return { content: [{ type: "text", text: JSON.stringify(weather) }] }; | ||
| * }); | ||
| * async (args) => { | ||
| * const weather = await fetchWeather(args.location); | ||
| * return { content: [{ type: "text", text: JSON.stringify(weather) }] }; | ||
| * }, | ||
| * ); | ||
| * ``` | ||
| * | ||
| * @example Tool visibility - create app-only tools for UI actions | ||
| * ```typescript | ||
| * import { registerAppTool } from '@modelcontextprotocol/ext-apps/server'; | ||
| * import { z } from 'zod'; | ||
| * | ||
| * // Main tool - visible to both model and app (default) | ||
| * registerAppTool(server, "show-cart", { | ||
| * description: "Display the user's shopping cart", | ||
| * _meta: { | ||
| * ui: { | ||
| * resourceUri: "ui://shop/cart.html", | ||
| * visibility: ["model", "app"], | ||
| * @example Tool visible to model but not callable by UI | ||
| * ```ts source="./index.examples.ts#registerAppTool_modelOnlyVisibility" | ||
| * registerAppTool( | ||
| * server, | ||
| * "show-cart", | ||
| * { | ||
| * description: "Display the user's shopping cart", | ||
| * _meta: { | ||
| * ui: { | ||
| * resourceUri: "ui://shop/cart.html", | ||
| * visibility: ["model"], | ||
| * }, | ||
| * }, | ||
| * }, | ||
| * }, async () => { | ||
| * const cart = await getCart(); | ||
| * return { content: [{ type: "text", text: JSON.stringify(cart) }] }; | ||
| * }); | ||
| * async () => { | ||
| * const cart = await getCart(); | ||
| * return { content: [{ type: "text", text: JSON.stringify(cart) }] }; | ||
| * }, | ||
| * ); | ||
| * ``` | ||
| * | ||
| * // App-only tool - hidden from the model, only callable by the UI | ||
| * registerAppTool(server, "update-quantity", { | ||
| * description: "Update item quantity in cart", | ||
| * inputSchema: { itemId: z.string(), quantity: z.number() }, | ||
| * _meta: { | ||
| * ui: { | ||
| * resourceUri: "ui://shop/cart.html", | ||
| * visibility: ["app"], | ||
| * @example Tool hidden from model, only callable by UI | ||
| * ```ts source="./index.examples.ts#registerAppTool_appOnlyVisibility" | ||
| * registerAppTool( | ||
| * server, | ||
| * "update-quantity", | ||
| * { | ||
| * description: "Update item quantity in cart", | ||
| * inputSchema: { itemId: z.string(), quantity: z.number() }, | ||
| * _meta: { | ||
| * ui: { | ||
| * resourceUri: "ui://shop/cart.html", | ||
| * visibility: ["app"], | ||
| * }, | ||
| * }, | ||
| * }, | ||
| * }, async ({ itemId, quantity }) => { | ||
| * const cart = await updateCartItem(itemId, quantity); | ||
| * return { content: [{ type: "text", text: JSON.stringify(cart) }] }; | ||
| * }); | ||
| * async ({ itemId, quantity }) => { | ||
| * const cart = await updateCartItem(itemId, quantity); | ||
| * return { content: [{ type: "text", text: JSON.stringify(cart) }] }; | ||
| * }, | ||
| * ); | ||
| * ``` | ||
| * | ||
| * @see {@link registerAppResource} to register the HTML resource referenced by the tool | ||
| * @see {@link registerAppResource `registerAppResource`} to register the HTML resource referenced by the tool | ||
| */ | ||
@@ -174,3 +193,3 @@ export declare function registerAppTool<OutputArgs extends ZodRawShapeCompat | AnySchema, InputArgs extends undefined | ZodRawShapeCompat | AnySchema = undefined>(server: Pick<McpServer, "registerTool">, name: string, config: McpUiAppToolConfig & { | ||
| * This is a convenience wrapper around `server.registerResource` that: | ||
| * - Defaults the MIME type to {@link RESOURCE_MIME_TYPE} (`"text/html;profile=mcp-app"`) | ||
| * - Defaults the MIME type to {@link RESOURCE_MIME_TYPE `RESOURCE_MIME_TYPE`} (`"text/html;profile=mcp-app"`) | ||
| * - Provides a cleaner API matching the SDK's callback signature | ||
@@ -185,33 +204,95 @@ * | ||
| * @example Basic usage | ||
| * ```typescript | ||
| * import { registerAppResource } from '@modelcontextprotocol/ext-apps/server'; | ||
| * | ||
| * registerAppResource(server, "Weather Widget", "ui://weather/widget.html", { | ||
| * description: "Interactive weather display", | ||
| * }, async () => ({ | ||
| * contents: [{ | ||
| * uri: "ui://weather/widget.html", | ||
| * mimeType: RESOURCE_MIME_TYPE, | ||
| * text: await fs.readFile("dist/widget.html", "utf-8"), | ||
| * }], | ||
| * })); | ||
| * ```ts source="./index.examples.ts#registerAppResource_basicUsage" | ||
| * registerAppResource( | ||
| * server, | ||
| * "Weather View", | ||
| * "ui://weather/view.html", | ||
| * { | ||
| * description: "Interactive weather display", | ||
| * }, | ||
| * async () => ({ | ||
| * contents: [ | ||
| * { | ||
| * uri: "ui://weather/view.html", | ||
| * mimeType: RESOURCE_MIME_TYPE, | ||
| * text: await fs.readFile("dist/view.html", "utf-8"), | ||
| * }, | ||
| * ], | ||
| * }), | ||
| * ); | ||
| * ``` | ||
| * | ||
| * @example With CSP configuration for external domains | ||
| * ```typescript | ||
| * registerAppResource(server, "Music Player", "ui://music/player.html", { | ||
| * description: "Audio player with external soundfonts", | ||
| * _meta: { | ||
| * ui: { | ||
| * csp: { | ||
| * connectDomains: ["https://api.example.com"], // For fetch/WebSocket | ||
| * resourceDomains: ["https://cdn.example.com"], // For scripts/styles/images | ||
| * ```ts source="./index.examples.ts#registerAppResource_withCsp" | ||
| * registerAppResource( | ||
| * server, | ||
| * "Music Player", | ||
| * "ui://music/player.html", | ||
| * { | ||
| * description: "Audio player with external soundfonts", | ||
| * }, | ||
| * async () => ({ | ||
| * contents: [ | ||
| * { | ||
| * uri: "ui://music/player.html", | ||
| * mimeType: RESOURCE_MIME_TYPE, | ||
| * text: musicPlayerHtml, | ||
| * _meta: { | ||
| * ui: { | ||
| * csp: { | ||
| * resourceDomains: ["https://cdn.example.com"], // For scripts/styles/images | ||
| * connectDomains: ["https://api.example.com"], // For fetch/WebSocket | ||
| * }, | ||
| * }, | ||
| * }, | ||
| * }, | ||
| * }, | ||
| * }, | ||
| * }, readCallback); | ||
| * ], | ||
| * }), | ||
| * ); | ||
| * ``` | ||
| * | ||
| * @see {@link registerAppTool} to register tools that reference this resource | ||
| * @see {@link registerAppTool `registerAppTool`} to register tools that reference this resource | ||
| */ | ||
| export declare function registerAppResource(server: Pick<McpServer, "registerResource">, name: string, uri: string, config: McpUiAppResourceConfig, readCallback: ReadResourceCallback): void; | ||
| /** | ||
| * Extension identifier for MCP Apps capability negotiation. | ||
| * | ||
| * Used as the key in `extensions` to advertise MCP Apps support. | ||
| */ | ||
| export declare const EXTENSION_ID = "io.modelcontextprotocol/ui"; | ||
| /** | ||
| * Get MCP Apps capability settings from client capabilities. | ||
| * | ||
| * This helper retrieves the capability object from the `extensions` field | ||
| * where MCP Apps advertises its support. | ||
| * | ||
| * Note: The `clientCapabilities` parameter extends the SDK's `ClientCapabilities` | ||
| * type with an `extensions` field (pending SEP-1724). Once `extensions` is added | ||
| * to the SDK, this can use `ClientCapabilities` directly. | ||
| * | ||
| * @param clientCapabilities - The client capabilities from the initialize response | ||
| * @returns The MCP Apps capability settings, or `undefined` if not supported | ||
| * | ||
| * @example Check for MCP Apps support in server initialization | ||
| * ```typescript | ||
| * import { getUiCapability, RESOURCE_MIME_TYPE, registerAppTool } from "@modelcontextprotocol/ext-apps/server"; | ||
| * | ||
| * server.oninitialized = ({ clientCapabilities }) => { | ||
| * const uiCap = getUiCapability(clientCapabilities); | ||
| * if (uiCap?.mimeTypes?.includes(RESOURCE_MIME_TYPE)) { | ||
| * registerAppTool(server, "weather", { | ||
| * description: "Get weather with interactive dashboard", | ||
| * _meta: { ui: { resourceUri: "ui://weather/dashboard" } }, | ||
| * }, weatherHandler); | ||
| * } else { | ||
| * // Register text-only fallback | ||
| * server.registerTool("weather", { | ||
| * description: "Get weather as text", | ||
| * }, textWeatherHandler); | ||
| * } | ||
| * }; | ||
| * ``` | ||
| */ | ||
| export declare function getUiCapability(clientCapabilities: (ClientCapabilities & { | ||
| extensions?: Record<string, unknown>; | ||
| }) | null | undefined): McpUiClientCapabilities | undefined; |
+51
-35
@@ -44,3 +44,3 @@ /** | ||
| * @description Request to open an external URL in the host's default browser. | ||
| * @see {@link app!App.openLink} for the method that sends this request | ||
| * @see {@link app!App.openLink `App.openLink`} for the method that sends this request | ||
| */ | ||
@@ -56,3 +56,3 @@ export interface McpUiOpenLinkRequest { | ||
| * @description Result from opening a URL. | ||
| * @see {@link McpUiOpenLinkRequest} | ||
| * @see {@link McpUiOpenLinkRequest `McpUiOpenLinkRequest`} | ||
| */ | ||
@@ -70,3 +70,3 @@ export interface McpUiOpenLinkResult { | ||
| * @description Request to send a message to the host's chat interface. | ||
| * @see {@link app!App.sendMessage} for the method that sends this request | ||
| * @see {@link app!App.sendMessage `App.sendMessage`} for the method that sends this request | ||
| */ | ||
@@ -84,3 +84,3 @@ export interface McpUiMessageRequest { | ||
| * @description Result from sending a message. | ||
| * @see {@link McpUiMessageRequest} | ||
| * @see {@link McpUiMessageRequest `McpUiMessageRequest`} | ||
| */ | ||
@@ -124,4 +124,4 @@ export interface McpUiMessageResult { | ||
| /** | ||
| * @description Notification of UI size changes (Guest UI -> Host). | ||
| * @see {@link app!App.sendSizeChanged} for the method to send this from Guest UI | ||
| * @description Notification of UI size changes (View -> Host). | ||
| * @see {@link app!App.sendSizeChanged `App.sendSizeChanged`} for the method to send this from View | ||
| */ | ||
@@ -138,3 +138,3 @@ export interface McpUiSizeChangedNotification { | ||
| /** | ||
| * @description Notification containing complete tool arguments (Host -> Guest UI). | ||
| * @description Notification containing complete tool arguments (Host -> View). | ||
| */ | ||
@@ -149,3 +149,3 @@ export interface McpUiToolInputNotification { | ||
| /** | ||
| * @description Notification containing partial/streaming tool arguments (Host -> Guest UI). | ||
| * @description Notification containing partial/streaming tool arguments (Host -> View). | ||
| */ | ||
@@ -160,3 +160,3 @@ export interface McpUiToolInputPartialNotification { | ||
| /** | ||
| * @description Notification containing tool execution result (Host -> Guest UI). | ||
| * @description Notification containing tool execution result (Host -> View). | ||
| */ | ||
@@ -169,3 +169,3 @@ export interface McpUiToolResultNotification { | ||
| /** | ||
| * @description Notification that tool execution was cancelled (Host -> Guest UI). | ||
| * @description Notification that tool execution was cancelled (Host -> View). | ||
| * Host MUST send this if tool execution was cancelled for any reason (user action, | ||
@@ -185,3 +185,3 @@ * sampling error, classifier intervention, etc.). | ||
| export interface McpUiHostCss { | ||
| /** @description CSS for font loading (`@font-face` rules or `@import` statements). Apps must apply using {@link applyHostFonts}. */ | ||
| /** @description CSS for font loading (`@font-face` rules or `@import` statements). Apps must apply using {@link applyHostFonts `applyHostFonts`}. */ | ||
| fonts?: string; | ||
@@ -199,3 +199,3 @@ } | ||
| /** | ||
| * @description Rich context about the host environment provided to Guest UIs. | ||
| * @description Rich context about the host environment provided to views. | ||
| */ | ||
@@ -219,3 +219,3 @@ export interface McpUiHostContext { | ||
| /** @description Display modes the host supports. */ | ||
| availableDisplayModes?: string[]; | ||
| availableDisplayModes?: McpUiDisplayMode[]; | ||
| /** | ||
@@ -266,4 +266,4 @@ * @description Container dimensions. Represents the dimensions of the iframe or other | ||
| /** | ||
| * @description Notification that host context has changed (Host -> Guest UI). | ||
| * @see {@link McpUiHostContext} for the full context structure | ||
| * @description Notification that host context has changed (Host -> View). | ||
| * @see {@link McpUiHostContext `McpUiHostContext`} for the full context structure | ||
| */ | ||
@@ -276,6 +276,6 @@ export interface McpUiHostContextChangedNotification { | ||
| /** | ||
| * @description Request to update the agent's context without requiring a follow-up action (Guest UI -> Host). | ||
| * @description Request to update the agent's context without requiring a follow-up action (View -> Host). | ||
| * | ||
| * Unlike `notifications/message` which is for debugging/logging, this request is intended | ||
| * to update the Host's model context. Each request overwrites the previous context sent by the Guest UI. | ||
| * to update the Host's model context. Each request overwrites the previous context sent by the View. | ||
| * Unlike messages, context updates do not trigger follow-ups. | ||
@@ -286,3 +286,3 @@ * | ||
| * | ||
| * @see {@link app.App.updateModelContext} for the method that sends this request | ||
| * @see {@link app.App.updateModelContext `App.updateModelContext`} for the method that sends this request | ||
| */ | ||
@@ -299,4 +299,4 @@ export interface McpUiUpdateModelContextRequest { | ||
| /** | ||
| * @description Request for graceful shutdown of the Guest UI (Host -> Guest UI). | ||
| * @see {@link app-bridge!AppBridge.teardownResource} for the host method that sends this | ||
| * @description Request for graceful shutdown of the View (Host -> View). | ||
| * @see {@link app-bridge!AppBridge.teardownResource `AppBridge.teardownResource`} for the host method that sends this | ||
| */ | ||
@@ -309,3 +309,3 @@ export interface McpUiResourceTeardownRequest { | ||
| * @description Result from graceful shutdown request. | ||
| * @see {@link McpUiResourceTeardownRequest} | ||
| * @see {@link McpUiResourceTeardownRequest `McpUiResourceTeardownRequest`} | ||
| */ | ||
@@ -334,3 +334,3 @@ export interface McpUiResourceTeardownResult { | ||
| * @description Capabilities supported by the host application. | ||
| * @see {@link McpUiInitializeResult} for the initialization result that includes these capabilities | ||
| * @see {@link McpUiInitializeResult `McpUiInitializeResult`} for the initialization result that includes these capabilities | ||
| */ | ||
@@ -363,8 +363,8 @@ export interface McpUiHostCapabilities { | ||
| updateModelContext?: McpUiSupportedContentBlockModalities; | ||
| /** @description Host supports receiving content messages (ui/message) from the Guest UI. */ | ||
| /** @description Host supports receiving content messages (ui/message) from the view. */ | ||
| message?: McpUiSupportedContentBlockModalities; | ||
| } | ||
| /** | ||
| * @description Capabilities provided by the Guest UI ({@link app!App}). | ||
| * @see {@link McpUiInitializeRequest} for the initialization request that includes these capabilities | ||
| * @description Capabilities provided by the View ({@link app!App `App`}). | ||
| * @see {@link McpUiInitializeRequest `McpUiInitializeRequest`} for the initialization request that includes these capabilities | ||
| */ | ||
@@ -379,6 +379,8 @@ export interface McpUiAppCapabilities { | ||
| }; | ||
| /** @description Display modes the app supports. */ | ||
| availableDisplayModes?: McpUiDisplayMode[]; | ||
| } | ||
| /** | ||
| * @description Initialization request sent from Guest UI to Host. | ||
| * @see {@link app!App.connect} for the method that sends this request | ||
| * @description Initialization request sent from View to Host. | ||
| * @see {@link app!App.connect `App.connect`} for the method that sends this request | ||
| */ | ||
@@ -397,4 +399,4 @@ export interface McpUiInitializeRequest { | ||
| /** | ||
| * @description Initialization result returned from Host to Guest UI. | ||
| * @see {@link McpUiInitializeRequest} | ||
| * @description Initialization result returned from Host to View. | ||
| * @see {@link McpUiInitializeRequest `McpUiInitializeRequest`} | ||
| */ | ||
@@ -417,4 +419,4 @@ export interface McpUiInitializeResult { | ||
| /** | ||
| * @description Notification that Guest UI has completed initialization (Guest UI -> Host). | ||
| * @see {@link app!App.connect} for the method that sends this notification | ||
| * @description Notification that View has completed initialization (View -> Host). | ||
| * @see {@link app!App.connect `App.connect`} for the method that sends this notification | ||
| */ | ||
@@ -461,3 +463,3 @@ export interface McpUiInitializedNotification { | ||
| permissions?: McpUiResourcePermissions; | ||
| /** @description Dedicated origin for widget sandbox. */ | ||
| /** @description Dedicated origin for view sandbox. */ | ||
| domain?: string; | ||
@@ -471,3 +473,3 @@ /** @description Visual boundary preference - true if UI prefers a visible border. */ | ||
| * which may differ from the requested mode if not supported. | ||
| * @see {@link app!App.requestDisplayMode} for the method that sends this request | ||
| * @see {@link app!App.requestDisplayMode `App.requestDisplayMode`} for the method that sends this request | ||
| */ | ||
@@ -483,3 +485,3 @@ export interface McpUiRequestDisplayModeRequest { | ||
| * @description Result from requesting a display mode change. | ||
| * @see {@link McpUiRequestDisplayModeRequest} | ||
| * @see {@link McpUiRequestDisplayModeRequest `McpUiRequestDisplayModeRequest`} | ||
| */ | ||
@@ -507,3 +509,3 @@ export interface McpUiRequestDisplayModeResult { | ||
| * | ||
| * @example "ui://weather/widget.html" | ||
| * @example "ui://weather/view.html" | ||
| */ | ||
@@ -548,1 +550,15 @@ resourceUri?: string; | ||
| export declare const REQUEST_DISPLAY_MODE_METHOD: McpUiRequestDisplayModeRequest["method"]; | ||
| /** | ||
| * @description MCP Apps capability settings advertised by clients to servers. | ||
| * | ||
| * Clients advertise these capabilities via the `extensions` field in their | ||
| * capabilities during MCP initialization. Servers can check for MCP Apps | ||
| * support using {@link server-helpers!getUiCapability}. | ||
| */ | ||
| export interface McpUiClientCapabilities { | ||
| /** | ||
| * @description Array of supported MIME types for UI resources. | ||
| * Must include `"text/html;profile=mcp-app"` for MCP Apps support. | ||
| */ | ||
| mimeTypes?: string[]; | ||
| } |
+71
-28
@@ -12,11 +12,9 @@ import { McpUiStyles, McpUiTheme } from "./types"; | ||
| * @example Check current theme | ||
| * ```typescript | ||
| * import { getDocumentTheme } from '@modelcontextprotocol/ext-apps'; | ||
| * | ||
| * ```ts source="./styles.examples.ts#getDocumentTheme_checkCurrent" | ||
| * const theme = getDocumentTheme(); | ||
| * console.log(`Current theme: ${theme}`); | ||
| * document.body.classList.toggle("dark", theme === "dark"); | ||
| * ``` | ||
| * | ||
| * @see {@link applyDocumentTheme} to set the theme | ||
| * @see {@link McpUiTheme} for the theme type | ||
| * @see {@link applyDocumentTheme `applyDocumentTheme`} to set the theme | ||
| * @see {@link McpUiTheme `McpUiTheme`} for the theme type | ||
| */ | ||
@@ -35,5 +33,4 @@ export declare function getDocumentTheme(): McpUiTheme; | ||
| * @example Apply theme from host context | ||
| * ```typescript | ||
| * import { applyDocumentTheme } from '@modelcontextprotocol/ext-apps'; | ||
| * | ||
| * ```ts source="./styles.examples.ts#applyDocumentTheme_fromHostContext" | ||
| * // Apply when host context changes | ||
| * app.onhostcontextchanged = (params) => { | ||
@@ -44,2 +41,10 @@ * if (params.theme) { | ||
| * }; | ||
| * | ||
| * // Apply initial theme after connecting | ||
| * app.connect().then(() => { | ||
| * const ctx = app.getHostContext(); | ||
| * if (ctx?.theme) { | ||
| * applyDocumentTheme(ctx.theme); | ||
| * } | ||
| * }); | ||
| * ``` | ||
@@ -57,4 +62,4 @@ * | ||
| * | ||
| * @see {@link getDocumentTheme} to read the current theme | ||
| * @see {@link McpUiTheme} for the theme type | ||
| * @see {@link getDocumentTheme `getDocumentTheme`} to read the current theme | ||
| * @see {@link McpUiTheme `McpUiTheme`} for the theme type | ||
| */ | ||
@@ -65,3 +70,3 @@ export declare function applyDocumentTheme(theme: McpUiTheme): void; | ||
| * | ||
| * This function takes the `variables` object from {@link McpUiHostContext.styles} and sets | ||
| * This function takes the `variables` object from {@link McpUiHostContext.styles `McpUiHostContext.styles`} and sets | ||
| * each CSS variable on the specified root element (defaults to `document.documentElement`). | ||
@@ -75,5 +80,7 @@ * This allows apps to use the host's theming values via CSS variables like | ||
| * @example Apply style variables from host context | ||
| * ```typescript | ||
| * import { applyHostStyleVariables } from '@modelcontextprotocol/ext-apps'; | ||
| * ```ts source="./styles.examples.ts#applyHostStyleVariables_fromHostContext" | ||
| * // Use CSS variables in your styles | ||
| * document.body.style.background = "var(--color-background-primary)"; | ||
| * | ||
| * // Apply when host context changes | ||
| * app.onhostcontextchanged = (params) => { | ||
@@ -84,12 +91,37 @@ * if (params.styles?.variables) { | ||
| * }; | ||
| * | ||
| * // Apply initial styles after connecting | ||
| * app.connect().then(() => { | ||
| * const ctx = app.getHostContext(); | ||
| * if (ctx?.styles?.variables) { | ||
| * applyHostStyleVariables(ctx.styles.variables); | ||
| * } | ||
| * }); | ||
| * ``` | ||
| * | ||
| * @example Apply to a specific element | ||
| * ```typescript | ||
| * const container = document.getElementById('app-root'); | ||
| * applyHostStyleVariables(hostContext.styles?.variables, container); | ||
| * ```ts source="./styles.examples.ts#applyHostStyleVariables_toElement" | ||
| * app.onhostcontextchanged = (params) => { | ||
| * const container = document.getElementById("app-root"); | ||
| * if (container && params.styles?.variables) { | ||
| * applyHostStyleVariables(params.styles.variables, container); | ||
| * } | ||
| * }; | ||
| * ``` | ||
| * | ||
| * @see {@link McpUiStyles} for the available CSS variables | ||
| * @see {@link McpUiHostContext} for the full host context structure | ||
| * @example Use host style variables in CSS | ||
| * ```css | ||
| * body { | ||
| * background-color: var(--color-background-primary); | ||
| * color: var(--color-text-primary); | ||
| * } | ||
| * | ||
| * .card { | ||
| * background-color: var(--color-background-secondary); | ||
| * border: 1px solid var(--color-border-primary); | ||
| * } | ||
| * ``` | ||
| * | ||
| * @see {@link McpUiStyles `McpUiStyles`} for the available CSS variables | ||
| * @see {@link McpUiHostContext `McpUiHostContext`} for the full host context structure | ||
| */ | ||
@@ -111,5 +143,4 @@ export declare function applyHostStyleVariables(styles: McpUiStyles, root?: HTMLElement): void; | ||
| * @example Apply fonts from host context | ||
| * ```typescript | ||
| * import { applyHostFonts } from '@modelcontextprotocol/ext-apps'; | ||
| * | ||
| * ```ts source="./styles.examples.ts#applyHostFonts_fromHostContext" | ||
| * // Apply when host context changes | ||
| * app.onhostcontextchanged = (params) => { | ||
@@ -120,7 +151,16 @@ * if (params.styles?.css?.fonts) { | ||
| * }; | ||
| * | ||
| * // Apply initial fonts after connecting | ||
| * app.connect().then(() => { | ||
| * const ctx = app.getHostContext(); | ||
| * if (ctx?.styles?.css?.fonts) { | ||
| * applyHostFonts(ctx.styles.css.fonts); | ||
| * } | ||
| * }); | ||
| * ``` | ||
| * | ||
| * @example Host providing self-hosted fonts | ||
| * ```typescript | ||
| * hostContext.styles.css.fonts = ` | ||
| * ```ts source="./styles.examples.ts#applyHostFonts_selfHosted" | ||
| * // Example of what a host might provide: | ||
| * const fontCss = ` | ||
| * @font-face { | ||
@@ -132,9 +172,12 @@ * font-family: "Anthropic Sans"; | ||
| * `; | ||
| * applyHostFonts(fontCss); | ||
| * ``` | ||
| * | ||
| * @example Host providing Google Fonts | ||
| * ```typescript | ||
| * hostContext.styles.css.fonts = ` | ||
| * ```ts source="./styles.examples.ts#applyHostFonts_googleFonts" | ||
| * // Example of what a host might provide: | ||
| * const fontCss = ` | ||
| * @import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap'); | ||
| * `; | ||
| * applyHostFonts(fontCss); | ||
| * ``` | ||
@@ -145,8 +188,8 @@ * | ||
| * body { | ||
| * font-family: "Anthropic Sans", sans-serif; | ||
| * font-family: var(--font-sans, system-ui, sans-serif); | ||
| * } | ||
| * ``` | ||
| * | ||
| * @see {@link McpUiHostContext} for the full host context structure | ||
| * @see {@link McpUiHostContext `McpUiHostContext`} for the full host context structure | ||
| */ | ||
| export declare function applyHostFonts(fontCss: string): void; |
@@ -11,3 +11,3 @@ /** | ||
| */ | ||
| export { LATEST_PROTOCOL_VERSION, OPEN_LINK_METHOD, MESSAGE_METHOD, SANDBOX_PROXY_READY_METHOD, SANDBOX_RESOURCE_READY_METHOD, SIZE_CHANGED_METHOD, TOOL_INPUT_METHOD, TOOL_INPUT_PARTIAL_METHOD, TOOL_RESULT_METHOD, TOOL_CANCELLED_METHOD, HOST_CONTEXT_CHANGED_METHOD, RESOURCE_TEARDOWN_METHOD, INITIALIZE_METHOD, INITIALIZED_METHOD, REQUEST_DISPLAY_MODE_METHOD, type McpUiTheme, type McpUiDisplayMode, type McpUiStyleVariableKey, type McpUiStyles, type McpUiHostCss, type McpUiHostStyles, type McpUiOpenLinkRequest, type McpUiOpenLinkResult, type McpUiMessageRequest, type McpUiMessageResult, type McpUiUpdateModelContextRequest, type McpUiSupportedContentBlockModalities, type McpUiSandboxProxyReadyNotification, type McpUiSandboxResourceReadyNotification, type McpUiSizeChangedNotification, type McpUiToolInputNotification, type McpUiToolInputPartialNotification, type McpUiToolResultNotification, type McpUiToolCancelledNotification, type McpUiHostContext, type McpUiHostContextChangedNotification, type McpUiResourceTeardownRequest, type McpUiResourceTeardownResult, type McpUiHostCapabilities, type McpUiAppCapabilities, type McpUiInitializeRequest, type McpUiInitializeResult, type McpUiInitializedNotification, type McpUiResourceCsp, type McpUiResourcePermissions, type McpUiResourceMeta, type McpUiRequestDisplayModeRequest, type McpUiRequestDisplayModeResult, type McpUiToolVisibility, type McpUiToolMeta, } from "./spec.types.js"; | ||
| export { LATEST_PROTOCOL_VERSION, OPEN_LINK_METHOD, MESSAGE_METHOD, SANDBOX_PROXY_READY_METHOD, SANDBOX_RESOURCE_READY_METHOD, SIZE_CHANGED_METHOD, TOOL_INPUT_METHOD, TOOL_INPUT_PARTIAL_METHOD, TOOL_RESULT_METHOD, TOOL_CANCELLED_METHOD, HOST_CONTEXT_CHANGED_METHOD, RESOURCE_TEARDOWN_METHOD, INITIALIZE_METHOD, INITIALIZED_METHOD, REQUEST_DISPLAY_MODE_METHOD, type McpUiTheme, type McpUiDisplayMode, type McpUiStyleVariableKey, type McpUiStyles, type McpUiHostCss, type McpUiHostStyles, type McpUiOpenLinkRequest, type McpUiOpenLinkResult, type McpUiMessageRequest, type McpUiMessageResult, type McpUiUpdateModelContextRequest, type McpUiSupportedContentBlockModalities, type McpUiSandboxProxyReadyNotification, type McpUiSandboxResourceReadyNotification, type McpUiSizeChangedNotification, type McpUiToolInputNotification, type McpUiToolInputPartialNotification, type McpUiToolResultNotification, type McpUiToolCancelledNotification, type McpUiHostContext, type McpUiHostContextChangedNotification, type McpUiResourceTeardownRequest, type McpUiResourceTeardownResult, type McpUiHostCapabilities, type McpUiAppCapabilities, type McpUiInitializeRequest, type McpUiInitializeResult, type McpUiInitializedNotification, type McpUiResourceCsp, type McpUiResourcePermissions, type McpUiResourceMeta, type McpUiRequestDisplayModeRequest, type McpUiRequestDisplayModeResult, type McpUiToolVisibility, type McpUiToolMeta, type McpUiClientCapabilities, } from "./spec.types.js"; | ||
| import type { McpUiInitializeRequest, McpUiOpenLinkRequest, McpUiMessageRequest, McpUiUpdateModelContextRequest, McpUiResourceTeardownRequest, McpUiRequestDisplayModeRequest, McpUiHostContextChangedNotification, McpUiToolInputNotification, McpUiToolInputPartialNotification, McpUiToolResultNotification, McpUiToolCancelledNotification, McpUiSandboxResourceReadyNotification, McpUiInitializedNotification, McpUiSizeChangedNotification, McpUiSandboxProxyReadyNotification, McpUiInitializeResult, McpUiOpenLinkResult, McpUiMessageResult, McpUiResourceTeardownResult, McpUiRequestDisplayModeResult } from "./spec.types.js"; | ||
@@ -14,0 +14,0 @@ export { McpUiThemeSchema, McpUiDisplayModeSchema, McpUiHostCssSchema, McpUiHostStylesSchema, McpUiOpenLinkRequestSchema, McpUiOpenLinkResultSchema, McpUiMessageRequestSchema, McpUiMessageResultSchema, McpUiUpdateModelContextRequestSchema, McpUiSupportedContentBlockModalitiesSchema, McpUiSandboxProxyReadyNotificationSchema, McpUiSandboxResourceReadyNotificationSchema, McpUiSizeChangedNotificationSchema, McpUiToolInputNotificationSchema, McpUiToolInputPartialNotificationSchema, McpUiToolResultNotificationSchema, McpUiToolCancelledNotificationSchema, McpUiHostContextSchema, McpUiHostContextChangedNotificationSchema, McpUiResourceTeardownRequestSchema, McpUiResourceTeardownResultSchema, McpUiHostCapabilitiesSchema, McpUiAppCapabilitiesSchema, McpUiInitializeRequestSchema, McpUiInitializeResultSchema, McpUiInitializedNotificationSchema, McpUiResourceCspSchema, McpUiResourcePermissionsSchema, McpUiResourceMetaSchema, McpUiRequestDisplayModeRequestSchema, McpUiRequestDisplayModeResultSchema, McpUiToolVisibilitySchema, McpUiToolMetaSchema, } from "./generated/schema.js"; |
+25
-8
@@ -8,3 +8,3 @@ { | ||
| "homepage": "https://github.com/modelcontextprotocol/ext-apps", | ||
| "version": "0.4.1", | ||
| "version": "0.4.2", | ||
| "license": "MIT", | ||
@@ -51,3 +51,4 @@ "description": "MCP Apps SDK — Enable MCP servers to display interactive user interfaces in conversational clients.", | ||
| "generate:schemas": "tsx scripts/generate-schemas.ts && prettier --write \"src/generated/**/*\"", | ||
| "build": "npm run generate:schemas && node scripts/run-bun.mjs build.bun.ts", | ||
| "sync:snippets": "bun scripts/sync-snippets.ts", | ||
| "build": "npm run generate:schemas && npm run sync:snippets && node scripts/run-bun.mjs build.bun.ts", | ||
| "prepack": "npm run build", | ||
@@ -59,4 +60,4 @@ "build:all": "npm run examples:build", | ||
| "test:e2e:ui": "playwright test --ui", | ||
| "test:e2e:docker": "docker run --rm -v $(pwd):/work -w /work -it mcr.microsoft.com/playwright:v1.57.0-noble sh -c 'apt-get update -qq && apt-get install -qq -y python3-venv curl > /dev/null && curl -LsSf https://astral.sh/uv/install.sh | sh && export PATH=\"$HOME/.local/bin:$PATH\" && npm i -g bun && npm ci && npx playwright test'", | ||
| "test:e2e:docker:update": "npm run build:all && docker run --rm -v $(pwd):/work -w /work -it mcr.microsoft.com/playwright:v1.57.0-noble sh -c 'apt-get update -qq && apt-get install -qq -y python3-venv curl > /dev/null && curl -LsSf https://astral.sh/uv/install.sh | sh && export PATH=\"$HOME/.local/bin:$PATH\" && npm i -g bun && npm ci && npx playwright test --update-snapshots'", | ||
| "test:e2e:docker": "docker run --rm -e EXAMPLE -v $(pwd):/work -w /work -it mcr.microsoft.com/playwright:v1.57.0-noble sh -c 'apt-get update -qq && apt-get install -qq -y python3-venv curl > /dev/null && curl -LsSf https://astral.sh/uv/install.sh | sh && export PATH=\"$HOME/.local/bin:$PATH\" && npm i -g bun && npm ci && npx playwright test'", | ||
| "test:e2e:docker:update": "npm run build:all && docker run --rm -e EXAMPLE -v $(pwd):/work -w /work -it mcr.microsoft.com/playwright:v1.57.0-noble sh -c 'apt-get update -qq && apt-get install -qq -y python3-venv curl > /dev/null && curl -LsSf https://astral.sh/uv/install.sh | sh && export PATH=\"$HOME/.local/bin:$PATH\" && npm i -g bun && npm ci && npx playwright test --update-snapshots'", | ||
| "preexamples:build": "npm run build", | ||
@@ -70,17 +71,23 @@ "examples:build": "bun examples/run-all.ts build", | ||
| "docs:watch": "typedoc --watch", | ||
| "generate:screenshots": "npm run build:all && docker run --rm -v $(pwd):/work -w /work mcr.microsoft.com/playwright:v1.57.0-noble sh -c 'apt-get update -qq && apt-get install -qq -y python3-venv curl > /dev/null && curl -LsSf https://astral.sh/uv/install.sh | sh && export PATH=\"$HOME/.local/bin:$PATH\" && npm i -g bun && npm ci && npx playwright test tests/e2e/generate-grid-screenshots.spec.ts'", | ||
| "generate:screenshots": "npm run build:all && docker run --rm -e EXAMPLE -v $(pwd):/work -w /work mcr.microsoft.com/playwright:v1.57.0-noble sh -c 'apt-get update -qq && apt-get install -qq -y python3-venv curl > /dev/null && curl -LsSf https://astral.sh/uv/install.sh | sh && export PATH=\"$HOME/.local/bin:$PATH\" && npm i -g bun && npm ci && npx playwright test tests/e2e/generate-grid-screenshots.spec.ts'", | ||
| "prettier": "prettier -u \"**/*.{js,jsx,ts,tsx,mjs,json,md,yml,yaml}\" --check", | ||
| "prettier:fix": "prettier -u \"**/*.{js,jsx,ts,tsx,mjs,json,md,yml,yaml}\" --write", | ||
| "check:versions": "node scripts/check-versions.mjs" | ||
| "check:versions": "node scripts/check-versions.mjs", | ||
| "update-lock:docker": "rm -rf node_modules package-lock.json && docker run --rm --platform linux/amd64 -v $(pwd):/work -w /work node:latest npm i --registry=https://registry.npmjs.org/ && rm -rf node_modules && npm i" | ||
| }, | ||
| "author": "Olivier Chafik", | ||
| "devDependencies": { | ||
| "@modelcontextprotocol/sdk": "^1.24.0", | ||
| "@playwright/test": "^1.52.0", | ||
| "@boneskull/typedoc-plugin-mermaid": "^0.2.0", | ||
| "@modelcontextprotocol/sdk": "1.25.2", | ||
| "@playwright/test": "1.57.0", | ||
| "@types/bun": "^1.3.2", | ||
| "@types/react": "^19.2.2", | ||
| "@types/react-dom": "^19.2.2", | ||
| "@types/node": "20.19.27", | ||
| "caniuse-lite": "1.0.30001763", | ||
| "cheerio": "1.1.2", | ||
| "concurrently": "^9.2.1", | ||
| "cors": "^2.8.5", | ||
| "cross-env": "^10.1.0", | ||
| "electron-to-chromium": "1.5.267", | ||
| "esbuild": "^0.25.12", | ||
@@ -90,2 +97,4 @@ "express": "^5.1.0", | ||
| "nodemon": "^3.1.0", | ||
| "playwright": "1.57.0", | ||
| "playwright-core": "1.57.0", | ||
| "prettier": "^3.6.2", | ||
@@ -98,2 +107,3 @@ "react": "^19.2.0", | ||
| "typedoc": "^0.28.14", | ||
| "typedoc-github-theme": "^0.3.1", | ||
| "typescript": "^5.9.3", | ||
@@ -134,3 +144,10 @@ "zod": "^4.1.13" | ||
| "@rollup/rollup-win32-x64-msvc": "^4.53.3" | ||
| }, | ||
| "overrides": { | ||
| "seroval": "1.4.1", | ||
| "seroval-plugins": "1.4.2", | ||
| "solid-js": "1.9.10", | ||
| "@hono/node-server": "1.19.7", | ||
| "@types/node": "20.19.27" | ||
| } | ||
| } |
+266
-28
@@ -9,18 +9,22 @@ # @modelcontextprotocol/ext-apps | ||
| ## Why MCP Apps? | ||
| MCP tools return text and structured data. That works for many cases, but not when you need an interactive UI, like a chart, form, or video player. | ||
| MCP Apps provide a standardized way to deliver interactive UIs from MCP servers. Your UI renders inline in the conversation, in context, in any compliant host. | ||
| ## How It Works | ||
| MCP Apps extend the Model Context Protocol to let servers deliver **interactive UIs** to MCP hosts. Here's how it works: | ||
| MCP Apps extend the Model Context Protocol by letting tools declare UI resources: | ||
| 1. **Tool call** — The LLM calls a tool on your server | ||
| 2. **UI Resource** — The tool's definition links to a predeclared `ui://` resource containing its HTML interface | ||
| 1. **Tool definition** — Your tool declares a `ui://` resource containing its HTML interface | ||
| 2. **Tool call** — The LLM calls the tool on your server | ||
| 3. **Host renders** — The host fetches the resource and displays it in a sandboxed iframe | ||
| 4. **Bidirectional communication** — The host passes tool data to the UI via notifications, and the UI can call other tools through the host | ||
| This enables dashboards, forms, visualizations, and other rich experiences inside chat interfaces. | ||
| ## Using the SDK | ||
| ## Overview | ||
| This SDK serves two audiences: | ||
| ### App Developers | ||
| ### For App Developers | ||
@@ -32,3 +36,3 @@ Build interactive UIs that run inside MCP-enabled chat clients. | ||
| ### Host Developers | ||
| ### For Host Developers | ||
@@ -49,27 +53,30 @@ Embed and communicate with MCP Apps in your chat application. | ||
| Or edit your `package.json` manually: | ||
| ### Install Agent Skills | ||
| ```json | ||
| { | ||
| "dependencies": { | ||
| "@modelcontextprotocol/ext-apps": "^0.0.1" | ||
| } | ||
| } | ||
| This repository provides two [Agent Skills](https://agentskills.io/) for building MCP Apps. You can install the skills as a Claude Code plugin: | ||
| ``` | ||
| /plugin marketplace add modelcontextprotocol/ext-apps | ||
| /plugin install mcp-apps@modelcontextprotocol-ext-apps | ||
| ``` | ||
| For more information, including instructions for installing the skills in your favorite AI coding agent, see the [agent skills guide](./docs/agent-skills.md). | ||
| ## Examples | ||
| The [`examples/`](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples) directory contains demo apps showcasing real-world use cases. | ||
| <!-- prettier-ignore-start --> | ||
| | | | | | ||
| |:---:|:---:|:---:| | ||
| | [](examples/map-server) | [](examples/threejs-server) | [](examples/shadertoy-server) | | ||
| | [**Map**](examples/map-server) | [**Three.js**](examples/threejs-server) | [**ShaderToy**](examples/shadertoy-server) | | ||
| | [](examples/sheet-music-server) | [](examples/wiki-explorer-server) | [](examples/cohort-heatmap-server) | | ||
| | [**Sheet Music**](examples/sheet-music-server) | [**Wiki Explorer**](examples/wiki-explorer-server) | [**Cohort Heatmap**](examples/cohort-heatmap-server) | | ||
| | [](examples/scenario-modeler-server) | [](examples/budget-allocator-server) | [](examples/customer-segmentation-server) | | ||
| | [**Scenario Modeler**](examples/scenario-modeler-server) | [**Budget Allocator**](examples/budget-allocator-server) | [**Customer Segmentation**](examples/customer-segmentation-server) | | ||
| | [](examples/system-monitor-server) | [](examples/transcript-server) | [](examples/video-resource-server) | | ||
| | [**System Monitor**](examples/system-monitor-server) | [**Transcript**](examples/transcript-server) | [**Video Resource**](examples/video-resource-server) | | ||
| | [](examples/pdf-server) | [](examples/qr-server) | | | ||
| | [**PDF Server**](examples/pdf-server) | [**QR Code (Python)**](examples/qr-server) | | | ||
| | [](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/map-server) | [](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/threejs-server) | [](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/shadertoy-server) | | ||
| | [**Map**](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/map-server) | [**Three.js**](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/threejs-server) | [**ShaderToy**](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/shadertoy-server) | | ||
| | [](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/sheet-music-server) | [](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/wiki-explorer-server) | [](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/cohort-heatmap-server) | | ||
| | [**Sheet Music**](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/sheet-music-server) | [**Wiki Explorer**](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/wiki-explorer-server) | [**Cohort Heatmap**](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/cohort-heatmap-server) | | ||
| | [](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/scenario-modeler-server) | [](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/budget-allocator-server) | [](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/customer-segmentation-server) | | ||
| | [**Scenario Modeler**](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/scenario-modeler-server) | [**Budget Allocator**](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/budget-allocator-server) | [**Customer Segmentation**](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/customer-segmentation-server) | | ||
| | [](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/system-monitor-server) | [](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/transcript-server) | [](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/video-resource-server) | | ||
| | [**System Monitor**](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/system-monitor-server) | [**Transcript**](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/transcript-server) | [**Video Resource**](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/video-resource-server) | | ||
| | [](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/pdf-server) | [](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/qr-server) | [](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/say-server) | | ||
| | [**PDF Server**](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/pdf-server) | [**QR Code (Python)**](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/qr-server) | [**Say Demo**](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/say-server) | | ||
@@ -80,10 +87,14 @@ ### Starter Templates | ||
| |:---:|:---| | ||
| | [](examples/basic-server-react) | The same app built with different frameworks — pick your favorite!<br><br>[React](examples/basic-server-react) · [Vue](examples/basic-server-vue) · [Svelte](examples/basic-server-svelte) · [Preact](examples/basic-server-preact) · [Solid](examples/basic-server-solid) · [Vanilla JS](examples/basic-server-vanillajs) | | ||
| | [](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/basic-server-react) | The same app built with different frameworks — pick your favorite!<br><br>[React](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/basic-server-react) · [Vue](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/basic-server-vue) · [Svelte](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/basic-server-svelte) · [Preact](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/basic-server-preact) · [Solid](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/basic-server-solid) · [Vanilla JS](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/basic-server-vanillajs) | | ||
| <!-- prettier-ignore-end --> | ||
| The [`examples/`](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples) directory contains additional demo apps showcasing real-world use cases. | ||
| ### Running the Examples | ||
| To run all examples: | ||
| #### With basic-host | ||
| To run all examples locally using [basic-host](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/basic-host) (the reference host implementation included in this repo): | ||
| ```bash | ||
| git clone https://github.com/modelcontextprotocol/ext-apps.git | ||
| cd ext-apps | ||
| npm install | ||
@@ -95,2 +106,229 @@ npm start | ||
| #### With MCP Clients | ||
| To use these examples with MCP clients that support the stdio transport (such as Claude Desktop or VS Code), add this MCP server configuration to your client's settings: | ||
| <details> | ||
| <summary>MCP client configuration for all examples (using stdio)</summary> | ||
| ```json | ||
| { | ||
| "mcpServers": { | ||
| "basic-react": { | ||
| "command": "npx", | ||
| "args": [ | ||
| "-y", | ||
| "--silent", | ||
| "--registry=https://registry.npmjs.org/", | ||
| "@modelcontextprotocol/server-basic-react", | ||
| "--stdio" | ||
| ] | ||
| }, | ||
| "basic-vanillajs": { | ||
| "command": "npx", | ||
| "args": [ | ||
| "-y", | ||
| "--silent", | ||
| "--registry=https://registry.npmjs.org/", | ||
| "@modelcontextprotocol/server-basic-vanillajs", | ||
| "--stdio" | ||
| ] | ||
| }, | ||
| "basic-vue": { | ||
| "command": "npx", | ||
| "args": [ | ||
| "-y", | ||
| "--silent", | ||
| "--registry=https://registry.npmjs.org/", | ||
| "@modelcontextprotocol/server-basic-vue", | ||
| "--stdio" | ||
| ] | ||
| }, | ||
| "basic-svelte": { | ||
| "command": "npx", | ||
| "args": [ | ||
| "-y", | ||
| "--silent", | ||
| "--registry=https://registry.npmjs.org/", | ||
| "@modelcontextprotocol/server-basic-svelte", | ||
| "--stdio" | ||
| ] | ||
| }, | ||
| "basic-preact": { | ||
| "command": "npx", | ||
| "args": [ | ||
| "-y", | ||
| "--silent", | ||
| "--registry=https://registry.npmjs.org/", | ||
| "@modelcontextprotocol/server-basic-preact", | ||
| "--stdio" | ||
| ] | ||
| }, | ||
| "basic-solid": { | ||
| "command": "npx", | ||
| "args": [ | ||
| "-y", | ||
| "--silent", | ||
| "--registry=https://registry.npmjs.org/", | ||
| "@modelcontextprotocol/server-basic-solid", | ||
| "--stdio" | ||
| ] | ||
| }, | ||
| "budget-allocator": { | ||
| "command": "npx", | ||
| "args": [ | ||
| "-y", | ||
| "--silent", | ||
| "--registry=https://registry.npmjs.org/", | ||
| "@modelcontextprotocol/server-budget-allocator", | ||
| "--stdio" | ||
| ] | ||
| }, | ||
| "cohort-heatmap": { | ||
| "command": "npx", | ||
| "args": [ | ||
| "-y", | ||
| "--silent", | ||
| "--registry=https://registry.npmjs.org/", | ||
| "@modelcontextprotocol/server-cohort-heatmap", | ||
| "--stdio" | ||
| ] | ||
| }, | ||
| "customer-segmentation": { | ||
| "command": "npx", | ||
| "args": [ | ||
| "-y", | ||
| "--silent", | ||
| "--registry=https://registry.npmjs.org/", | ||
| "@modelcontextprotocol/server-customer-segmentation", | ||
| "--stdio" | ||
| ] | ||
| }, | ||
| "map": { | ||
| "command": "npx", | ||
| "args": [ | ||
| "-y", | ||
| "--silent", | ||
| "--registry=https://registry.npmjs.org/", | ||
| "@modelcontextprotocol/server-map", | ||
| "--stdio" | ||
| ] | ||
| }, | ||
| "pdf": { | ||
| "command": "npx", | ||
| "args": [ | ||
| "-y", | ||
| "--silent", | ||
| "--registry=https://registry.npmjs.org/", | ||
| "@modelcontextprotocol/server-pdf", | ||
| "--stdio" | ||
| ] | ||
| }, | ||
| "scenario-modeler": { | ||
| "command": "npx", | ||
| "args": [ | ||
| "-y", | ||
| "--silent", | ||
| "--registry=https://registry.npmjs.org/", | ||
| "@modelcontextprotocol/server-scenario-modeler", | ||
| "--stdio" | ||
| ] | ||
| }, | ||
| "shadertoy": { | ||
| "command": "npx", | ||
| "args": [ | ||
| "-y", | ||
| "--silent", | ||
| "--registry=https://registry.npmjs.org/", | ||
| "@modelcontextprotocol/server-shadertoy", | ||
| "--stdio" | ||
| ] | ||
| }, | ||
| "sheet-music": { | ||
| "command": "npx", | ||
| "args": [ | ||
| "-y", | ||
| "--silent", | ||
| "--registry=https://registry.npmjs.org/", | ||
| "@modelcontextprotocol/server-sheet-music", | ||
| "--stdio" | ||
| ] | ||
| }, | ||
| "system-monitor": { | ||
| "command": "npx", | ||
| "args": [ | ||
| "-y", | ||
| "--silent", | ||
| "--registry=https://registry.npmjs.org/", | ||
| "@modelcontextprotocol/server-system-monitor", | ||
| "--stdio" | ||
| ] | ||
| }, | ||
| "threejs": { | ||
| "command": "npx", | ||
| "args": [ | ||
| "-y", | ||
| "--silent", | ||
| "--registry=https://registry.npmjs.org/", | ||
| "@modelcontextprotocol/server-threejs", | ||
| "--stdio" | ||
| ] | ||
| }, | ||
| "transcript": { | ||
| "command": "npx", | ||
| "args": [ | ||
| "-y", | ||
| "--silent", | ||
| "--registry=https://registry.npmjs.org/", | ||
| "@modelcontextprotocol/server-transcript", | ||
| "--stdio" | ||
| ] | ||
| }, | ||
| "video-resource": { | ||
| "command": "npx", | ||
| "args": [ | ||
| "-y", | ||
| "--silent", | ||
| "--registry=https://registry.npmjs.org/", | ||
| "@modelcontextprotocol/server-video-resource", | ||
| "--stdio" | ||
| ] | ||
| }, | ||
| "wiki-explorer": { | ||
| "command": "npx", | ||
| "args": [ | ||
| "-y", | ||
| "--silent", | ||
| "--registry=https://registry.npmjs.org/", | ||
| "@modelcontextprotocol/server-wiki-explorer", | ||
| "--stdio" | ||
| ] | ||
| }, | ||
| "qr": { | ||
| "command": "uv", | ||
| "args": [ | ||
| "run", | ||
| "/path/to/ext-apps/examples/qr-server/server.py", | ||
| "--stdio" | ||
| ] | ||
| }, | ||
| "say": { | ||
| "command": "uv", | ||
| "args": [ | ||
| "run", | ||
| "--default-index", | ||
| "https://pypi.org/simple", | ||
| "https://raw.githubusercontent.com/modelcontextprotocol/ext-apps/refs/heads/main/examples/say-server/server.py", | ||
| "--stdio" | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
| </details> | ||
| > [!NOTE] | ||
| > The `qr` server requires cloning the repository first. See [qr-server README](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/qr-server) for details. | ||
| ## Resources | ||
@@ -97,0 +335,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 2 instances in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 2 instances in 1 package
2029533
1.3%36
44%11450
2.2%335
245.36%64
-3.03%29
38.1%