annator / loan-advisor-chatgpt-app /node_modules /@modelcontextprotocol /ext-apps /dist /src /app.d.ts
| import { type RequestOptions, ProtocolOptions } from "@modelcontextprotocol/sdk/shared/protocol.js"; | |
| import { CallToolRequest, CallToolResult, CreateMessageRequest, CreateMessageResult, CreateMessageResultWithTools, Implementation, ListResourcesRequest, ListResourcesResult, ListToolsRequest, ListToolsResult, LoggingMessageNotification, ReadResourceRequest, ReadResourceResult, ToolAnnotations, ToolListChangedNotification } from "@modelcontextprotocol/sdk/types.js"; | |
| import { AppNotification, AppRequest, AppResult } from "./types"; | |
| import { ProtocolWithEvents } from "./events"; | |
| export { ProtocolWithEvents }; | |
| import { McpUiAppCapabilities, McpUiUpdateModelContextRequest, McpUiHostCapabilities, McpUiHostContext, McpUiHostContextChangedNotification, McpUiMessageRequest, McpUiOpenLinkRequest, McpUiDownloadFileRequest, McpUiResourceTeardownRequest, McpUiResourceTeardownResult, McpUiRequestTeardownNotification, McpUiSizeChangedNotification, McpUiToolCancelledNotification, McpUiToolInputNotification, McpUiToolInputPartialNotification, McpUiToolResultNotification, McpUiRequestDisplayModeRequest } from "./types"; | |
| import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js"; | |
| import { StandardSchemaV1 } from "./standard-schema"; | |
| import { z } from "zod/v4"; | |
| export type { StandardSchemaV1, StandardSchemaWithJSON, } from "./standard-schema"; | |
| export { PostMessageTransport } from "./message-transport"; | |
| export * from "./types"; | |
| export { applyHostStyleVariables, applyHostFonts, getDocumentTheme, applyDocumentTheme, } from "./styles"; | |
| /** | |
| * Metadata key for associating a UI resource URI with a tool. | |
| * | |
| * 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 and backwards compatibility. | |
| * Server developers should use {@link server-helpers!registerAppTool `registerAppTool`} | |
| * with the `_meta.ui.resourceUri` format instead. Host developers must check both | |
| * formats for compatibility. | |
| * | |
| * @example Modern format (server-side, not in Apps) | |
| * ```ts source="./app.examples.ts#RESOURCE_URI_META_KEY_modernFormat" | |
| * // Preferred: Use registerAppTool with nested ui.resourceUri | |
| * registerAppTool( | |
| * server, | |
| * "weather", | |
| * { | |
| * description: "Get weather forecast", | |
| * _meta: { | |
| * ui: { resourceUri: "ui://weather/forecast" }, | |
| * }, | |
| * }, | |
| * handler, | |
| * ); | |
| * ``` | |
| * | |
| * @example Legacy format (deprecated, for backwards compatibility) | |
| * ```ts source="./app.examples.ts#RESOURCE_URI_META_KEY_legacyFormat" | |
| * // Deprecated: Direct use of RESOURCE_URI_META_KEY | |
| * server.registerTool( | |
| * "weather", | |
| * { | |
| * description: "Get weather forecast", | |
| * _meta: { | |
| * [RESOURCE_URI_META_KEY]: "ui://weather/forecast", | |
| * }, | |
| * }, | |
| * handler, | |
| * ); | |
| * ``` | |
| * | |
| * @example How hosts check for this metadata (must support both formats) | |
| * ```ts source="./app.examples.ts#RESOURCE_URI_META_KEY_hostSide" | |
| * // Hosts should check both modern and legacy formats | |
| * const meta = tool._meta; | |
| * const uiMeta = meta?.ui as McpUiToolMeta | undefined; | |
| * const legacyUri = meta?.[RESOURCE_URI_META_KEY] as string | undefined; | |
| * const uiUri = uiMeta?.resourceUri ?? legacyUri; | |
| * if (typeof uiUri === "string" && uiUri.startsWith("ui://")) { | |
| * // Fetch the resource and display the UI | |
| * } | |
| * ``` | |
| */ | |
| export declare const RESOURCE_URI_META_KEY = "ui/resourceUri"; | |
| /** | |
| * MIME type for MCP UI resources. | |
| * | |
| * Identifies HTML content as an MCP App UI resource. | |
| * | |
| * 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 `App`} behavior. | |
| * | |
| * Extends `ProtocolOptions` from the MCP SDK with `App`-specific configuration. | |
| * | |
| * @see `ProtocolOptions` from @modelcontextprotocol/sdk for inherited options | |
| */ | |
| export type AppOptions = ProtocolOptions & { | |
| /** | |
| * Automatically report size changes to the host using `ResizeObserver`. | |
| * | |
| * When enabled, the {@link App `App`} monitors `document.body` and `document.documentElement` | |
| * for size changes and automatically sends `ui/notifications/size-changed` | |
| * notifications to the host. | |
| * | |
| * @default true | |
| */ | |
| autoResize?: boolean; | |
| /** | |
| * Throw on detected misuse instead of logging a console warning. | |
| * | |
| * Currently this affects calling host-bound methods (e.g. | |
| * {@link App.callServerTool `callServerTool`}, {@link App.sendMessage `sendMessage`}) | |
| * before {@link App.connect `connect`} has completed the `ui/initialize` | |
| * handshake. With `strict: false` (default) a `console.warn` is emitted; | |
| * with `strict: true` an `Error` is thrown. | |
| * | |
| * @remarks Throwing will become the default in a future release. | |
| * @default false | |
| */ | |
| strict?: boolean; | |
| /** | |
| * Allow code paths that require CSP `unsafe-eval` (e.g. `new Function()`). | |
| * | |
| * Views typically run under a strict CSP without `unsafe-eval`. Zod's JIT | |
| * object parser uses `new Function()` and throws on the first message parse | |
| * under such a policy. By default (`allowUnsafeEval: false`) the | |
| * {@link App `App`} constructor sets `z.config({ jitless: true })` so the | |
| * SDK works out of the box under the spec's default CSP. Set | |
| * `allowUnsafeEval: true` to skip that and keep the faster JIT path when | |
| * the host's CSP permits `unsafe-eval`. | |
| * | |
| * @default false | |
| */ | |
| allowUnsafeEval?: boolean; | |
| }; | |
| type RequestHandlerExtra = Parameters<Parameters<App["setRequestHandler"]>[1]>[1]; | |
| /** | |
| * Result of an app-registered tool callback. When `Out` is provided, | |
| * `structuredContent` is required and typed (unless `isError: true`). | |
| */ | |
| export type AppToolResult<Out extends StandardSchemaV1 | undefined = undefined> = Out extends StandardSchemaV1 ? (CallToolResult & { | |
| structuredContent: StandardSchemaV1.InferOutput<Out>; | |
| isError?: false; | |
| }) | (CallToolResult & { | |
| isError: true; | |
| }) : CallToolResult; | |
| /** | |
| * Callback for an app-registered tool. When `In` is provided, `args` is the | |
| * validated/parsed input; when `In` is `undefined`, the callback receives only | |
| * `extra`. When `Out` is provided, the return's `structuredContent` is typed. | |
| * | |
| * Mirrors `ToolCallback` from `@modelcontextprotocol/sdk/server/mcp.js` but is | |
| * parameterized over {@link StandardSchemaV1} instead of zod, so any | |
| * Standard-Schema-compatible library (Zod, ArkType, Valibot, …) can be used. | |
| */ | |
| export type AppToolCallback<In extends StandardSchemaV1 | undefined = undefined, Out extends StandardSchemaV1 | undefined = undefined> = In extends StandardSchemaV1 ? (args: StandardSchemaV1.InferOutput<In>, extra: RequestHandlerExtra) => AppToolResult<Out> | Promise<AppToolResult<Out>> : (extra: RequestHandlerExtra) => AppToolResult<Out> | Promise<AppToolResult<Out>>; | |
| /** | |
| * Handle returned by {@link App.registerTool}. Mirrors `RegisteredTool` from | |
| * `@modelcontextprotocol/sdk/server/mcp.js` but stores | |
| * {@link StandardSchemaV1} schemas. | |
| */ | |
| export type RegisteredAppTool = { | |
| title?: string; | |
| description?: string; | |
| inputSchema?: StandardSchemaV1; | |
| outputSchema?: StandardSchemaV1; | |
| annotations?: ToolAnnotations; | |
| _meta?: Record<string, unknown>; | |
| enabled: boolean; | |
| enable(): void; | |
| disable(): void; | |
| remove(): void; | |
| update(updates: Partial<Omit<RegisteredAppTool, "update">>): void; | |
| /** @internal */ | |
| handler: (args: unknown, extra: RequestHandlerExtra) => Promise<CallToolResult>; | |
| }; | |
| /** | |
| * Maps DOM-style event names to their notification `params` types. | |
| * | |
| * Used by {@link App `App`} (which extends {@link ProtocolWithEvents `ProtocolWithEvents`}) | |
| * to provide type-safe `addEventListener` / `removeEventListener` and | |
| * singular `on*` handler support. | |
| */ | |
| export type AppEventMap = { | |
| toolinput: McpUiToolInputNotification["params"]; | |
| toolinputpartial: McpUiToolInputPartialNotification["params"]; | |
| toolresult: McpUiToolResultNotification["params"]; | |
| toolcancelled: McpUiToolCancelledNotification["params"]; | |
| hostcontextchanged: McpUiHostContextChangedNotification["params"]; | |
| }; | |
| /** | |
| * Main class for MCP Apps to communicate with their host. | |
| * | |
| * The `App` class provides a framework-agnostic way to build interactive MCP Apps | |
| * that run inside host applications. It extends the MCP SDK's `Protocol` class and | |
| * handles the connection lifecycle, initialization handshake, and bidirectional | |
| * communication with the host. | |
| * | |
| * ## Architecture | |
| * | |
| * 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 | |
| * responses back to the App. | |
| * | |
| * ## Lifecycle | |
| * | |
| * 1. **Create**: Instantiate App with info and capabilities | |
| * 2. **Connect**: Call `connect()` to establish transport and perform handshake | |
| * 3. **Interactive**: Send requests, receive notifications, call tools | |
| * 4. **Teardown**: Host sends teardown request before unmounting | |
| * | |
| * ## Inherited Methods | |
| * | |
| * As a subclass of {@link ProtocolWithEvents `ProtocolWithEvents`}, `App` inherits: | |
| * - `setRequestHandler()` - Register handlers for requests from host | |
| * - `setNotificationHandler()` - Register handlers for notifications from host | |
| * - `addEventListener()` - Append a listener for a notification event (multi-listener) | |
| * - `removeEventListener()` - Remove a previously added listener | |
| * | |
| * @see {@link ProtocolWithEvents `ProtocolWithEvents`} for the DOM-model event system | |
| * | |
| * ## Notification Setters (DOM-model `on*` handlers) | |
| * | |
| * For common notifications, the `App` class provides getter/setter properties | |
| * that follow DOM-model replace semantics (like `el.onclick`): | |
| * - `ontoolinput` - Complete tool arguments from host | |
| * - `ontoolinputpartial` - Streaming partial tool arguments | |
| * - `ontoolresult` - Tool execution results | |
| * - `ontoolcancelled` - Tool execution was cancelled by user or host | |
| * - `onhostcontextchanged` - Host context changes (theme, locale, etc.) | |
| * | |
| * Assigning replaces the previous handler; assigning `undefined` clears it. | |
| * Use `addEventListener` to attach multiple listeners without replacing. | |
| * | |
| * @example Basic usage with PostMessageTransport | |
| * ```ts source="./app.examples.ts#App_basicUsage" | |
| * const app = new App( | |
| * { name: "WeatherApp", version: "1.0.0" }, | |
| * {}, // capabilities | |
| * ); | |
| * | |
| * // Register handlers before connecting to ensure no notifications are missed | |
| * app.ontoolinput = (params) => { | |
| * console.log("Tool arguments:", params.arguments); | |
| * }; | |
| * | |
| * await app.connect(); | |
| * ``` | |
| */ | |
| export declare class App extends ProtocolWithEvents<AppRequest, AppNotification, AppResult, AppEventMap> { | |
| private _appInfo; | |
| private _capabilities; | |
| private options; | |
| private _hostCapabilities?; | |
| private _hostInfo?; | |
| private _hostContext?; | |
| private _registeredTools; | |
| private _initializedSent; | |
| /** | |
| * Warn if a host-bound method is called before {@link connect `connect`} has | |
| * completed the `ui/initialize` → `ui/notifications/initialized` handshake. | |
| * | |
| * Calling these methods early can race the handshake on strict hosts and | |
| * leave the iframe permanently hidden. See | |
| * {@link https://github.com/anthropics/claude-ai-mcp/issues/61 claude-ai-mcp#61} / | |
| * {@link https://github.com/anthropics/claude-ai-mcp/issues/149 #149}. | |
| * | |
| * @remarks This will become a thrown `Error` in a future minor release. | |
| */ | |
| private _assertInitialized; | |
| protected readonly eventSchemas: { | |
| toolinput: z.ZodObject<{ | |
| method: z.ZodLiteral<"ui/notifications/tool-input">; | |
| params: z.ZodObject<{ | |
| arguments: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>; | |
| }, z.core.$strip>; | |
| }, z.core.$strip>; | |
| toolinputpartial: z.ZodObject<{ | |
| method: z.ZodLiteral<"ui/notifications/tool-input-partial">; | |
| params: z.ZodObject<{ | |
| arguments: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>; | |
| }, z.core.$strip>; | |
| }, z.core.$strip>; | |
| toolresult: z.ZodObject<{ | |
| method: z.ZodLiteral<"ui/notifications/tool-result">; | |
| params: z.ZodObject<{ | |
| _meta: z.ZodOptional<z.ZodObject<{ | |
| progressToken: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>; | |
| "io.modelcontextprotocol/related-task": z.ZodOptional<z.ZodObject<{ | |
| taskId: z.ZodString; | |
| }, z.core.$strip>>; | |
| }, z.core.$loose>>; | |
| content: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{ | |
| type: z.ZodLiteral<"text">; | |
| text: z.ZodString; | |
| annotations: z.ZodOptional<z.ZodObject<{ | |
| audience: z.ZodOptional<z.ZodArray<z.ZodEnum<{ | |
| user: "user"; | |
| assistant: "assistant"; | |
| }>>>; | |
| priority: z.ZodOptional<z.ZodNumber>; | |
| lastModified: z.ZodOptional<z.ZodISODateTime>; | |
| }, z.core.$strip>>; | |
| _meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>; | |
| }, z.core.$strip>, z.ZodObject<{ | |
| type: z.ZodLiteral<"image">; | |
| data: z.ZodString; | |
| mimeType: z.ZodString; | |
| annotations: z.ZodOptional<z.ZodObject<{ | |
| audience: z.ZodOptional<z.ZodArray<z.ZodEnum<{ | |
| user: "user"; | |
| assistant: "assistant"; | |
| }>>>; | |
| priority: z.ZodOptional<z.ZodNumber>; | |
| lastModified: z.ZodOptional<z.ZodISODateTime>; | |
| }, z.core.$strip>>; | |
| _meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>; | |
| }, z.core.$strip>, z.ZodObject<{ | |
| type: z.ZodLiteral<"audio">; | |
| data: z.ZodString; | |
| mimeType: z.ZodString; | |
| annotations: z.ZodOptional<z.ZodObject<{ | |
| audience: z.ZodOptional<z.ZodArray<z.ZodEnum<{ | |
| user: "user"; | |
| assistant: "assistant"; | |
| }>>>; | |
| priority: z.ZodOptional<z.ZodNumber>; | |
| lastModified: z.ZodOptional<z.ZodISODateTime>; | |
| }, z.core.$strip>>; | |
| _meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>; | |
| }, z.core.$strip>, z.ZodObject<{ | |
| uri: z.ZodString; | |
| description: z.ZodOptional<z.ZodString>; | |
| mimeType: z.ZodOptional<z.ZodString>; | |
| size: z.ZodOptional<z.ZodNumber>; | |
| annotations: z.ZodOptional<z.ZodObject<{ | |
| audience: z.ZodOptional<z.ZodArray<z.ZodEnum<{ | |
| user: "user"; | |
| assistant: "assistant"; | |
| }>>>; | |
| priority: z.ZodOptional<z.ZodNumber>; | |
| lastModified: z.ZodOptional<z.ZodISODateTime>; | |
| }, z.core.$strip>>; | |
| _meta: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>; | |
| icons: z.ZodOptional<z.ZodArray<z.ZodObject<{ | |
| src: z.ZodString; | |
| mimeType: z.ZodOptional<z.ZodString>; | |
| sizes: z.ZodOptional<z.ZodArray<z.ZodString>>; | |
| theme: z.ZodOptional<z.ZodEnum<{ | |
| light: "light"; | |
| dark: "dark"; | |
| }>>; | |
| }, z.core.$strip>>>; | |
| name: z.ZodString; | |
| title: z.ZodOptional<z.ZodString>; | |
| type: z.ZodLiteral<"resource_link">; | |
| }, z.core.$strip>, z.ZodObject<{ | |
| type: z.ZodLiteral<"resource">; | |
| resource: z.ZodUnion<readonly [z.ZodObject<{ | |
| uri: z.ZodString; | |
| mimeType: z.ZodOptional<z.ZodString>; | |
| _meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>; | |
| text: z.ZodString; | |
| }, z.core.$strip>, z.ZodObject<{ | |
| uri: z.ZodString; | |
| mimeType: z.ZodOptional<z.ZodString>; | |
| _meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>; | |
| blob: z.ZodString; | |
| }, z.core.$strip>]>; | |
| annotations: z.ZodOptional<z.ZodObject<{ | |
| audience: z.ZodOptional<z.ZodArray<z.ZodEnum<{ | |
| user: "user"; | |
| assistant: "assistant"; | |
| }>>>; | |
| priority: z.ZodOptional<z.ZodNumber>; | |
| lastModified: z.ZodOptional<z.ZodISODateTime>; | |
| }, z.core.$strip>>; | |
| _meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>; | |
| }, z.core.$strip>]>>>; | |
| structuredContent: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>; | |
| isError: z.ZodOptional<z.ZodBoolean>; | |
| }, z.core.$loose>; | |
| }, z.core.$strip>; | |
| toolcancelled: z.ZodObject<{ | |
| method: z.ZodLiteral<"ui/notifications/tool-cancelled">; | |
| params: z.ZodObject<{ | |
| reason: z.ZodOptional<z.ZodString>; | |
| }, z.core.$strip>; | |
| }, z.core.$strip>; | |
| hostcontextchanged: z.ZodObject<{ | |
| method: z.ZodLiteral<"ui/notifications/host-context-changed">; | |
| params: z.ZodObject<{ | |
| toolInfo: z.ZodOptional<z.ZodObject<{ | |
| id: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>; | |
| tool: z.ZodObject<{ | |
| description: z.ZodOptional<z.ZodString>; | |
| inputSchema: z.ZodObject<{ | |
| type: z.ZodLiteral<"object">; | |
| properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCustom<object, object>>>; | |
| required: z.ZodOptional<z.ZodArray<z.ZodString>>; | |
| }, z.core.$catchall<z.ZodUnknown>>; | |
| outputSchema: z.ZodOptional<z.ZodObject<{ | |
| type: z.ZodLiteral<"object">; | |
| properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCustom<object, object>>>; | |
| required: z.ZodOptional<z.ZodArray<z.ZodString>>; | |
| }, z.core.$catchall<z.ZodUnknown>>>; | |
| annotations: z.ZodOptional<z.ZodObject<{ | |
| title: z.ZodOptional<z.ZodString>; | |
| readOnlyHint: z.ZodOptional<z.ZodBoolean>; | |
| destructiveHint: z.ZodOptional<z.ZodBoolean>; | |
| idempotentHint: z.ZodOptional<z.ZodBoolean>; | |
| openWorldHint: z.ZodOptional<z.ZodBoolean>; | |
| }, z.core.$strip>>; | |
| execution: z.ZodOptional<z.ZodObject<{ | |
| taskSupport: z.ZodOptional<z.ZodEnum<{ | |
| optional: "optional"; | |
| required: "required"; | |
| forbidden: "forbidden"; | |
| }>>; | |
| }, z.core.$strip>>; | |
| _meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>; | |
| icons: z.ZodOptional<z.ZodArray<z.ZodObject<{ | |
| src: z.ZodString; | |
| mimeType: z.ZodOptional<z.ZodString>; | |
| sizes: z.ZodOptional<z.ZodArray<z.ZodString>>; | |
| theme: z.ZodOptional<z.ZodEnum<{ | |
| light: "light"; | |
| dark: "dark"; | |
| }>>; | |
| }, z.core.$strip>>>; | |
| name: z.ZodString; | |
| title: z.ZodOptional<z.ZodString>; | |
| }, z.core.$strip>; | |
| }, z.core.$strip>>; | |
| theme: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"light">, z.ZodLiteral<"dark">]>>; | |
| styles: z.ZodOptional<z.ZodObject<{ | |
| variables: z.ZodOptional<z.ZodRecord<z.ZodUnion<readonly [z.ZodLiteral<"--color-background-primary">, z.ZodLiteral<"--color-background-secondary">, z.ZodLiteral<"--color-background-tertiary">, z.ZodLiteral<"--color-background-inverse">, z.ZodLiteral<"--color-background-ghost">, z.ZodLiteral<"--color-background-info">, z.ZodLiteral<"--color-background-danger">, z.ZodLiteral<"--color-background-success">, z.ZodLiteral<"--color-background-warning">, z.ZodLiteral<"--color-background-disabled">, z.ZodLiteral<"--color-text-primary">, z.ZodLiteral<"--color-text-secondary">, z.ZodLiteral<"--color-text-tertiary">, z.ZodLiteral<"--color-text-inverse">, z.ZodLiteral<"--color-text-ghost">, z.ZodLiteral<"--color-text-info">, z.ZodLiteral<"--color-text-danger">, z.ZodLiteral<"--color-text-success">, z.ZodLiteral<"--color-text-warning">, z.ZodLiteral<"--color-text-disabled">, z.ZodLiteral<"--color-border-primary">, z.ZodLiteral<"--color-border-secondary">, z.ZodLiteral<"--color-border-tertiary">, z.ZodLiteral<"--color-border-inverse">, z.ZodLiteral<"--color-border-ghost">, z.ZodLiteral<"--color-border-info">, z.ZodLiteral<"--color-border-danger">, z.ZodLiteral<"--color-border-success">, z.ZodLiteral<"--color-border-warning">, z.ZodLiteral<"--color-border-disabled">, z.ZodLiteral<"--color-ring-primary">, z.ZodLiteral<"--color-ring-secondary">, z.ZodLiteral<"--color-ring-inverse">, z.ZodLiteral<"--color-ring-info">, z.ZodLiteral<"--color-ring-danger">, z.ZodLiteral<"--color-ring-success">, z.ZodLiteral<"--color-ring-warning">, z.ZodLiteral<"--font-sans">, z.ZodLiteral<"--font-mono">, z.ZodLiteral<"--font-weight-normal">, z.ZodLiteral<"--font-weight-medium">, z.ZodLiteral<"--font-weight-semibold">, z.ZodLiteral<"--font-weight-bold">, z.ZodLiteral<"--font-text-xs-size">, z.ZodLiteral<"--font-text-sm-size">, z.ZodLiteral<"--font-text-md-size">, z.ZodLiteral<"--font-text-lg-size">, z.ZodLiteral<"--font-heading-xs-size">, z.ZodLiteral<"--font-heading-sm-size">, z.ZodLiteral<"--font-heading-md-size">, z.ZodLiteral<"--font-heading-lg-size">, z.ZodLiteral<"--font-heading-xl-size">, z.ZodLiteral<"--font-heading-2xl-size">, z.ZodLiteral<"--font-heading-3xl-size">, z.ZodLiteral<"--font-text-xs-line-height">, z.ZodLiteral<"--font-text-sm-line-height">, z.ZodLiteral<"--font-text-md-line-height">, z.ZodLiteral<"--font-text-lg-line-height">, z.ZodLiteral<"--font-heading-xs-line-height">, z.ZodLiteral<"--font-heading-sm-line-height">, z.ZodLiteral<"--font-heading-md-line-height">, z.ZodLiteral<"--font-heading-lg-line-height">, z.ZodLiteral<"--font-heading-xl-line-height">, z.ZodLiteral<"--font-heading-2xl-line-height">, z.ZodLiteral<"--font-heading-3xl-line-height">, z.ZodLiteral<"--border-radius-xs">, z.ZodLiteral<"--border-radius-sm">, z.ZodLiteral<"--border-radius-md">, z.ZodLiteral<"--border-radius-lg">, z.ZodLiteral<"--border-radius-xl">, z.ZodLiteral<"--border-radius-full">, z.ZodLiteral<"--border-width-regular">, z.ZodLiteral<"--shadow-hairline">, z.ZodLiteral<"--shadow-sm">, z.ZodLiteral<"--shadow-md">, z.ZodLiteral<"--shadow-lg">]>, z.ZodUnion<readonly [z.ZodString, z.ZodUndefined]>>>; | |
| css: z.ZodOptional<z.ZodObject<{ | |
| fonts: z.ZodOptional<z.ZodString>; | |
| }, z.core.$strip>>; | |
| }, z.core.$strip>>; | |
| displayMode: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"inline">, z.ZodLiteral<"fullscreen">, z.ZodLiteral<"pip">]>>; | |
| 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<{ | |
| height: z.ZodNumber; | |
| }, z.core.$strip>, z.ZodObject<{ | |
| maxHeight: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodUndefined]>>; | |
| }, z.core.$strip>]>, z.ZodUnion<readonly [z.ZodObject<{ | |
| width: z.ZodNumber; | |
| }, z.core.$strip>, z.ZodObject<{ | |
| maxWidth: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodUndefined]>>; | |
| }, z.core.$strip>]>>>; | |
| locale: z.ZodOptional<z.ZodString>; | |
| timeZone: z.ZodOptional<z.ZodString>; | |
| userAgent: z.ZodOptional<z.ZodString>; | |
| platform: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"web">, z.ZodLiteral<"desktop">, z.ZodLiteral<"mobile">]>>; | |
| deviceCapabilities: z.ZodOptional<z.ZodObject<{ | |
| touch: z.ZodOptional<z.ZodBoolean>; | |
| hover: z.ZodOptional<z.ZodBoolean>; | |
| }, z.core.$strip>>; | |
| safeAreaInsets: z.ZodOptional<z.ZodObject<{ | |
| top: z.ZodNumber; | |
| right: z.ZodNumber; | |
| bottom: z.ZodNumber; | |
| left: z.ZodNumber; | |
| }, z.core.$strip>>; | |
| }, z.core.$loose>; | |
| }, z.core.$strip>; | |
| }; | |
| /** | |
| * Events the host typically sends once, shortly after the handshake. | |
| * Registering a handler for one of these *after* {@link connect `connect`} | |
| * resolves risks missing the notification entirely. | |
| */ | |
| private static readonly ONE_SHOT_EVENTS; | |
| /** | |
| * One-shot events that have had at least one handler registered (via `on*` | |
| * setter or `addEventListener`) at any point. Once an event is in this set, | |
| * subsequent late registrations are not flagged — only the *first* handler | |
| * matters for the missed-notification race, and re-registration (e.g. React | |
| * `useEffect` cleanup → re-add on dep change) is a legitimate pattern. | |
| */ | |
| private readonly _everHadListener; | |
| /** | |
| * Warn (or throw under `strict`) when the *first* handler for a one-shot | |
| * event is registered after the `ui/initialize` → `ui/notifications/initialized` | |
| * handshake has completed. The host may have already fired the notification | |
| * by then. Subsequent registrations for the same event are not flagged. | |
| * | |
| * Mirrors {@link _assertInitialized `_assertInitialized`} (the outbound-side guard). | |
| */ | |
| private _assertHandlerTiming; | |
| protected setEventHandler<K extends keyof AppEventMap>(event: K, handler: ((params: AppEventMap[K]) => void) | undefined): void; | |
| addEventListener<K extends keyof AppEventMap>(event: K, handler: (params: AppEventMap[K]) => void): void; | |
| protected onEventDispatch<K extends keyof AppEventMap>(event: K, params: AppEventMap[K]): void; | |
| /** | |
| * Create a new MCP App instance. | |
| * | |
| * @param _appInfo - App identification (name and version) | |
| * @param _capabilities - Features and capabilities this app provides | |
| * @param options - Configuration options including `autoResize` behavior | |
| * | |
| * @example | |
| * ```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 | |
| * ); | |
| * ``` | |
| */ | |
| constructor(_appInfo: Implementation, _capabilities?: McpUiAppCapabilities, options?: AppOptions); | |
| private registerCapabilities; | |
| registerTool<OutputArgs extends undefined | StandardSchemaV1 = undefined, InputArgs extends undefined | StandardSchemaV1 = undefined>(name: string, config: { | |
| title?: string; | |
| description?: string; | |
| inputSchema?: InputArgs; | |
| outputSchema?: OutputArgs; | |
| annotations?: ToolAnnotations; | |
| _meta?: Record<string, unknown>; | |
| }, cb: AppToolCallback<InputArgs, OutputArgs>): RegisteredAppTool; | |
| private _toolHandlersInitialized; | |
| private ensureToolHandlersInitialized; | |
| sendToolListChanged(params?: ToolListChangedNotification["params"]): Promise<void>; | |
| /** | |
| * Get the host's capabilities discovered during initialization. | |
| * | |
| * Returns the capabilities that the host advertised during the | |
| * {@link connect `connect`} handshake. Returns `undefined` if called before | |
| * connection is established. | |
| * | |
| * @returns Host capabilities, or `undefined` if not yet connected | |
| * | |
| * @example Check host capabilities after connection | |
| * ```ts source="./app.examples.ts#App_getHostCapabilities_checkAfterConnection" | |
| * await app.connect(); | |
| * if (app.getHostCapabilities()?.serverTools) { | |
| * console.log("Host supports server tool calls"); | |
| * } | |
| * ``` | |
| * | |
| * @see {@link connect `connect`} for the initialization handshake | |
| * @see {@link McpUiHostCapabilities `McpUiHostCapabilities`} for the capabilities structure | |
| */ | |
| getHostCapabilities(): McpUiHostCapabilities | undefined; | |
| /** | |
| * Get the host's implementation info discovered during initialization. | |
| * | |
| * Returns the host's name and version as advertised during the | |
| * {@link connect `connect`} handshake. Returns `undefined` if called before | |
| * connection is established. | |
| * | |
| * @returns Host implementation info, or `undefined` if not yet connected | |
| * | |
| * @example Log host information after connection | |
| * ```ts source="./app.examples.ts#App_getHostVersion_logAfterConnection" | |
| * await app.connect(transport); | |
| * const { name, version } = app.getHostVersion() ?? {}; | |
| * console.log(`Connected to ${name} v${version}`); | |
| * ``` | |
| * | |
| * @see {@link connect `connect`} for the initialization handshake | |
| */ | |
| getHostVersion(): Implementation | undefined; | |
| /** | |
| * Get the host context discovered during initialization. | |
| * | |
| * Returns the host context that was provided in the initialization response, | |
| * including tool info, theme, locale, and other environment details. | |
| * This context is automatically updated when the host sends | |
| * `ui/notifications/host-context-changed` notifications. | |
| * | |
| * Returns `undefined` if called before connection is established. | |
| * | |
| * @returns Host context, or `undefined` if not yet connected | |
| * | |
| * @example Access host context after connection | |
| * ```ts source="./app.examples.ts#App_getHostContext_accessAfterConnection" | |
| * await app.connect(transport); | |
| * const context = app.getHostContext(); | |
| * if (context?.theme === "dark") { | |
| * document.body.classList.add("dark-theme"); | |
| * } | |
| * if (context?.toolInfo) { | |
| * console.log("Tool:", context.toolInfo.tool.name); | |
| * } | |
| * ``` | |
| * | |
| * @see {@link connect `connect`} for the initialization handshake | |
| * @see {@link onhostcontextchanged `onhostcontextchanged`} for context change notifications | |
| * @see {@link McpUiHostContext `McpUiHostContext`} for the context structure | |
| */ | |
| getHostContext(): McpUiHostContext | undefined; | |
| /** | |
| * Convenience handler for receiving complete tool input from the host. | |
| * | |
| * Set this property to register a handler that will be called when the host | |
| * sends a tool's complete arguments. This is sent after a tool call begins | |
| * and before the tool result is available. | |
| * | |
| * Assigning replaces the previous handler; assigning `undefined` clears it. | |
| * Use {@link addEventListener `addEventListener`} to attach multiple listeners | |
| * without replacing. | |
| * | |
| * Register handlers before calling {@link connect `connect`} to avoid missing notifications. | |
| * | |
| * @example | |
| * ```ts source="./app.examples.ts#App_ontoolinput_setter" | |
| * // Register before connecting to ensure no notifications are missed | |
| * app.ontoolinput = (params) => { | |
| * console.log("Tool:", params.arguments); | |
| * // Update your UI with the tool arguments | |
| * }; | |
| * await app.connect(); | |
| * ``` | |
| * | |
| * @deprecated Use {@link addEventListener `addEventListener("toolinput", handler)`} instead — it composes with other listeners and supports cleanup via {@link removeEventListener `removeEventListener`}. | |
| * @see {@link McpUiToolInputNotification `McpUiToolInputNotification`} for the notification structure | |
| */ | |
| get ontoolinput(): ((params: McpUiToolInputNotification["params"]) => void) | undefined; | |
| set ontoolinput(callback: ((params: McpUiToolInputNotification["params"]) => void) | undefined); | |
| /** | |
| * Convenience handler for receiving streaming partial tool input from the host. | |
| * | |
| * Set this property to register a handler that will be called as the host | |
| * streams partial tool arguments during tool call initialization. This enables | |
| * progressive rendering of tool arguments before they're complete. | |
| * | |
| * **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. | |
| * | |
| * Assigning replaces the previous handler; assigning `undefined` clears it. | |
| * Use {@link addEventListener `addEventListener`} to attach multiple listeners | |
| * without replacing. | |
| * | |
| * Register handlers before calling {@link connect `connect`} to avoid missing notifications. | |
| * | |
| * @example Progressive rendering of tool arguments | |
| * ```ts source="./app.examples.ts#App_ontoolinputpartial_progressiveRendering" | |
| * const codePreview = document.querySelector<HTMLPreElement>("#code-preview")!; | |
| * const canvas = document.querySelector<HTMLCanvasElement>("#canvas")!; | |
| * | |
| * app.ontoolinputpartial = (params) => { | |
| * codePreview.textContent = (params.arguments?.code as string) ?? ""; | |
| * codePreview.style.display = "block"; | |
| * canvas.style.display = "none"; | |
| * }; | |
| * | |
| * app.ontoolinput = (params) => { | |
| * codePreview.style.display = "none"; | |
| * canvas.style.display = "block"; | |
| * render(params.arguments?.code as string); | |
| * }; | |
| * ``` | |
| * | |
| * @deprecated Use {@link addEventListener `addEventListener("toolinputpartial", handler)`} instead — it composes with other listeners and supports cleanup via {@link removeEventListener `removeEventListener`}. | |
| * @see {@link McpUiToolInputPartialNotification `McpUiToolInputPartialNotification`} for the notification structure | |
| * @see {@link ontoolinput `ontoolinput`} for the complete tool input handler | |
| */ | |
| get ontoolinputpartial(): ((params: McpUiToolInputPartialNotification["params"]) => void) | undefined; | |
| set ontoolinputpartial(callback: ((params: McpUiToolInputPartialNotification["params"]) => void) | undefined); | |
| /** | |
| * Convenience handler for receiving tool execution results from the host. | |
| * | |
| * Set this property to register a handler that will be called when the host | |
| * sends the result of a tool execution. This is sent after the tool completes | |
| * on the MCP server, allowing your app to display the results or update its state. | |
| * | |
| * Assigning replaces the previous handler; assigning `undefined` clears it. | |
| * Use {@link addEventListener `addEventListener`} to attach multiple listeners | |
| * without replacing. | |
| * | |
| * Register handlers before calling {@link connect `connect`} to avoid missing notifications. | |
| * | |
| * @example Display tool execution results | |
| * ```ts source="./app.examples.ts#App_ontoolresult_displayResults" | |
| * app.ontoolresult = (params) => { | |
| * if (params.isError) { | |
| * console.error("Tool execution failed:", params.content); | |
| * } else if (params.content) { | |
| * console.log("Tool output:", params.content); | |
| * } | |
| * }; | |
| * ``` | |
| * | |
| * @deprecated Use {@link addEventListener `addEventListener("toolresult", handler)`} instead — it composes with other listeners and supports cleanup via {@link removeEventListener `removeEventListener`}. | |
| * @see {@link McpUiToolResultNotification `McpUiToolResultNotification`} for the notification structure | |
| * @see {@link ontoolinput `ontoolinput`} for the initial tool input handler | |
| */ | |
| get ontoolresult(): ((params: McpUiToolResultNotification["params"]) => void) | undefined; | |
| set ontoolresult(callback: ((params: McpUiToolResultNotification["params"]) => void) | undefined); | |
| /** | |
| * Convenience handler for receiving tool cancellation notifications from the host. | |
| * | |
| * Set this property to register a handler that will be called when the host | |
| * notifies that tool execution was cancelled. This can occur for various reasons | |
| * including user action, sampling error, classifier intervention, or other | |
| * interruptions. Apps should update their state and display appropriate feedback. | |
| * | |
| * Assigning replaces the previous handler; assigning `undefined` clears it. | |
| * Use {@link addEventListener `addEventListener`} to attach multiple listeners | |
| * without replacing. | |
| * | |
| * Register handlers before calling {@link connect `connect`} to avoid missing notifications. | |
| * | |
| * @example Handle tool cancellation | |
| * ```ts source="./app.examples.ts#App_ontoolcancelled_handleCancellation" | |
| * app.ontoolcancelled = (params) => { | |
| * console.log("Tool cancelled:", params.reason); | |
| * // Update your UI to show cancellation state | |
| * }; | |
| * ``` | |
| * | |
| * @deprecated Use {@link addEventListener `addEventListener("toolcancelled", handler)`} instead — it composes with other listeners and supports cleanup via {@link removeEventListener `removeEventListener`}. | |
| * @see {@link McpUiToolCancelledNotification `McpUiToolCancelledNotification`} for the notification structure | |
| * @see {@link ontoolresult `ontoolresult`} for successful tool completion | |
| */ | |
| get ontoolcancelled(): ((params: McpUiToolCancelledNotification["params"]) => void) | undefined; | |
| set ontoolcancelled(callback: ((params: McpUiToolCancelledNotification["params"]) => void) | undefined); | |
| /** | |
| * Convenience handler for host context changes (theme, locale, etc.). | |
| * | |
| * Set this property to register a handler that will be called when the host's | |
| * context changes, such as theme switching (light/dark), locale changes, or | |
| * other environmental updates. Apps should respond by updating their UI | |
| * accordingly. | |
| * | |
| * Assigning replaces the previous handler; assigning `undefined` clears it. | |
| * Use {@link addEventListener `addEventListener`} to attach multiple listeners | |
| * without replacing. | |
| * | |
| * Notification params are automatically merged into the internal host context | |
| * via {@link onEventDispatch `onEventDispatch`} before any handler or listener | |
| * fires. This means {@link getHostContext `getHostContext`} will return the | |
| * updated values even before your callback runs. | |
| * | |
| * Register handlers before calling {@link connect `connect`} to avoid missing notifications. | |
| * | |
| * @example Respond to theme changes | |
| * ```ts source="./app.examples.ts#App_onhostcontextchanged_respondToTheme" | |
| * app.onhostcontextchanged = (ctx) => { | |
| * if (ctx.theme === "dark") { | |
| * document.body.classList.add("dark-theme"); | |
| * } else { | |
| * document.body.classList.remove("dark-theme"); | |
| * } | |
| * }; | |
| * ``` | |
| * | |
| * @deprecated Use {@link addEventListener `addEventListener("hostcontextchanged", handler)`} instead — it composes with other listeners and supports cleanup via {@link removeEventListener `removeEventListener`}. | |
| * @see {@link McpUiHostContextChangedNotification `McpUiHostContextChangedNotification`} for the notification structure | |
| * @see {@link McpUiHostContext `McpUiHostContext`} for the full context structure | |
| */ | |
| get onhostcontextchanged(): ((params: McpUiHostContextChangedNotification["params"]) => void) | undefined; | |
| set onhostcontextchanged(callback: ((params: McpUiHostContextChangedNotification["params"]) => void) | undefined); | |
| /** | |
| * Convenience handler for graceful shutdown requests from the host. | |
| * | |
| * Set this property to register a handler that will be called when the host | |
| * requests the app to prepare for teardown. This allows the app to perform | |
| * cleanup operations (save state, close connections, etc.) before being unmounted. | |
| * | |
| * The handler can be sync or async. The host will wait for the returned promise | |
| * to resolve before proceeding with teardown. | |
| * | |
| * Assigning replaces the previous handler; assigning `undefined` clears it. | |
| * | |
| * Register handlers before calling {@link connect `connect`} to avoid missing requests. | |
| * | |
| * @param callback - Function called when teardown is requested. | |
| * Must return `McpUiResourceTeardownResult` (can be an empty object `{}`) or a Promise resolving to it. | |
| * | |
| * @example Perform cleanup before teardown | |
| * ```ts source="./app.examples.ts#App_onteardown_performCleanup" | |
| * app.onteardown = async () => { | |
| * await saveState(); | |
| * closeConnections(); | |
| * console.log("App ready for teardown"); | |
| * return {}; | |
| * }; | |
| * ``` | |
| * | |
| * @see {@link McpUiResourceTeardownRequest `McpUiResourceTeardownRequest`} for the request structure | |
| */ | |
| private _onteardown?; | |
| get onteardown(): ((params: McpUiResourceTeardownRequest["params"], extra: RequestHandlerExtra) => McpUiResourceTeardownResult | Promise<McpUiResourceTeardownResult>) | undefined; | |
| set onteardown(callback: ((params: McpUiResourceTeardownRequest["params"], extra: RequestHandlerExtra) => McpUiResourceTeardownResult | Promise<McpUiResourceTeardownResult>) | undefined); | |
| /** | |
| * Convenience handler for tool call requests from the host. | |
| * | |
| * Set this property to register a handler that will be called when the host | |
| * requests this app to execute a tool. This enables apps to provide their own | |
| * tools that can be called by the host or LLM. | |
| * | |
| * The app must declare tool capabilities in the constructor to use this handler. | |
| * | |
| * Assigning replaces the previous handler; assigning `undefined` clears it. | |
| * | |
| * Register handlers before calling {@link connect `connect`} to avoid missing requests. | |
| * | |
| * @param callback - Async function that executes the tool and returns the result. | |
| * The callback will only be invoked if the app declared tool capabilities | |
| * in the constructor. | |
| * | |
| * @example Handle tool calls from the host | |
| * ```ts source="./app.examples.ts#App_oncalltool_handleFromHost" | |
| * app.oncalltool = async (params, extra) => { | |
| * if (params.name === "greet") { | |
| * const name = params.arguments?.name ?? "World"; | |
| * return { content: [{ type: "text", text: `Hello, ${name}!` }] }; | |
| * } | |
| * throw new Error(`Unknown tool: ${params.name}`); | |
| * }; | |
| * ``` | |
| */ | |
| private _oncalltool?; | |
| get oncalltool(): ((params: CallToolRequest["params"], extra: RequestHandlerExtra) => Promise<CallToolResult>) | undefined; | |
| set oncalltool(callback: ((params: CallToolRequest["params"], extra: RequestHandlerExtra) => Promise<CallToolResult>) | undefined); | |
| /** | |
| * Convenience handler for listing available tools. | |
| * | |
| * Set this property to register a handler that will be called when the host | |
| * requests a list of tools this app provides. This enables dynamic tool | |
| * discovery by the host or LLM. | |
| * | |
| * The app must declare tool capabilities in the constructor to use this handler. | |
| * | |
| * Assigning replaces the previous handler; assigning `undefined` clears it. | |
| * | |
| * Register handlers before calling {@link connect `connect`} to avoid missing requests. | |
| * | |
| * @param callback - Async function that returns a {@link ListToolsResult `ListToolsResult`}. | |
| * Registration is always allowed; capability validation occurs when handlers | |
| * are invoked. | |
| * | |
| * @example Return available tools | |
| * ```ts source="./app.examples.ts#App_onlisttools_returnTools" | |
| * app.onlisttools = async (params, extra) => { | |
| * return { | |
| * tools: [ | |
| * { | |
| * name: "greet", | |
| * description: "Greet the user", | |
| * inputSchema: { type: "object" as const }, | |
| * }, | |
| * { | |
| * name: "calculate", | |
| * description: "Perform a calculation", | |
| * inputSchema: { type: "object" as const }, | |
| * }, | |
| * { | |
| * name: "format", | |
| * description: "Format text", | |
| * inputSchema: { type: "object" as const }, | |
| * }, | |
| * ], | |
| * }; | |
| * }; | |
| * ``` | |
| * | |
| * @see {@link oncalltool `oncalltool`} for handling tool execution | |
| */ | |
| private _onlisttools?; | |
| get onlisttools(): ((params: ListToolsRequest["params"], extra: RequestHandlerExtra) => Promise<ListToolsResult>) | undefined; | |
| set onlisttools(callback: ((params: ListToolsRequest["params"], extra: RequestHandlerExtra) => Promise<ListToolsResult>) | undefined); | |
| /** | |
| * Verify that the host supports the capability required for the given request method. | |
| * @internal | |
| */ | |
| assertCapabilityForMethod(method: AppRequest["method"]): void; | |
| /** | |
| * Verify that the app declared the capability required for the given request method. | |
| * @internal | |
| */ | |
| assertRequestHandlerCapability(method: AppRequest["method"]): void; | |
| /** | |
| * Verify that the app supports the capability required for the given notification method. | |
| * @internal | |
| */ | |
| assertNotificationCapability(_method: AppNotification["method"]): void; | |
| /** | |
| * Verify that task creation is supported for the given request method. | |
| * @internal | |
| */ | |
| protected assertTaskCapability(_method: string): void; | |
| /** | |
| * Verify that task handler is supported for the given method. | |
| * @internal | |
| */ | |
| protected assertTaskHandlerCapability(_method: string): void; | |
| /** | |
| * Call a tool on the originating MCP server (proxied through the host). | |
| * | |
| * Apps can call tools to fetch fresh data or trigger server-side actions. | |
| * The host proxies the request to the actual MCP server and returns the result. | |
| * | |
| * @param params - Tool name and arguments | |
| * @param options - Request options (timeout, etc.) | |
| * @returns Tool execution result | |
| * | |
| * @throws {Error} If the tool does not exist on the server | |
| * @throws {Error} If the request times out or the connection is lost | |
| * @throws {Error} If the host rejects the request | |
| * | |
| * Note: Tool-level execution errors are returned in the result with `isError: true` | |
| * rather than throwing exceptions. Always check `result.isError` to distinguish | |
| * between transport failures (thrown) and tool execution failures (returned). | |
| * | |
| * @example Fetch updated weather data | |
| * ```ts source="./app.examples.ts#App_callServerTool_fetchWeather" | |
| * try { | |
| * const result = await app.callServerTool({ | |
| * name: "get_weather", | |
| * arguments: { location: "Tokyo" }, | |
| * }); | |
| * if (result.isError) { | |
| * console.error("Tool returned error:", result.content); | |
| * } else { | |
| * console.log(result.content); | |
| * } | |
| * } catch (error) { | |
| * console.error("Tool call failed:", error); | |
| * } | |
| * ``` | |
| */ | |
| callServerTool(params: CallToolRequest["params"], options?: RequestOptions): Promise<CallToolResult>; | |
| /** | |
| * Read a resource from the originating MCP server (proxied through the host). | |
| * | |
| * Apps can read resources to access files, data, or other content provided by | |
| * the MCP server. Resources are identified by URI (e.g., `file:///path/to/file` | |
| * or custom schemes like `videos://bunny-1mb`). The host proxies the request to | |
| * the actual MCP server and returns the resource content. | |
| * | |
| * @param params - Resource URI to read | |
| * @param options - Request options (timeout, etc.) | |
| * @returns Resource content with URI, name, description, mimeType, and contents array | |
| * | |
| * @throws {Error} If the resource does not exist on the server | |
| * @throws {Error} If the request times out or the connection is lost | |
| * @throws {Error} If the host rejects the request | |
| * | |
| * @example Read a video resource and play it | |
| * ```ts source="./app.examples.ts#App_readServerResource_playVideo" | |
| * try { | |
| * const result = await app.readServerResource({ | |
| * uri: "videos://bunny-1mb", | |
| * }); | |
| * const content = result.contents[0]; | |
| * if (content && "blob" in content) { | |
| * const binary = Uint8Array.from(atob(content.blob), (c) => | |
| * c.charCodeAt(0), | |
| * ); | |
| * const url = URL.createObjectURL( | |
| * new Blob([binary], { type: content.mimeType || "video/mp4" }), | |
| * ); | |
| * videoElement.src = url; | |
| * videoElement.play(); | |
| * } | |
| * } catch (error) { | |
| * console.error("Failed to read resource:", error); | |
| * } | |
| * ``` | |
| * | |
| * @see {@link listServerResources `listServerResources`} to discover available resources | |
| */ | |
| readServerResource(params: ReadResourceRequest["params"], options?: RequestOptions): Promise<ReadResourceResult>; | |
| /** | |
| * List available resources from the originating MCP server (proxied through the host). | |
| * | |
| * Apps can list resources to discover what content is available on the MCP server. | |
| * This enables dynamic resource discovery and building resource browsers or pickers. | |
| * The host proxies the request to the actual MCP server and returns the resource list. | |
| * | |
| * Results may be paginated using the `cursor` parameter for servers with many resources. | |
| * | |
| * @param params - Optional parameters (omit for all resources, or `{ cursor }` for pagination) | |
| * @param options - Request options (timeout, etc.) | |
| * @returns List of resources with their URIs, names, descriptions, mimeTypes, and optional pagination cursor | |
| * | |
| * @throws {Error} If the request times out or the connection is lost | |
| * @throws {Error} If the host rejects the request | |
| * | |
| * @example Discover available videos and build a picker UI | |
| * ```ts source="./app.examples.ts#App_listServerResources_buildPicker" | |
| * try { | |
| * const result = await app.listServerResources(); | |
| * const videoResources = result.resources.filter((r) => | |
| * r.mimeType?.startsWith("video/"), | |
| * ); | |
| * videoResources.forEach((resource) => { | |
| * const option = document.createElement("option"); | |
| * option.value = resource.uri; | |
| * option.textContent = resource.description || resource.name; | |
| * selectElement.appendChild(option); | |
| * }); | |
| * } catch (error) { | |
| * console.error("Failed to list resources:", error); | |
| * } | |
| * ``` | |
| * | |
| * @see {@link readServerResource `readServerResource`} to read a specific resource | |
| */ | |
| listServerResources(params?: ListResourcesRequest["params"], options?: RequestOptions): Promise<ListResourcesResult>; | |
| /** | |
| * Request an LLM completion from the host (standard MCP `sampling/createMessage`). | |
| * | |
| * Enables the app to use the host's model connection for completions. The host | |
| * has full discretion over which model to select and MAY modify or reject the | |
| * request (human-in-the-loop). Check {@link getHostCapabilities `getHostCapabilities`}`()?.sampling` | |
| * before calling — hosts without this capability will reject the request. | |
| * | |
| * This method reuses the stock MCP `CreateMessageRequest` shape. When `params.tools` | |
| * is provided, the result is parsed with the extended schema that permits | |
| * `stopReason: "toolUse"` and array content containing `tool_use` blocks. | |
| * | |
| * @param params - Standard MCP `CreateMessageRequest` params (messages, maxTokens, | |
| * systemPrompt, temperature, modelPreferences, tools, toolChoice, etc.) | |
| * @param options - Request options (timeout, abort signal) | |
| * @returns `CreateMessageResult` (single content block) or `CreateMessageResultWithTools` | |
| * (array content, may include `tool_use` blocks) depending on whether `tools` was set | |
| * | |
| * @throws {Error} If the host rejects the request or does not support sampling | |
| * @throws {Error} If the request times out or the connection is lost | |
| * | |
| * @example Simple completion | |
| * ```ts source="./app.examples.ts#App_createSamplingMessage_simple" | |
| * const result = await app.createSamplingMessage({ | |
| * messages: [ | |
| * { | |
| * role: "user", | |
| * content: { type: "text", text: "Summarize this in one line." }, | |
| * }, | |
| * ], | |
| * maxTokens: 100, | |
| * }); | |
| * console.log(result.content); | |
| * ``` | |
| * | |
| * @example Agentic loop with tools | |
| * ```ts source="./app.examples.ts#App_createSamplingMessage_withTools" | |
| * if (!app.getHostCapabilities()?.sampling?.tools) return; | |
| * | |
| * const result = await app.createSamplingMessage({ | |
| * messages, | |
| * maxTokens: 1024, | |
| * tools: [ | |
| * { | |
| * name: "get_weather", | |
| * description: "Get the current weather", | |
| * inputSchema: { | |
| * type: "object", | |
| * properties: { city: { type: "string" } }, | |
| * }, | |
| * }, | |
| * ], | |
| * }); | |
| * if (result.stopReason === "toolUse") { | |
| * // result.content may be an array containing tool_use blocks | |
| * } | |
| * ``` | |
| * | |
| * @see `CreateMessageRequest` from @modelcontextprotocol/sdk for the request type | |
| * @see `CreateMessageResult` / `CreateMessageResultWithTools` from @modelcontextprotocol/sdk for result types | |
| */ | |
| createSamplingMessage(params: CreateMessageRequest["params"] & { | |
| tools?: undefined; | |
| }, options?: RequestOptions): Promise<CreateMessageResult>; | |
| createSamplingMessage(params: CreateMessageRequest["params"], options?: RequestOptions): Promise<CreateMessageResultWithTools>; | |
| /** | |
| * Send a message to the host's chat interface. | |
| * | |
| * Enables the app to add messages to the conversation thread. Useful for | |
| * user-initiated messages or app-to-conversation communication. | |
| * | |
| * @param params - Message role and content | |
| * @param options - Request options (timeout, etc.) | |
| * @returns Result with optional `isError` flag indicating host rejection | |
| * | |
| * @throws {Error} If the request times out or the connection is lost | |
| * | |
| * @example Send a text message from user interaction | |
| * ```ts source="./app.examples.ts#App_sendMessage_textFromInteraction" | |
| * try { | |
| * const result = await app.sendMessage({ | |
| * role: "user", | |
| * 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 transport/protocol error | |
| * } | |
| * ``` | |
| * | |
| * @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 | |
| */ | |
| sendMessage(params: McpUiMessageRequest["params"], options?: RequestOptions): Promise<{ | |
| [x: string]: unknown; | |
| isError?: boolean | undefined; | |
| }>; | |
| /** | |
| * Send log messages to the host for debugging and telemetry. | |
| * | |
| * Logs are not added to the conversation but may be recorded by the host | |
| * for debugging purposes. | |
| * | |
| * @param params - Log level and message | |
| * | |
| * @example Log app state for debugging | |
| * ```ts source="./app.examples.ts#App_sendLog_debugState" | |
| * app.sendLog({ | |
| * level: "info", | |
| * data: "Weather data refreshed", | |
| * logger: "WeatherApp", | |
| * }); | |
| * ``` | |
| * | |
| * @returns Promise that resolves when the log notification is sent | |
| */ | |
| sendLog(params: LoggingMessageNotification["params"]): Promise<void>; | |
| /** | |
| * Update the host's model context with app state. | |
| * | |
| * 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 — either from the actual user or via `sendMessage`. Only | |
| * the last update is sent; each call overwrites any previous context. | |
| * | |
| * @param params - Context content and/or structured content | |
| * @param options - Request options (timeout, etc.) | |
| * | |
| * @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 | |
| * ```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: markdown }], | |
| * }); | |
| * ``` | |
| * | |
| * @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", | |
| * }, | |
| * ], | |
| * }); | |
| * } | |
| * ``` | |
| * | |
| * @returns Promise that resolves when the context update is acknowledged | |
| */ | |
| updateModelContext(params: McpUiUpdateModelContextRequest["params"], options?: RequestOptions): Promise<{ | |
| _meta?: { | |
| [x: string]: unknown; | |
| progressToken?: string | number | undefined; | |
| "io.modelcontextprotocol/related-task"?: { | |
| taskId: string; | |
| } | undefined; | |
| } | undefined; | |
| }>; | |
| /** | |
| * Request the host to open an external URL in the default browser. | |
| * | |
| * The host may deny this request based on user preferences or security policy. | |
| * Apps should handle rejection gracefully by checking `result.isError`. | |
| * | |
| * @param params - URL to open | |
| * @param options - Request options (timeout, etc.) | |
| * @returns Result with `isError: true` if the host denied the request (e.g., blocked domain, user cancelled) | |
| * | |
| * @throws {Error} If the request times out or the connection is lost | |
| * | |
| * @example Open documentation link | |
| * ```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 `McpUiOpenLinkRequest`} for request structure | |
| * @see {@link McpUiOpenLinkResult `McpUiOpenLinkResult`} for result structure | |
| */ | |
| openLink(params: McpUiOpenLinkRequest["params"], options?: RequestOptions): Promise<{ | |
| [x: string]: unknown; | |
| isError?: boolean | undefined; | |
| }>; | |
| /** @deprecated Use {@link openLink `openLink`} instead */ | |
| sendOpenLink: App["openLink"]; | |
| /** | |
| * Request the host to download a file. | |
| * | |
| * Since MCP Apps run in sandboxed iframes where direct downloads are blocked, | |
| * this provides a host-mediated mechanism for file exports. The host will | |
| * typically show a confirmation dialog before initiating the download. | |
| * | |
| * Uses standard MCP resource types: `EmbeddedResource` for inline content | |
| * and `ResourceLink` for content the host can fetch directly. | |
| * | |
| * @param params - Resource contents to download | |
| * @param options - Request options (timeout, etc.) | |
| * @returns Result with `isError: true` if the host denied the request (e.g., user cancelled) | |
| * | |
| * @throws {Error} If the request times out or the connection is lost | |
| * | |
| * @example Download a JSON file (embedded text resource) | |
| * ```ts | |
| * const data = JSON.stringify({ items: selectedItems }, null, 2); | |
| * const { isError } = await app.downloadFile({ | |
| * contents: [{ | |
| * type: "resource", | |
| * resource: { | |
| * uri: "file:///export.json", | |
| * mimeType: "application/json", | |
| * text: data, | |
| * }, | |
| * }], | |
| * }); | |
| * if (isError) { | |
| * console.warn("Download denied or cancelled"); | |
| * } | |
| * ``` | |
| * | |
| * @example Download binary content (embedded blob resource) | |
| * ```ts | |
| * const { isError } = await app.downloadFile({ | |
| * contents: [{ | |
| * type: "resource", | |
| * resource: { | |
| * uri: "file:///image.png", | |
| * mimeType: "image/png", | |
| * blob: base64EncodedPng, | |
| * }, | |
| * }], | |
| * }); | |
| * ``` | |
| * | |
| * @example Download via resource link (host fetches) | |
| * ```ts | |
| * const { isError } = await app.downloadFile({ | |
| * contents: [{ | |
| * type: "resource_link", | |
| * uri: "https://api.example.com/reports/q4.pdf", | |
| * name: "Q4 Report", | |
| * mimeType: "application/pdf", | |
| * }], | |
| * }); | |
| * ``` | |
| * | |
| * @see {@link McpUiDownloadFileRequest `McpUiDownloadFileRequest`} for request structure | |
| * @see {@link McpUiDownloadFileResult `McpUiDownloadFileResult`} for result structure | |
| */ | |
| downloadFile(params: McpUiDownloadFileRequest["params"], options?: RequestOptions): Promise<{ | |
| [x: string]: unknown; | |
| isError?: boolean | undefined; | |
| }>; | |
| /** | |
| * Request the host to tear down this app. | |
| * | |
| * Apps call this method to request that the host tear them down. The host | |
| * decides whether to proceed - if approved, the host will send | |
| * `ui/resource-teardown` to allow the app to perform gracefull termination before being | |
| * unmounted. This piggybacks on the existing teardown mechanism, ensuring | |
| * the app only needs a single shutdown procedure (via {@link onteardown `onteardown`}) | |
| * regardless of whether the teardown was initiated by the app or the host. | |
| * | |
| * This is a fire-and-forget notification - no response is expected. | |
| * If the host approves, the app will receive a `ui/resource-teardown` | |
| * request via the {@link onteardown `onteardown`} handler to persist unsaved state. | |
| * | |
| * @param params - Empty params object (reserved for future use) | |
| * @returns Promise that resolves when the notification is sent | |
| * | |
| * @example App-initiated teardown after user action | |
| * ```typescript | |
| * // User clicks "Done" button in the app | |
| * async function handleDoneClick() { | |
| * // Request the host to tear down the app | |
| * await app.requestTeardown(); | |
| * // If host approves, onteardown handler will be called for termination | |
| * } | |
| * | |
| * // Set up teardown handler (called for both app-initiated and host-initiated teardown) | |
| * app.onteardown = async () => { | |
| * await saveState(); | |
| * closeConnections(); | |
| * return {}; | |
| * }; | |
| * ``` | |
| * | |
| * @see {@link McpUiRequestTeardownNotification `McpUiRequestTeardownNotification`} for notification structure | |
| * @see {@link onteardown `onteardown`} for the graceful termination handler | |
| */ | |
| requestTeardown(params?: McpUiRequestTeardownNotification["params"]): Promise<void>; | |
| /** | |
| * Request a change to the display mode. | |
| * | |
| * Requests the host to change the UI container to the specified display mode | |
| * (e.g., "inline", "fullscreen", "pip"). The host will respond with the actual | |
| * display mode that was set, which may differ from the requested mode if | |
| * the requested mode is not available (check `availableDisplayModes` in host context). | |
| * | |
| * @param params - The display mode being requested | |
| * @param options - Request options (timeout, etc.) | |
| * @returns Result containing the actual display mode that was set | |
| * | |
| * @example Toggle display mode | |
| * ```ts source="./app.examples.ts#App_requestDisplayMode_toggle" | |
| * const container = document.getElementById("main")!; | |
| * const ctx = app.getHostContext(); | |
| * const newMode = ctx?.displayMode === "inline" ? "fullscreen" : "inline"; | |
| * if (ctx?.availableDisplayModes?.includes(newMode)) { | |
| * const result = await app.requestDisplayMode({ mode: newMode }); | |
| * container.classList.toggle("fullscreen", result.mode === "fullscreen"); | |
| * } | |
| * ``` | |
| * | |
| * @see {@link McpUiRequestDisplayModeRequest `McpUiRequestDisplayModeRequest`} for request structure | |
| * @see {@link McpUiHostContext `McpUiHostContext`} for checking availableDisplayModes | |
| */ | |
| requestDisplayMode(params: McpUiRequestDisplayModeRequest["params"], options?: RequestOptions): Promise<{ | |
| [x: string]: unknown; | |
| mode: "inline" | "fullscreen" | "pip"; | |
| }>; | |
| /** | |
| * Notify the host of UI size changes. | |
| * | |
| * Apps can manually report size changes to help the host adjust the container. | |
| * If `autoResize` is enabled (default), this is called automatically. | |
| * | |
| * @param params - New width and height in pixels | |
| * | |
| * @example Manually notify host of size change | |
| * ```ts source="./app.examples.ts#App_sendSizeChanged_manual" | |
| * app.sendSizeChanged({ | |
| * width: 400, | |
| * height: 600, | |
| * }); | |
| * ``` | |
| * | |
| * @returns Promise that resolves when the notification is sent | |
| * | |
| * @see {@link McpUiSizeChangedNotification `McpUiSizeChangedNotification`} for notification structure | |
| */ | |
| sendSizeChanged(params: McpUiSizeChangedNotification["params"]): Promise<void>; | |
| /** | |
| * Set up automatic size change notifications using ResizeObserver. | |
| * | |
| * Observes both `document.documentElement` and `document.body` for size changes | |
| * and automatically sends `ui/notifications/size-changed` notifications to the host. | |
| * The notifications are debounced using requestAnimationFrame to avoid duplicates. | |
| * | |
| * Note: This method is automatically called by `connect()` if the `autoResize` | |
| * option is true (default). You typically don't need to call this manually unless | |
| * you disabled autoResize and want to enable it later. | |
| * | |
| * @returns Cleanup function to disconnect the observer | |
| * | |
| * @example Manual setup for custom scenarios | |
| * ```ts source="./app.examples.ts#App_setupAutoResize_manual" | |
| * const app = new App( | |
| * { name: "MyApp", version: "1.0.0" }, | |
| * {}, | |
| * { autoResize: false }, | |
| * ); | |
| * await app.connect(transport); | |
| * | |
| * // Later, enable auto-resize manually | |
| * const cleanup = app.setupSizeChangedNotifications(); | |
| * | |
| * // Clean up when done | |
| * cleanup(); | |
| * ``` | |
| */ | |
| setupSizeChangedNotifications(): () => void; | |
| /** | |
| * Establish connection with the host and perform initialization handshake. | |
| * | |
| * This method performs the following steps: | |
| * 1. Connects the transport layer | |
| * 2. Sends `ui/initialize` request with app info and capabilities | |
| * 3. Receives host capabilities and context in response | |
| * 4. Sends `ui/notifications/initialized` notification | |
| * 5. Sets up auto-resize using {@link setupSizeChangedNotifications `setupSizeChangedNotifications`} if enabled (default) | |
| * | |
| * If initialization fails, the connection is automatically closed and an error | |
| * is thrown. | |
| * | |
| * @param transport - Transport layer (typically {@link PostMessageTransport `PostMessageTransport`}) | |
| * @param options - Request options for the initialize request | |
| * | |
| * @throws {Error} If initialization fails or connection is lost | |
| * | |
| * @example Connect with PostMessageTransport | |
| * ```ts source="./app.examples.ts#App_connect_withPostMessageTransport" | |
| * const app = new App({ name: "MyApp", version: "1.0.0" }, {}); | |
| * | |
| * try { | |
| * await app.connect(new PostMessageTransport(window.parent, window.parent)); | |
| * console.log("Connected successfully!"); | |
| * } catch (error) { | |
| * console.error("Failed to connect:", error); | |
| * } | |
| * ``` | |
| * | |
| * @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>; | |
| } | |