Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@modelcontextprotocol/ext-apps

Package Overview
Dependencies
Maintainers
6
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@modelcontextprotocol/ext-apps - npm Package Compare versions

Comparing version
1.3.2
to
1.4.0
+130
dist/src/events.d.ts
import { Protocol } from "@modelcontextprotocol/sdk/shared/protocol.js";
import { Request, Notification, Result } from "@modelcontextprotocol/sdk/types.js";
import { ZodLiteral, ZodObject } from "zod/v4";
type MethodSchema = ZodObject<{
method: ZodLiteral<string>;
}>;
/**
* Intermediate base class that adds DOM-style event support on top of the
* MCP SDK's `Protocol`.
*
* The base `Protocol` class stores one handler per method:
* `setRequestHandler()` and `setNotificationHandler()` replace any existing
* handler for the same method silently. This class introduces a two-channel
* event model inspired by the DOM:
*
* ### Singular `on*` handler (like `el.onclick`)
*
* Subclasses expose `get`/`set` pairs that delegate to
* {@link setEventHandler `setEventHandler`} /
* {@link getEventHandler `getEventHandler`}. Assigning replaces the previous
* handler; assigning `undefined` clears it. `addEventListener` listeners are
* unaffected.
*
* ### Multi-listener (`addEventListener` / `removeEventListener`)
*
* Append to a per-event listener array. Listeners fire in insertion order
* after the singular `on*` handler.
*
* ### Dispatch order
*
* When a notification arrives for a mapped event:
* 1. {@link onEventDispatch `onEventDispatch`} (subclass side-effects)
* 2. The singular `on*` handler (if set)
* 3. All `addEventListener` listeners in insertion order
*
* ### Double-set protection
*
* Direct calls to {@link setRequestHandler `setRequestHandler`} /
* {@link setNotificationHandler `setNotificationHandler`} throw if a handler
* for the same method has already been registered (through any path), so
* accidental overwrites surface as errors instead of silent bugs.
*
* @typeParam EventMap - Maps event names to the listener's `params` type.
*/
export declare abstract class ProtocolWithEvents<SendRequestT extends Request, SendNotificationT extends Notification, SendResultT extends Result, EventMap extends Record<string, unknown>> extends Protocol<SendRequestT, SendNotificationT, SendResultT> {
private _registeredMethods;
private _eventSlots;
/**
* Event name → notification schema. Subclasses populate this so that
* the event system can lazily register a dispatcher with the correct
* schema on first use.
*/
protected abstract readonly eventSchemas: {
[K in keyof EventMap]: MethodSchema;
};
/**
* Called once per incoming notification, before any handlers or listeners
* fire. Subclasses may override to perform side effects such as merging
* notification params into cached state.
*/
protected onEventDispatch<K extends keyof EventMap>(_event: K, _params: EventMap[K]): void;
/**
* Lazily create the event slot and register a single dispatcher with the
* base `Protocol`. The dispatcher fans out to the `on*` handler and all
* `addEventListener` listeners.
*/
private _ensureEventSlot;
/**
* Set or clear the singular `on*` handler for an event.
*
* Replace semantics — like the DOM's `el.onclick = fn`. Assigning
* `undefined` clears the handler without affecting `addEventListener`
* listeners.
*/
protected setEventHandler<K extends keyof EventMap>(event: K, handler: ((params: EventMap[K]) => void) | undefined): void;
/**
* Get the singular `on*` handler for an event, or `undefined` if none is
* set. `addEventListener` listeners are not reflected here.
*/
protected getEventHandler<K extends keyof EventMap>(event: K): ((params: EventMap[K]) => void) | undefined;
/**
* Add a listener for a notification event.
*
* Unlike the singular `on*` handler, calling this multiple times appends
* listeners rather than replacing them. All registered listeners fire in
* insertion order after the `on*` handler when the notification arrives.
*
* Registration is lazy: the first call (for a given event, from either
* this method or the `on*` setter) registers a dispatcher with the base
* `Protocol`.
*
* @param event - Event name (a key of the `EventMap` type parameter).
* @param handler - Listener invoked with the notification `params`.
*/
addEventListener<K extends keyof EventMap>(event: K, handler: (params: EventMap[K]) => void): void;
/**
* Remove a previously registered event listener. The dispatcher stays
* registered even if the listener array becomes empty; future
* notifications simply have no listeners to call.
*/
removeEventListener<K extends keyof EventMap>(event: K, handler: (params: EventMap[K]) => void): void;
/**
* Registers a request handler. Throws if a handler for the same method
* has already been registered — use the `on*` setter (replace semantics)
* or `addEventListener` (multi-listener) for notification events.
*
* @throws {Error} if a handler for this method is already registered.
*/
setRequestHandler: Protocol<SendRequestT, SendNotificationT, SendResultT>["setRequestHandler"];
/**
* Registers a notification handler. Throws if a handler for the same
* method has already been registered — use the `on*` setter (replace
* semantics) or `addEventListener` (multi-listener) for mapped events.
*
* @throws {Error} if a handler for this method is already registered.
*/
setNotificationHandler: Protocol<SendRequestT, SendNotificationT, SendResultT>["setNotificationHandler"];
/**
* Warn if a request handler `on*` setter is replacing a previously-set
* handler. Call from each request setter before updating the backing field.
*/
protected warnIfRequestHandlerReplaced(name: string, previous: unknown, next: unknown): void;
/**
* Replace a request handler, bypassing double-set protection. Used by
* `on*` request-handler setters that need replace semantics.
*/
protected replaceRequestHandler: Protocol<SendRequestT, SendNotificationT, SendResultT>["setRequestHandler"];
private _assertMethodNotRegistered;
}
export {};
+257
-25
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
import { CallToolRequest, CallToolResult, EmptyResult, Implementation, ListPromptsRequest, ListPromptsResult, ListResourcesRequest, ListResourcesResult, ListResourceTemplatesRequest, ListResourceTemplatesResult, LoggingMessageNotification, PingRequest, PromptListChangedNotification, ReadResourceRequest, ReadResourceResult, ResourceListChangedNotification, Tool, ToolListChangedNotification } from "@modelcontextprotocol/sdk/types.js";
import { Protocol, ProtocolOptions, RequestOptions } from "@modelcontextprotocol/sdk/shared/protocol.js";
import { CallToolRequest, CallToolResult, EmptyResult, Implementation, ListPromptsRequest, ListPromptsResult, ListResourcesRequest, ListResourcesResult, ListResourceTemplatesRequest, ListResourceTemplatesResult, ListToolsRequest, LoggingMessageNotification, PingRequest, PromptListChangedNotification, ReadResourceRequest, ReadResourceResult, ResourceListChangedNotification, Tool, ToolListChangedNotification } from "@modelcontextprotocol/sdk/types.js";
import { ProtocolOptions, RequestOptions } from "@modelcontextprotocol/sdk/shared/protocol.js";
import { ProtocolWithEvents } from "./events";
import { type AppNotification, type AppRequest, type AppResult, type McpUiSandboxResourceReadyNotification, type McpUiSizeChangedNotification, type McpUiToolCancelledNotification, type McpUiToolInputNotification, type McpUiToolInputPartialNotification, type McpUiToolResultNotification, McpUiAppCapabilities, McpUiUpdateModelContextRequest, McpUiHostCapabilities, McpUiHostContext, McpUiHostContextChangedNotification, McpUiInitializedNotification, McpUiMessageRequest, McpUiMessageResult, McpUiOpenLinkRequest, McpUiOpenLinkResult, McpUiDownloadFileRequest, McpUiDownloadFileResult, McpUiResourceTeardownRequest, McpUiRequestTeardownNotification, McpUiSandboxProxyReadyNotification, McpUiRequestDisplayModeRequest, McpUiRequestDisplayModeResult, McpUiResourcePermissions } from "./types";

@@ -94,2 +95,16 @@ export * from "./types";

/**
* Maps DOM-style event names to their notification `params` types.
*
* Used by {@link AppBridge `AppBridge`} to provide type-safe
* `addEventListener` / `removeEventListener` and singular `on*` handler
* support.
*/
export type AppBridgeEventMap = {
sizechange: McpUiSizeChangedNotification["params"];
sandboxready: McpUiSandboxProxyReadyNotification["params"];
initialized: McpUiInitializedNotification["params"];
requestteardown: McpUiRequestTeardownNotification["params"];
loggingmessage: LoggingMessageNotification["params"];
};
/**
* Host-side bridge for communicating with a single View ({@link app!App `App`}).

@@ -151,3 +166,3 @@ *

*/
export declare class AppBridge extends Protocol<AppRequest, AppNotification, AppResult> {
export declare class AppBridge extends ProtocolWithEvents<AppRequest, AppNotification, AppResult, AppBridgeEventMap> {
private _client;

@@ -159,2 +174,46 @@ private _hostInfo;

private _appInfo?;
protected readonly eventSchemas: {
sizechange: import("zod").ZodObject<{
method: import("zod").ZodLiteral<"ui/notifications/size-changed">;
params: import("zod").ZodObject<{
width: import("zod").ZodOptional<import("zod").ZodNumber>;
height: import("zod").ZodOptional<import("zod").ZodNumber>;
}, import("zod/v4/core").$strip>;
}, import("zod/v4/core").$strip>;
sandboxready: import("zod").ZodObject<{
method: import("zod").ZodLiteral<"ui/notifications/sandbox-proxy-ready">;
params: import("zod").ZodObject<{}, import("zod/v4/core").$strip>;
}, import("zod/v4/core").$strip>;
initialized: import("zod").ZodObject<{
method: import("zod").ZodLiteral<"ui/notifications/initialized">;
params: import("zod").ZodOptional<import("zod").ZodObject<{}, import("zod/v4/core").$strip>>;
}, import("zod/v4/core").$strip>;
requestteardown: import("zod").ZodObject<{
method: import("zod").ZodLiteral<"ui/notifications/request-teardown">;
params: import("zod").ZodOptional<import("zod").ZodObject<{}, import("zod/v4/core").$strip>>;
}, import("zod/v4/core").$strip>;
loggingmessage: import("zod").ZodObject<{
method: import("zod").ZodLiteral<"notifications/message">;
params: import("zod").ZodObject<{
_meta: import("zod").ZodOptional<import("zod").ZodObject<{
progressToken: import("zod").ZodOptional<import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>>;
"io.modelcontextprotocol/related-task": import("zod").ZodOptional<import("zod").ZodObject<{
taskId: import("zod").ZodString;
}, import("zod/v4/core").$strip>>;
}, import("zod/v4/core").$loose>>;
level: import("zod").ZodEnum<{
error: "error";
debug: "debug";
info: "info";
notice: "notice";
warning: "warning";
critical: "critical";
alert: "alert";
emergency: "emergency";
}>;
logger: import("zod").ZodOptional<import("zod").ZodString>;
data: import("zod").ZodUnknown;
}, import("zod/v4/core").$strip>;
}, import("zod/v4/core").$strip>;
};
/**

@@ -280,4 +339,6 @@ * Create a new AppBridge instance.

* @see {@link app!App.sendSizeChanged `App.sendSizeChanged`} - the View method that sends these notifications
* @deprecated Use {@link addEventListener `addEventListener("sizechange", handler)`} instead — it composes with other listeners and supports cleanup via {@link removeEventListener `removeEventListener`}.
*/
set onsizechange(callback: (params: McpUiSizeChangedNotification["params"]) => void);
get onsizechange(): ((params: McpUiSizeChangedNotification["params"]) => void) | undefined;
set onsizechange(callback: ((params: McpUiSizeChangedNotification["params"]) => void) | undefined);
/**

@@ -312,4 +373,6 @@ * Register a handler for sandbox proxy ready notifications.

* @see {@link sendSandboxResourceReady `sendSandboxResourceReady`} for sending content to the sandbox
* @deprecated Use {@link addEventListener `addEventListener("sandboxready", handler)`} instead — it composes with other listeners and supports cleanup via {@link removeEventListener `removeEventListener`}.
*/
set onsandboxready(callback: (params: McpUiSandboxProxyReadyNotification["params"]) => void);
get onsandboxready(): ((params: McpUiSandboxProxyReadyNotification["params"]) => void) | undefined;
set onsandboxready(callback: ((params: McpUiSandboxProxyReadyNotification["params"]) => void) | undefined);
/**

@@ -331,4 +394,6 @@ * Called when the view completes initialization.

* @see {@link sendToolInput `sendToolInput`} for sending tool arguments to the View
* @deprecated Use {@link addEventListener `addEventListener("initialized", handler)`} instead — it composes with other listeners and supports cleanup via {@link removeEventListener `removeEventListener`}.
*/
set oninitialized(callback: (params: McpUiInitializedNotification["params"]) => void);
get oninitialized(): ((params: McpUiInitializedNotification["params"]) => void) | undefined;
set oninitialized(callback: ((params: McpUiInitializedNotification["params"]) => void) | undefined);
/**

@@ -368,3 +433,5 @@ * Register a handler for message requests from the view.

*/
set onmessage(callback: (params: McpUiMessageRequest["params"], extra: RequestHandlerExtra) => Promise<McpUiMessageResult>);
private _onmessage?;
get onmessage(): ((params: McpUiMessageRequest["params"], extra: RequestHandlerExtra) => Promise<McpUiMessageResult>) | undefined;
set onmessage(callback: ((params: McpUiMessageRequest["params"], extra: RequestHandlerExtra) => Promise<McpUiMessageResult>) | undefined);
/**

@@ -413,3 +480,5 @@ * Register a handler for external link requests from the view.

*/
set onopenlink(callback: (params: McpUiOpenLinkRequest["params"], extra: RequestHandlerExtra) => Promise<McpUiOpenLinkResult>);
private _onopenlink?;
get onopenlink(): ((params: McpUiOpenLinkRequest["params"], extra: RequestHandlerExtra) => Promise<McpUiOpenLinkResult>) | undefined;
set onopenlink(callback: ((params: McpUiOpenLinkRequest["params"], extra: RequestHandlerExtra) => Promise<McpUiOpenLinkResult>) | undefined);
/**

@@ -457,3 +526,5 @@ * Register a handler for file download requests from the View.

*/
set ondownloadfile(callback: (params: McpUiDownloadFileRequest["params"], extra: RequestHandlerExtra) => Promise<McpUiDownloadFileResult>);
private _ondownloadfile?;
get ondownloadfile(): ((params: McpUiDownloadFileRequest["params"], extra: RequestHandlerExtra) => Promise<McpUiDownloadFileResult>) | undefined;
set ondownloadfile(callback: ((params: McpUiDownloadFileRequest["params"], extra: RequestHandlerExtra) => Promise<McpUiDownloadFileResult>) | undefined);
/**

@@ -467,5 +538,2 @@ * Register a handler for app-initiated teardown request notifications from the view.

*
* @param callback - Handler that receives teardown request params
* - params - Empty object (reserved for future use)
*
* @example

@@ -485,4 +553,6 @@ * ```typescript

* @see {@link teardownResource `teardownResource`} for initiating teardown
* @deprecated Use {@link addEventListener `addEventListener("requestteardown", handler)`} instead — it composes with other listeners and supports cleanup via {@link removeEventListener `removeEventListener`}.
*/
set onrequestteardown(callback: (params: McpUiRequestTeardownNotification["params"]) => void);
get onrequestteardown(): ((params: McpUiRequestTeardownNotification["params"]) => void) | undefined;
set onrequestteardown(callback: ((params: McpUiRequestTeardownNotification["params"]) => void) | undefined);
/**

@@ -520,3 +590,5 @@ * Register a handler for display mode change requests from the view.

*/
set onrequestdisplaymode(callback: (params: McpUiRequestDisplayModeRequest["params"], extra: RequestHandlerExtra) => Promise<McpUiRequestDisplayModeResult>);
private _onrequestdisplaymode?;
get onrequestdisplaymode(): ((params: McpUiRequestDisplayModeRequest["params"], extra: RequestHandlerExtra) => Promise<McpUiRequestDisplayModeResult>) | undefined;
set onrequestdisplaymode(callback: ((params: McpUiRequestDisplayModeRequest["params"], extra: RequestHandlerExtra) => Promise<McpUiRequestDisplayModeResult>) | undefined);
/**

@@ -533,6 +605,6 @@ * Register a handler for logging messages from the view.

*
* @param callback - Handler that receives logging params
* - `params.level` - Log level: "debug" | "info" | "notice" | "warning" | "error" | "critical" | "alert" | "emergency"
* - `params.logger` - Optional logger name/identifier
* - `params.data` - Log message and optional structured data
* The handler receives `LoggingMessageNotification["params"]`:
* - `level` — "debug" | "info" | "notice" | "warning" | "error" | "critical" | "alert" | "emergency"
* - `logger` — optional logger name/identifier
* - `data` — log message and optional structured data
*

@@ -548,4 +620,6 @@ * @example

* ```
* @deprecated Use {@link addEventListener `addEventListener("loggingmessage", handler)`} instead — it composes with other listeners and supports cleanup via {@link removeEventListener `removeEventListener`}.
*/
set onloggingmessage(callback: (params: LoggingMessageNotification["params"]) => void);
get onloggingmessage(): ((params: LoggingMessageNotification["params"]) => void) | undefined;
set onloggingmessage(callback: ((params: LoggingMessageNotification["params"]) => void) | undefined);
/**

@@ -577,3 +651,5 @@ * Register a handler for model context updates from the view.

*/
set onupdatemodelcontext(callback: (params: McpUiUpdateModelContextRequest["params"], extra: RequestHandlerExtra) => Promise<EmptyResult>);
private _onupdatemodelcontext?;
get onupdatemodelcontext(): ((params: McpUiUpdateModelContextRequest["params"], extra: RequestHandlerExtra) => Promise<EmptyResult>) | undefined;
set onupdatemodelcontext(callback: ((params: McpUiUpdateModelContextRequest["params"], extra: RequestHandlerExtra) => Promise<EmptyResult>) | undefined);
/**

@@ -605,3 +681,5 @@ * Register a handler for tool call requests from the view.

*/
set oncalltool(callback: (params: CallToolRequest["params"], extra: RequestHandlerExtra) => Promise<CallToolResult>);
private _oncalltool?;
get oncalltool(): ((params: CallToolRequest["params"], extra: RequestHandlerExtra) => Promise<CallToolResult>) | undefined;
set oncalltool(callback: ((params: CallToolRequest["params"], extra: RequestHandlerExtra) => Promise<CallToolResult>) | undefined);
/**

@@ -653,3 +731,5 @@ * Notify the view that the MCP server's tool list has changed.

*/
set onlistresources(callback: (params: ListResourcesRequest["params"], extra: RequestHandlerExtra) => Promise<ListResourcesResult>);
private _onlistresources?;
get onlistresources(): ((params: ListResourcesRequest["params"], extra: RequestHandlerExtra) => Promise<ListResourcesResult>) | undefined;
set onlistresources(callback: ((params: ListResourcesRequest["params"], extra: RequestHandlerExtra) => Promise<ListResourcesResult>) | undefined);
/**

@@ -681,3 +761,5 @@ * Register a handler for list resource templates requests from the view.

*/
set onlistresourcetemplates(callback: (params: ListResourceTemplatesRequest["params"], extra: RequestHandlerExtra) => Promise<ListResourceTemplatesResult>);
private _onlistresourcetemplates?;
get onlistresourcetemplates(): ((params: ListResourceTemplatesRequest["params"], extra: RequestHandlerExtra) => Promise<ListResourceTemplatesResult>) | undefined;
set onlistresourcetemplates(callback: ((params: ListResourceTemplatesRequest["params"], extra: RequestHandlerExtra) => Promise<ListResourceTemplatesResult>) | undefined);
/**

@@ -709,3 +791,5 @@ * Register a handler for read resource requests from the view.

*/
set onreadresource(callback: (params: ReadResourceRequest["params"], extra: RequestHandlerExtra) => Promise<ReadResourceResult>);
private _onreadresource?;
get onreadresource(): ((params: ReadResourceRequest["params"], extra: RequestHandlerExtra) => Promise<ReadResourceResult>) | undefined;
set onreadresource(callback: ((params: ReadResourceRequest["params"], extra: RequestHandlerExtra) => Promise<ReadResourceResult>) | undefined);
/**

@@ -757,3 +841,5 @@ * Notify the view that the MCP server's resource list has changed.

*/
set onlistprompts(callback: (params: ListPromptsRequest["params"], extra: RequestHandlerExtra) => Promise<ListPromptsResult>);
private _onlistprompts?;
get onlistprompts(): ((params: ListPromptsRequest["params"], extra: RequestHandlerExtra) => Promise<ListPromptsResult>) | undefined;
set onlistprompts(callback: ((params: ListPromptsRequest["params"], extra: RequestHandlerExtra) => Promise<ListPromptsResult>) | undefined);
/**

@@ -1011,2 +1097,148 @@ * Notify the view that the MCP server's prompt list has changed.

/**
* Call a tool on the view.
*
* Sends a `tools/call` request to the view and returns the result.
*
* @param params - Tool call parameters (name and arguments)
* @param options - Request options (timeout, abort signal, etc.)
* @returns Promise resolving to the tool call result
*/
callTool(params: CallToolRequest["params"], options?: RequestOptions): Promise<{
[x: string]: unknown;
content: ({
type: "text";
text: string;
annotations?: {
audience?: ("user" | "assistant")[] | undefined;
priority?: number | undefined;
lastModified?: string | undefined;
} | undefined;
_meta?: Record<string, unknown> | undefined;
} | {
type: "image";
data: string;
mimeType: string;
annotations?: {
audience?: ("user" | "assistant")[] | undefined;
priority?: number | undefined;
lastModified?: string | undefined;
} | undefined;
_meta?: Record<string, unknown> | undefined;
} | {
type: "audio";
data: string;
mimeType: string;
annotations?: {
audience?: ("user" | "assistant")[] | undefined;
priority?: number | undefined;
lastModified?: string | undefined;
} | undefined;
_meta?: Record<string, unknown> | undefined;
} | {
uri: string;
name: string;
type: "resource_link";
description?: string | undefined;
mimeType?: string | undefined;
size?: number | undefined;
annotations?: {
audience?: ("user" | "assistant")[] | undefined;
priority?: number | undefined;
lastModified?: string | undefined;
} | undefined;
_meta?: {
[x: string]: unknown;
} | undefined;
icons?: {
src: string;
mimeType?: string | undefined;
sizes?: string[] | undefined;
theme?: "light" | "dark" | undefined;
}[] | undefined;
title?: string | undefined;
} | {
type: "resource";
resource: {
uri: string;
text: string;
mimeType?: string | undefined;
_meta?: Record<string, unknown> | undefined;
} | {
uri: string;
blob: string;
mimeType?: string | undefined;
_meta?: Record<string, unknown> | undefined;
};
annotations?: {
audience?: ("user" | "assistant")[] | undefined;
priority?: number | undefined;
lastModified?: string | undefined;
} | undefined;
_meta?: Record<string, unknown> | undefined;
})[];
_meta?: {
[x: string]: unknown;
progressToken?: string | number | undefined;
"io.modelcontextprotocol/related-task"?: {
taskId: string;
} | undefined;
} | undefined;
structuredContent?: Record<string, unknown> | undefined;
isError?: boolean | undefined;
}>;
/**
* List tools available on the view.
*
* Sends a `tools/list` request to the view and returns the result.
*
* @param params - List tools parameters (may include cursor for pagination)
* @param options - Request options (timeout, abort signal, etc.)
* @returns Promise resolving to the list of tools
*/
listTools(params: ListToolsRequest["params"], options?: RequestOptions): Promise<{
[x: string]: unknown;
tools: {
inputSchema: {
[x: string]: unknown;
type: "object";
properties?: Record<string, object> | undefined;
required?: string[] | undefined;
};
name: string;
description?: string | undefined;
outputSchema?: {
[x: string]: unknown;
type: "object";
properties?: Record<string, object> | undefined;
required?: string[] | undefined;
} | undefined;
annotations?: {
title?: string | undefined;
readOnlyHint?: boolean | undefined;
destructiveHint?: boolean | undefined;
idempotentHint?: boolean | undefined;
openWorldHint?: boolean | undefined;
} | undefined;
execution?: {
taskSupport?: "optional" | "required" | "forbidden" | undefined;
} | undefined;
_meta?: Record<string, unknown> | undefined;
icons?: {
src: string;
mimeType?: string | undefined;
sizes?: string[] | undefined;
theme?: "light" | "dark" | undefined;
}[] | undefined;
title?: string | undefined;
}[];
_meta?: {
[x: string]: unknown;
progressToken?: string | number | undefined;
"io.modelcontextprotocol/related-task"?: {
taskId: string;
} | undefined;
} | undefined;
nextCursor?: string | undefined;
}>;
/**
* Connect to the view via transport and optionally set up message forwarding.

@@ -1013,0 +1245,0 @@ *

+6
-6

@@ -1,2 +0,2 @@

import{CallToolRequestSchema as CQ,CallToolResultSchema as SQ,ListPromptsRequestSchema as qQ,ListPromptsResultSchema as yQ,ListResourcesRequestSchema as kQ,ListResourcesResultSchema as fQ,ListResourceTemplatesRequestSchema as dQ,ListResourceTemplatesResultSchema as bQ,LoggingMessageNotificationSchema as xQ,PingRequestSchema as uQ,PromptListChangedNotificationSchema as hQ,ReadResourceRequestSchema as mQ,ReadResourceResultSchema as pQ,ResourceListChangedNotificationSchema as cQ,ToolListChangedNotificationSchema as nQ}from"@modelcontextprotocol/sdk/types.js";import{Protocol as iQ}from"@modelcontextprotocol/sdk/shared/protocol.js";var G="2026-01-26",o="ui/open-link",a="ui/download-file",t="ui/message",s="ui/notifications/sandbox-proxy-ready",e="ui/notifications/sandbox-resource-ready",QQ="ui/notifications/size-changed",XQ="ui/notifications/tool-input",_="ui/notifications/tool-input-partial",YQ="ui/notifications/tool-result",ZQ="ui/notifications/tool-cancelled",$Q="ui/notifications/host-context-changed",JQ="ui/notifications/request-teardown",KQ="ui/resource-teardown",GQ="ui/initialize",WQ="ui/notifications/initialized",DQ="ui/request-display-mode";import{z as Q}from"zod/v4";import{ContentBlockSchema as u,CallToolResultSchema as NQ,EmbeddedResourceSchema as jQ,ImplementationSchema as h,RequestIdSchema as EQ,ResourceLinkSchema as zQ,ToolSchema as BQ}from"@modelcontextprotocol/sdk/types.js";var m=Q.union([Q.literal("light"),Q.literal("dark")]).describe("Color theme preference for the host environment."),W=Q.union([Q.literal("inline"),Q.literal("fullscreen"),Q.literal("pip")]).describe("Display mode for UI presentation."),_Q=Q.union([Q.literal("--color-background-primary"),Q.literal("--color-background-secondary"),Q.literal("--color-background-tertiary"),Q.literal("--color-background-inverse"),Q.literal("--color-background-ghost"),Q.literal("--color-background-info"),Q.literal("--color-background-danger"),Q.literal("--color-background-success"),Q.literal("--color-background-warning"),Q.literal("--color-background-disabled"),Q.literal("--color-text-primary"),Q.literal("--color-text-secondary"),Q.literal("--color-text-tertiary"),Q.literal("--color-text-inverse"),Q.literal("--color-text-ghost"),Q.literal("--color-text-info"),Q.literal("--color-text-danger"),Q.literal("--color-text-success"),Q.literal("--color-text-warning"),Q.literal("--color-text-disabled"),Q.literal("--color-border-primary"),Q.literal("--color-border-secondary"),Q.literal("--color-border-tertiary"),Q.literal("--color-border-inverse"),Q.literal("--color-border-ghost"),Q.literal("--color-border-info"),Q.literal("--color-border-danger"),Q.literal("--color-border-success"),Q.literal("--color-border-warning"),Q.literal("--color-border-disabled"),Q.literal("--color-ring-primary"),Q.literal("--color-ring-secondary"),Q.literal("--color-ring-inverse"),Q.literal("--color-ring-info"),Q.literal("--color-ring-danger"),Q.literal("--color-ring-success"),Q.literal("--color-ring-warning"),Q.literal("--font-sans"),Q.literal("--font-mono"),Q.literal("--font-weight-normal"),Q.literal("--font-weight-medium"),Q.literal("--font-weight-semibold"),Q.literal("--font-weight-bold"),Q.literal("--font-text-xs-size"),Q.literal("--font-text-sm-size"),Q.literal("--font-text-md-size"),Q.literal("--font-text-lg-size"),Q.literal("--font-heading-xs-size"),Q.literal("--font-heading-sm-size"),Q.literal("--font-heading-md-size"),Q.literal("--font-heading-lg-size"),Q.literal("--font-heading-xl-size"),Q.literal("--font-heading-2xl-size"),Q.literal("--font-heading-3xl-size"),Q.literal("--font-text-xs-line-height"),Q.literal("--font-text-sm-line-height"),Q.literal("--font-text-md-line-height"),Q.literal("--font-text-lg-line-height"),Q.literal("--font-heading-xs-line-height"),Q.literal("--font-heading-sm-line-height"),Q.literal("--font-heading-md-line-height"),Q.literal("--font-heading-lg-line-height"),Q.literal("--font-heading-xl-line-height"),Q.literal("--font-heading-2xl-line-height"),Q.literal("--font-heading-3xl-line-height"),Q.literal("--border-radius-xs"),Q.literal("--border-radius-sm"),Q.literal("--border-radius-md"),Q.literal("--border-radius-lg"),Q.literal("--border-radius-xl"),Q.literal("--border-radius-full"),Q.literal("--border-width-regular"),Q.literal("--shadow-hairline"),Q.literal("--shadow-sm"),Q.literal("--shadow-md"),Q.literal("--shadow-lg")]).describe("CSS variable keys available to MCP apps for theming."),OQ=Q.record(_Q.describe(`Style variables for theming MCP apps.
import{CallToolRequestSchema as fQ,CallToolResultSchema as t,ListPromptsRequestSchema as yQ,ListPromptsResultSchema as vQ,ListResourcesRequestSchema as xQ,ListResourcesResultSchema as kQ,ListResourceTemplatesRequestSchema as dQ,ListResourceTemplatesResultSchema as bQ,ListToolsResultSchema as uQ,LoggingMessageNotificationSchema as hQ,PingRequestSchema as mQ,PromptListChangedNotificationSchema as iQ,ReadResourceRequestSchema as pQ,ReadResourceResultSchema as nQ,ResourceListChangedNotificationSchema as cQ,ToolListChangedNotificationSchema as rQ}from"@modelcontextprotocol/sdk/types.js";import{Protocol as s}from"@modelcontextprotocol/sdk/shared/protocol.js";class j extends s{_registeredMethods=new Set;_eventSlots=new Map;onEventDispatch(X,Y){}_ensureEventSlot(X){let Y=this._eventSlots.get(X);if(!Y){let Z=this.eventSchemas[X];if(!Z)throw Error(`Unknown event: ${String(X)}`);Y={listeners:[]},this._eventSlots.set(X,Y);let $=Z.shape.method.value;this._registeredMethods.add($);let J=Y;super.setNotificationHandler(Z,(K)=>{let N=K.params;this.onEventDispatch(X,N),J.onHandler?.(N);for(let W of[...J.listeners])W(N)})}return Y}setEventHandler(X,Y){let Z=this._ensureEventSlot(X);if(Z.onHandler&&Y)console.warn(`[MCP Apps] on${String(X)} handler replaced. Use addEventListener("${String(X)}", …) to add multiple listeners without replacing.`);Z.onHandler=Y}getEventHandler(X){return this._eventSlots.get(X)?.onHandler}addEventListener(X,Y){this._ensureEventSlot(X).listeners.push(Y)}removeEventListener(X,Y){let Z=this._eventSlots.get(X);if(!Z)return;let $=Z.listeners.indexOf(Y);if($!==-1)Z.listeners.splice($,1)}setRequestHandler=(X,Y)=>{this._assertMethodNotRegistered(X,"setRequestHandler"),super.setRequestHandler(X,Y)};setNotificationHandler=(X,Y)=>{this._assertMethodNotRegistered(X,"setNotificationHandler"),super.setNotificationHandler(X,Y)};warnIfRequestHandlerReplaced(X,Y,Z){if(Y&&Z)console.warn(`[MCP Apps] ${X} handler replaced. Previous handler will no longer be called.`)}replaceRequestHandler=(X,Y)=>{let Z=X.shape.method.value;this._registeredMethods.add(Z),super.setRequestHandler(X,Y)};_assertMethodNotRegistered(X,Y){let Z=X.shape.method.value;if(this._registeredMethods.has(Z))throw Error(`Handler for "${Z}" already registered (via ${Y}). Use addEventListener() to attach multiple listeners, or the on* setter for replace semantics.`);this._registeredMethods.add(Z)}}var G="2026-01-26",a="ui/open-link",e="ui/download-file",QQ="ui/message",XQ="ui/notifications/sandbox-proxy-ready",YQ="ui/notifications/sandbox-resource-ready",ZQ="ui/notifications/size-changed",$Q="ui/notifications/tool-input",V="ui/notifications/tool-input-partial",JQ="ui/notifications/tool-result",KQ="ui/notifications/tool-cancelled",GQ="ui/notifications/host-context-changed",DQ="ui/notifications/request-teardown",NQ="ui/resource-teardown",WQ="ui/initialize",jQ="ui/notifications/initialized",zQ="ui/request-display-mode";import{z as Q}from"zod/v4";import{ContentBlockSchema as m,CallToolResultSchema as BQ,EmbeddedResourceSchema as EQ,ImplementationSchema as i,RequestIdSchema as _Q,ResourceLinkSchema as OQ,ToolSchema as VQ}from"@modelcontextprotocol/sdk/types.js";var p=Q.union([Q.literal("light"),Q.literal("dark")]).describe("Color theme preference for the host environment."),D=Q.union([Q.literal("inline"),Q.literal("fullscreen"),Q.literal("pip")]).describe("Display mode for UI presentation."),IQ=Q.union([Q.literal("--color-background-primary"),Q.literal("--color-background-secondary"),Q.literal("--color-background-tertiary"),Q.literal("--color-background-inverse"),Q.literal("--color-background-ghost"),Q.literal("--color-background-info"),Q.literal("--color-background-danger"),Q.literal("--color-background-success"),Q.literal("--color-background-warning"),Q.literal("--color-background-disabled"),Q.literal("--color-text-primary"),Q.literal("--color-text-secondary"),Q.literal("--color-text-tertiary"),Q.literal("--color-text-inverse"),Q.literal("--color-text-ghost"),Q.literal("--color-text-info"),Q.literal("--color-text-danger"),Q.literal("--color-text-success"),Q.literal("--color-text-warning"),Q.literal("--color-text-disabled"),Q.literal("--color-border-primary"),Q.literal("--color-border-secondary"),Q.literal("--color-border-tertiary"),Q.literal("--color-border-inverse"),Q.literal("--color-border-ghost"),Q.literal("--color-border-info"),Q.literal("--color-border-danger"),Q.literal("--color-border-success"),Q.literal("--color-border-warning"),Q.literal("--color-border-disabled"),Q.literal("--color-ring-primary"),Q.literal("--color-ring-secondary"),Q.literal("--color-ring-inverse"),Q.literal("--color-ring-info"),Q.literal("--color-ring-danger"),Q.literal("--color-ring-success"),Q.literal("--color-ring-warning"),Q.literal("--font-sans"),Q.literal("--font-mono"),Q.literal("--font-weight-normal"),Q.literal("--font-weight-medium"),Q.literal("--font-weight-semibold"),Q.literal("--font-weight-bold"),Q.literal("--font-text-xs-size"),Q.literal("--font-text-sm-size"),Q.literal("--font-text-md-size"),Q.literal("--font-text-lg-size"),Q.literal("--font-heading-xs-size"),Q.literal("--font-heading-sm-size"),Q.literal("--font-heading-md-size"),Q.literal("--font-heading-lg-size"),Q.literal("--font-heading-xl-size"),Q.literal("--font-heading-2xl-size"),Q.literal("--font-heading-3xl-size"),Q.literal("--font-text-xs-line-height"),Q.literal("--font-text-sm-line-height"),Q.literal("--font-text-md-line-height"),Q.literal("--font-text-lg-line-height"),Q.literal("--font-heading-xs-line-height"),Q.literal("--font-heading-sm-line-height"),Q.literal("--font-heading-md-line-height"),Q.literal("--font-heading-lg-line-height"),Q.literal("--font-heading-xl-line-height"),Q.literal("--font-heading-2xl-line-height"),Q.literal("--font-heading-3xl-line-height"),Q.literal("--border-radius-xs"),Q.literal("--border-radius-sm"),Q.literal("--border-radius-md"),Q.literal("--border-radius-lg"),Q.literal("--border-radius-xl"),Q.literal("--border-radius-full"),Q.literal("--border-width-regular"),Q.literal("--shadow-hairline"),Q.literal("--shadow-sm"),Q.literal("--shadow-md"),Q.literal("--shadow-lg")]).describe("CSS variable keys available to MCP apps for theming."),AQ=Q.record(IQ.describe(`Style variables for theming MCP apps.

@@ -19,6 +19,6 @@ Individual style keys are optional - hosts may provide any subset of these values.

Note: This type uses \`Record<K, string | undefined>\` rather than \`Partial<Record<K, string>>\`
for compatibility with Zod schema generation. Both are functionally equivalent for validation.`),V=Q.object({method:Q.literal("ui/open-link"),params:Q.object({url:Q.string().describe("URL to open in the host's browser")})}),I=Q.object({isError:Q.boolean().optional().describe("True if the host failed to open the URL (e.g., due to security policy).")}).passthrough(),A=Q.object({isError:Q.boolean().optional().describe("True if the download failed (e.g., user cancelled or host denied).")}).passthrough(),F=Q.object({isError:Q.boolean().optional().describe("True if the host rejected or failed to deliver the message.")}).passthrough(),L=Q.object({method:Q.literal("ui/notifications/sandbox-proxy-ready"),params:Q.object({})}),N=Q.object({connectDomains:Q.array(Q.string()).optional().describe(`Origins for network requests (fetch/XHR/WebSocket).
for compatibility with Zod schema generation. Both are functionally equivalent for validation.`),A=Q.object({method:Q.literal("ui/open-link"),params:Q.object({url:Q.string().describe("URL to open in the host's browser")})}),F=Q.object({isError:Q.boolean().optional().describe("True if the host failed to open the URL (e.g., due to security policy).")}).passthrough(),L=Q.object({isError:Q.boolean().optional().describe("True if the download failed (e.g., user cancelled or host denied).")}).passthrough(),P=Q.object({isError:Q.boolean().optional().describe("True if the host rejected or failed to deliver the message.")}).passthrough(),T=Q.object({method:Q.literal("ui/notifications/sandbox-proxy-ready"),params:Q.object({})}),B=Q.object({connectDomains:Q.array(Q.string()).optional().describe(`Origins for network requests (fetch/XHR/WebSocket).
- Maps to CSP \`connect-src\` directive
- Empty or omitted → no network connections (secure default)`),resourceDomains:Q.array(Q.string()).optional().describe("Origins for static resources (images, scripts, stylesheets, fonts, media).\n\n- Maps to CSP `img-src`, `script-src`, `style-src`, `font-src`, `media-src` directives\n- Wildcard subdomains supported: `https://*.example.com`\n- Empty or omitted → no network resources (secure default)"),frameDomains:Q.array(Q.string()).optional().describe("Origins for nested iframes.\n\n- Maps to CSP `frame-src` directive\n- Empty or omitted → no nested iframes allowed (`frame-src 'none'`)"),baseUriDomains:Q.array(Q.string()).optional().describe("Allowed base URIs for the document.\n\n- Maps to CSP `base-uri` directive\n- Empty or omitted → only same origin allowed (`base-uri 'self'`)")}),j=Q.object({camera:Q.object({}).optional().describe("Request camera access.\n\nMaps to Permission Policy `camera` feature."),microphone:Q.object({}).optional().describe("Request microphone access.\n\nMaps to Permission Policy `microphone` feature."),geolocation:Q.object({}).optional().describe("Request geolocation access.\n\nMaps to Permission Policy `geolocation` feature."),clipboardWrite:Q.object({}).optional().describe("Request clipboard write access.\n\nMaps to Permission Policy `clipboard-write` feature.")}),P=Q.object({method:Q.literal("ui/notifications/size-changed"),params:Q.object({width:Q.number().optional().describe("New width in pixels."),height:Q.number().optional().describe("New height in pixels.")})}),T=Q.object({method:Q.literal("ui/notifications/tool-input"),params:Q.object({arguments:Q.record(Q.string(),Q.unknown().describe("Complete tool call arguments as key-value pairs.")).optional().describe("Complete tool call arguments as key-value pairs.")})}),w=Q.object({method:Q.literal("ui/notifications/tool-input-partial"),params:Q.object({arguments:Q.record(Q.string(),Q.unknown().describe("Partial tool call arguments (incomplete, may change).")).optional().describe("Partial tool call arguments (incomplete, may change).")})}),R=Q.object({method:Q.literal("ui/notifications/tool-cancelled"),params:Q.object({reason:Q.string().optional().describe('Optional reason for the cancellation (e.g., "user action", "timeout").')})}),p=Q.object({fonts:Q.string().optional()}),c=Q.object({variables:OQ.optional().describe("CSS variables for theming the app."),css:p.optional().describe("CSS blocks that apps can inject.")}),U=Q.object({method:Q.literal("ui/resource-teardown"),params:Q.object({})}),H=Q.record(Q.string(),Q.unknown()),O=Q.object({text:Q.object({}).optional().describe("Host supports text content blocks."),image:Q.object({}).optional().describe("Host supports image content blocks."),audio:Q.object({}).optional().describe("Host supports audio content blocks."),resource:Q.object({}).optional().describe("Host supports resource content blocks."),resourceLink:Q.object({}).optional().describe("Host supports resource link content blocks."),structuredContent:Q.object({}).optional().describe("Host supports structured content.")}),M=Q.object({method:Q.literal("ui/notifications/request-teardown"),params:Q.object({}).optional()}),n=Q.object({experimental:Q.object({}).optional().describe("Experimental features (structure TBD)."),openLinks:Q.object({}).optional().describe("Host supports opening external URLs."),downloadFile:Q.object({}).optional().describe("Host supports file downloads via ui/download-file."),serverTools:Q.object({listChanged:Q.boolean().optional().describe("Host supports tools/list_changed notifications.")}).optional().describe("Host can proxy tool calls to the MCP server."),serverResources:Q.object({listChanged:Q.boolean().optional().describe("Host supports resources/list_changed notifications.")}).optional().describe("Host can proxy resource reads to the MCP server."),logging:Q.object({}).optional().describe("Host accepts log messages."),sandbox:Q.object({permissions:j.optional().describe("Permissions granted by the host (camera, microphone, geolocation)."),csp:N.optional().describe("CSP domains approved by the host.")}).optional().describe("Sandbox configuration applied by the host."),updateModelContext:O.optional().describe("Host accepts context updates (ui/update-model-context) to be included in the model's context for future turns."),message:O.optional().describe("Host supports receiving content messages (ui/message) from the view.")}),i=Q.object({experimental:Q.object({}).optional().describe("Experimental features (structure TBD)."),tools:Q.object({listChanged:Q.boolean().optional().describe("App supports tools/list_changed notifications.")}).optional().describe("App exposes MCP-style tools that the host can call."),availableDisplayModes:Q.array(W).optional().describe("Display modes the app supports.")}),v=Q.object({method:Q.literal("ui/notifications/initialized"),params:Q.object({}).optional()}),VQ=Q.object({csp:N.optional().describe("Content Security Policy configuration for UI resources."),permissions:j.optional().describe("Sandbox permissions requested by the UI resource."),domain:Q.string().optional().describe(`Dedicated origin for view sandbox.
- Empty or omitted → no network connections (secure default)`),resourceDomains:Q.array(Q.string()).optional().describe("Origins for static resources (images, scripts, stylesheets, fonts, media).\n\n- Maps to CSP `img-src`, `script-src`, `style-src`, `font-src`, `media-src` directives\n- Wildcard subdomains supported: `https://*.example.com`\n- Empty or omitted → no network resources (secure default)"),frameDomains:Q.array(Q.string()).optional().describe("Origins for nested iframes.\n\n- Maps to CSP `frame-src` directive\n- Empty or omitted → no nested iframes allowed (`frame-src 'none'`)"),baseUriDomains:Q.array(Q.string()).optional().describe("Allowed base URIs for the document.\n\n- Maps to CSP `base-uri` directive\n- Empty or omitted → only same origin allowed (`base-uri 'self'`)")}),E=Q.object({camera:Q.object({}).optional().describe("Request camera access.\n\nMaps to Permission Policy `camera` feature."),microphone:Q.object({}).optional().describe("Request microphone access.\n\nMaps to Permission Policy `microphone` feature."),geolocation:Q.object({}).optional().describe("Request geolocation access.\n\nMaps to Permission Policy `geolocation` feature."),clipboardWrite:Q.object({}).optional().describe("Request clipboard write access.\n\nMaps to Permission Policy `clipboard-write` feature.")}),w=Q.object({method:Q.literal("ui/notifications/size-changed"),params:Q.object({width:Q.number().optional().describe("New width in pixels."),height:Q.number().optional().describe("New height in pixels.")})}),R=Q.object({method:Q.literal("ui/notifications/tool-input"),params:Q.object({arguments:Q.record(Q.string(),Q.unknown().describe("Complete tool call arguments as key-value pairs.")).optional().describe("Complete tool call arguments as key-value pairs.")})}),U=Q.object({method:Q.literal("ui/notifications/tool-input-partial"),params:Q.object({arguments:Q.record(Q.string(),Q.unknown().describe("Partial tool call arguments (incomplete, may change).")).optional().describe("Partial tool call arguments (incomplete, may change).")})}),H=Q.object({method:Q.literal("ui/notifications/tool-cancelled"),params:Q.object({reason:Q.string().optional().describe('Optional reason for the cancellation (e.g., "user action", "timeout").')})}),n=Q.object({fonts:Q.string().optional()}),c=Q.object({variables:AQ.optional().describe("CSS variables for theming the app."),css:n.optional().describe("CSS blocks that apps can inject.")}),M=Q.object({method:Q.literal("ui/resource-teardown"),params:Q.object({})}),g=Q.record(Q.string(),Q.unknown()),I=Q.object({text:Q.object({}).optional().describe("Host supports text content blocks."),image:Q.object({}).optional().describe("Host supports image content blocks."),audio:Q.object({}).optional().describe("Host supports audio content blocks."),resource:Q.object({}).optional().describe("Host supports resource content blocks."),resourceLink:Q.object({}).optional().describe("Host supports resource link content blocks."),structuredContent:Q.object({}).optional().describe("Host supports structured content.")}),C=Q.object({method:Q.literal("ui/notifications/request-teardown"),params:Q.object({}).optional()}),r=Q.object({experimental:Q.object({}).optional().describe("Experimental features (structure TBD)."),openLinks:Q.object({}).optional().describe("Host supports opening external URLs."),downloadFile:Q.object({}).optional().describe("Host supports file downloads via ui/download-file."),serverTools:Q.object({listChanged:Q.boolean().optional().describe("Host supports tools/list_changed notifications.")}).optional().describe("Host can proxy tool calls to the MCP server."),serverResources:Q.object({listChanged:Q.boolean().optional().describe("Host supports resources/list_changed notifications.")}).optional().describe("Host can proxy resource reads to the MCP server."),logging:Q.object({}).optional().describe("Host accepts log messages."),sandbox:Q.object({permissions:E.optional().describe("Permissions granted by the host (camera, microphone, geolocation)."),csp:B.optional().describe("CSP domains approved by the host.")}).optional().describe("Sandbox configuration applied by the host."),updateModelContext:I.optional().describe("Host accepts context updates (ui/update-model-context) to be included in the model's context for future turns."),message:I.optional().describe("Host supports receiving content messages (ui/message) from the view.")}),l=Q.object({experimental:Q.object({}).optional().describe("Experimental features (structure TBD)."),tools:Q.object({listChanged:Q.boolean().optional().describe("App supports tools/list_changed notifications.")}).optional().describe("App exposes MCP-style tools that the host can call."),availableDisplayModes:Q.array(D).optional().describe("Display modes the app supports.")}),S=Q.object({method:Q.literal("ui/notifications/initialized"),params:Q.object({}).optional()}),FQ=Q.object({csp:B.optional().describe("Content Security Policy configuration for UI resources."),permissions:E.optional().describe("Sandbox permissions requested by the UI resource."),domain:Q.string().optional().describe(`Dedicated origin for view sandbox.

@@ -37,5 +37,5 @@ Useful when views need stable, dedicated origins for OAuth callbacks, CORS policies, or API key allowlists.

- \`false\`: request no visible border + background
- omitted: host decides border`)}),E=Q.object({method:Q.literal("ui/request-display-mode"),params:Q.object({mode:W.describe("The display mode being requested.")})}),g=Q.object({mode:W.describe("The display mode that was actually set. May differ from requested if not supported.")}).passthrough(),l=Q.union([Q.literal("model"),Q.literal("app")]).describe("Tool visibility scope - who can access the tool."),IQ=Q.object({resourceUri:Q.string().optional(),visibility:Q.array(l).optional().describe(`Who can access this tool. Default: ["model", "app"]
- omitted: host decides border`)}),_=Q.object({method:Q.literal("ui/request-display-mode"),params:Q.object({mode:D.describe("The display mode being requested.")})}),q=Q.object({mode:D.describe("The display mode that was actually set. May differ from requested if not supported.")}).passthrough(),o=Q.union([Q.literal("model"),Q.literal("app")]).describe("Tool visibility scope - who can access the tool."),LQ=Q.object({resourceUri:Q.string().optional(),visibility:Q.array(o).optional().describe(`Who can access this tool. Default: ["model", "app"]
- "model": Tool visible to and callable by the agent
- "app": Tool callable by the app from this server only`)}),eQ=Q.object({mimeTypes:Q.array(Q.string()).optional().describe('Array of supported MIME types for UI resources.\nMust include `"text/html;profile=mcp-app"` for MCP Apps support.')}),C=Q.object({method:Q.literal("ui/download-file"),params:Q.object({contents:Q.array(Q.union([jQ,zQ])).describe("Resource contents to download — embedded (inline data) or linked (host fetches). Uses standard MCP resource types.")})}),S=Q.object({method:Q.literal("ui/message"),params:Q.object({role:Q.literal("user").describe('Message role, currently only "user" is supported.'),content:Q.array(u).describe("Message content blocks (text, image, etc.).")})}),AQ=Q.object({method:Q.literal("ui/notifications/sandbox-resource-ready"),params:Q.object({html:Q.string().describe("HTML content to load into the inner iframe."),sandbox:Q.string().optional().describe("Optional override for the inner iframe's sandbox attribute."),csp:N.optional().describe("CSP configuration from resource metadata."),permissions:j.optional().describe("Sandbox permissions from resource metadata.")})}),q=Q.object({method:Q.literal("ui/notifications/tool-result"),params:NQ.describe("Standard MCP tool execution result.")}),y=Q.object({toolInfo:Q.object({id:EQ.optional().describe("JSON-RPC id of the tools/call request."),tool:BQ.describe("Tool definition including name, inputSchema, etc.")}).optional().describe("Metadata of the tool call that instantiated this App."),theme:m.optional().describe("Current color theme preference."),styles:c.optional().describe("Style configuration for theming the app."),displayMode:W.optional().describe("How the UI is currently displayed."),availableDisplayModes:Q.array(W).optional().describe("Display modes the host supports."),containerDimensions:Q.union([Q.object({height:Q.number().describe("Fixed container height in pixels.")}),Q.object({maxHeight:Q.union([Q.number(),Q.undefined()]).optional().describe("Maximum container height in pixels.")})]).and(Q.union([Q.object({width:Q.number().describe("Fixed container width in pixels.")}),Q.object({maxWidth:Q.union([Q.number(),Q.undefined()]).optional().describe("Maximum container width in pixels.")})])).optional().describe(`Container dimensions. Represents the dimensions of the iframe or other
container holding the app. Specify either width or maxWidth, and either height or maxHeight.`),locale:Q.string().optional().describe("User's language and region preference in BCP 47 format."),timeZone:Q.string().optional().describe("User's timezone in IANA format."),userAgent:Q.string().optional().describe("Host application identifier."),platform:Q.union([Q.literal("web"),Q.literal("desktop"),Q.literal("mobile")]).optional().describe("Platform type for responsive design decisions."),deviceCapabilities:Q.object({touch:Q.boolean().optional().describe("Whether the device supports touch input."),hover:Q.boolean().optional().describe("Whether the device supports hover interactions.")}).optional().describe("Device input capabilities."),safeAreaInsets:Q.object({top:Q.number().describe("Top safe area inset in pixels."),right:Q.number().describe("Right safe area inset in pixels."),bottom:Q.number().describe("Bottom safe area inset in pixels."),left:Q.number().describe("Left safe area inset in pixels.")}).optional().describe("Mobile safe area boundaries in pixels.")}).passthrough(),k=Q.object({method:Q.literal("ui/notifications/host-context-changed"),params:y.describe("Partial context update containing only changed fields.")}),f=Q.object({method:Q.literal("ui/update-model-context"),params:Q.object({content:Q.array(u).optional().describe("Context content blocks (text, image, etc.)."),structuredContent:Q.record(Q.string(),Q.unknown().describe("Structured content for machine-readable context data.")).optional().describe("Structured content for machine-readable context data.")})}),d=Q.object({method:Q.literal("ui/initialize"),params:Q.object({appInfo:h.describe("App identification (name and version)."),appCapabilities:i.describe("Features and capabilities this app provides."),protocolVersion:Q.string().describe("Protocol version this app supports.")})}),b=Q.object({protocolVersion:Q.string().describe('Negotiated protocol version string (e.g., "2025-11-21").'),hostInfo:h.describe("Host application identification and version."),hostCapabilities:n.describe("Features and capabilities provided by the host."),hostContext:y.describe("Rich context about the host environment.")}).passthrough();import{Protocol as LQ}from"@modelcontextprotocol/sdk/shared/protocol.js";import{CallToolRequestSchema as PQ,CallToolResultSchema as TQ,EmptyResultSchema as wQ,ListResourcesResultSchema as RQ,ListToolsRequestSchema as UQ,PingRequestSchema as HQ,ReadResourceResultSchema as MQ}from"@modelcontextprotocol/sdk/types.js";import{JSONRPCMessageSchema as FQ}from"@modelcontextprotocol/sdk/types.js";class D{eventTarget;eventSource;messageListener;constructor(X=window.parent,Y){this.eventTarget=X;this.eventSource=Y;this.messageListener=(Z)=>{if(Y&&Z.source!==this.eventSource){console.debug("Ignoring message from unknown source",Z);return}let $=FQ.safeParse(Z.data);if($.success)console.debug("Parsed message",$.data),this.onmessage?.($.data);else if(Z.data?.jsonrpc!=="2.0")console.debug("Ignoring non-JSON-RPC message",$.error.message,Z);else console.error("Failed to parse message",$.error.message,Z),this.onerror?.(Error("Invalid JSON-RPC message received: "+$.error.message))}}async start(){window.addEventListener("message",this.messageListener)}async send(X,Y){if(X.method!==_)console.debug("Sending message",X);this.eventTarget.postMessage(X,"*")}async close(){window.removeEventListener("message",this.messageListener),this.onclose?.()}onclose;onerror;onmessage;sessionId;setProtocolVersion}var x="ui/resourceUri",vQ="text/html;profile=mcp-app";class gQ extends LQ{_appInfo;_capabilities;options;_hostCapabilities;_hostInfo;_hostContext;constructor(X,Y={},Z={autoResize:!0}){super(Z);this._appInfo=X;this._capabilities=Y;this.options=Z;this.setRequestHandler(HQ,($)=>{return console.log("Received ping:",$.params),{}}),this.onhostcontextchanged=()=>{}}getHostCapabilities(){return this._hostCapabilities}getHostVersion(){return this._hostInfo}getHostContext(){return this._hostContext}set ontoolinput(X){this.setNotificationHandler(T,(Y)=>X(Y.params))}set ontoolinputpartial(X){this.setNotificationHandler(w,(Y)=>X(Y.params))}set ontoolresult(X){this.setNotificationHandler(q,(Y)=>X(Y.params))}set ontoolcancelled(X){this.setNotificationHandler(R,(Y)=>X(Y.params))}set onhostcontextchanged(X){this.setNotificationHandler(k,(Y)=>{this._hostContext={...this._hostContext,...Y.params},X(Y.params)})}set onteardown(X){this.setRequestHandler(U,(Y,Z)=>X(Y.params,Z))}set oncalltool(X){this.setRequestHandler(PQ,(Y,Z)=>X(Y.params,Z))}set onlisttools(X){this.setRequestHandler(UQ,(Y,Z)=>X(Y.params,Z))}assertCapabilityForMethod(X){}assertRequestHandlerCapability(X){switch(X){case"tools/call":case"tools/list":if(!this._capabilities.tools)throw Error(`Client does not support tool capability (required for ${X})`);return;case"ping":case"ui/resource-teardown":return;default:throw Error(`No handler for method ${X} registered`)}}assertNotificationCapability(X){}assertTaskCapability(X){throw Error("Tasks are not supported in MCP Apps")}assertTaskHandlerCapability(X){throw Error("Task handlers are not supported in MCP Apps")}async callServerTool(X,Y){if(typeof X==="string")throw Error(`callServerTool() expects an object as its first argument, but received a string ("${X}"). Did you mean: callServerTool({ name: "${X}", arguments: { ... } })?`);return await this.request({method:"tools/call",params:X},TQ,Y)}async readServerResource(X,Y){return await this.request({method:"resources/read",params:X},MQ,Y)}async listServerResources(X,Y){return await this.request({method:"resources/list",params:X},RQ,Y)}sendMessage(X,Y){return this.request({method:"ui/message",params:X},F,Y)}sendLog(X){return this.notification({method:"notifications/message",params:X})}updateModelContext(X,Y){return this.request({method:"ui/update-model-context",params:X},wQ,Y)}openLink(X,Y){return this.request({method:"ui/open-link",params:X},I,Y)}sendOpenLink=this.openLink;downloadFile(X,Y){return this.request({method:"ui/download-file",params:X},A,Y)}requestTeardown(X={}){return this.notification({method:"ui/notifications/request-teardown",params:X})}requestDisplayMode(X,Y){return this.request({method:"ui/request-display-mode",params:X},g,Y)}sendSizeChanged(X){return this.notification({method:"ui/notifications/size-changed",params:X})}setupSizeChangedNotifications(){let X=!1,Y=0,Z=0,$=()=>{if(X)return;X=!0,requestAnimationFrame(()=>{X=!1;let K=document.documentElement,r=K.style.height;K.style.height="max-content";let z=Math.ceil(K.getBoundingClientRect().height);K.style.height=r;let B=Math.ceil(window.innerWidth);if(B!==Y||z!==Z)Y=B,Z=z,this.sendSizeChanged({width:B,height:z})})};$();let J=new ResizeObserver($);return J.observe(document.documentElement),J.observe(document.body),()=>J.disconnect()}async connect(X=new D(window.parent,window.parent),Y){if(this.transport)throw Error("App is already connected. Call close() before connecting again.");await super.connect(X);try{let Z=await this.request({method:"ui/initialize",params:{appCapabilities:this._capabilities,appInfo:this._appInfo,protocolVersion:G}},b,Y);if(Z===void 0)throw Error(`Server sent invalid initialize result: ${Z}`);if(this._hostCapabilities=Z.hostCapabilities,this._hostInfo=Z.hostInfo,this._hostContext=Z.hostContext,await this.notification({method:"ui/notifications/initialized"}),this.options?.autoResize)this.setupSizeChangedNotifications()}catch(Z){throw this.close(),Z}}}function mY(X){let Z=X._meta?.ui?.resourceUri;if(Z===void 0)Z=X._meta?.[x];if(typeof Z==="string"&&Z.startsWith("ui://"))return Z;else if(Z!==void 0)throw Error(`Invalid UI resource URI: ${JSON.stringify(Z)}`);return}function pY(X){let Z=X._meta?.ui?.visibility;if(!Z)return!1;if(Z.length===1&&Z[0]==="model")return!0;return!1}function cY(X){let Z=X._meta?.ui?.visibility;if(!Z)return!1;if(Z.length===1&&Z[0]==="app")return!0;return!1}function nY(X){if(!X)return"";let Y=[];if(X.camera)Y.push("camera");if(X.microphone)Y.push("microphone");if(X.geolocation)Y.push("geolocation");if(X.clipboardWrite)Y.push("clipboard-write");return Y.join("; ")}var lQ=[G];class rQ extends iQ{_client;_hostInfo;_capabilities;_appCapabilities;_hostContext={};_appInfo;constructor(X,Y,Z,$){super($);this._client=X;this._hostInfo=Y;this._capabilities=Z;this._hostContext=$?.hostContext||{},this.setRequestHandler(d,(J)=>this._oninitialize(J)),this.setRequestHandler(uQ,(J,K)=>{return this.onping?.(J.params,K),{}}),this.setRequestHandler(E,(J)=>{return{mode:this._hostContext.displayMode??"inline"}})}getAppCapabilities(){return this._appCapabilities}getAppVersion(){return this._appInfo}onping;set onsizechange(X){this.setNotificationHandler(P,(Y)=>X(Y.params))}set onsandboxready(X){this.setNotificationHandler(L,(Y)=>X(Y.params))}set oninitialized(X){this.setNotificationHandler(v,(Y)=>X(Y.params))}set onmessage(X){this.setRequestHandler(S,async(Y,Z)=>{return X(Y.params,Z)})}set onopenlink(X){this.setRequestHandler(V,async(Y,Z)=>{return X(Y.params,Z)})}set ondownloadfile(X){this.setRequestHandler(C,async(Y,Z)=>{return X(Y.params,Z)})}set onrequestteardown(X){this.setNotificationHandler(M,(Y)=>X(Y.params))}set onrequestdisplaymode(X){this.setRequestHandler(E,async(Y,Z)=>{return X(Y.params,Z)})}set onloggingmessage(X){this.setNotificationHandler(xQ,async(Y)=>{X(Y.params)})}set onupdatemodelcontext(X){this.setRequestHandler(f,async(Y,Z)=>{return X(Y.params,Z)})}set oncalltool(X){this.setRequestHandler(CQ,async(Y,Z)=>{return X(Y.params,Z)})}sendToolListChanged(X={}){return this.notification({method:"notifications/tools/list_changed",params:X})}set onlistresources(X){this.setRequestHandler(kQ,async(Y,Z)=>{return X(Y.params,Z)})}set onlistresourcetemplates(X){this.setRequestHandler(dQ,async(Y,Z)=>{return X(Y.params,Z)})}set onreadresource(X){this.setRequestHandler(mQ,async(Y,Z)=>{return X(Y.params,Z)})}sendResourceListChanged(X={}){return this.notification({method:"notifications/resources/list_changed",params:X})}set onlistprompts(X){this.setRequestHandler(qQ,async(Y,Z)=>{return X(Y.params,Z)})}sendPromptListChanged(X={}){return this.notification({method:"notifications/prompts/list_changed",params:X})}assertCapabilityForMethod(X){}assertRequestHandlerCapability(X){}assertNotificationCapability(X){}assertTaskCapability(X){throw Error("Tasks are not supported in MCP Apps")}assertTaskHandlerCapability(X){throw Error("Task handlers are not supported in MCP Apps")}getCapabilities(){return this._capabilities}async _oninitialize(X){let Y=X.params.protocolVersion;return this._appCapabilities=X.params.appCapabilities,this._appInfo=X.params.appInfo,{protocolVersion:lQ.includes(Y)?Y:G,hostCapabilities:this.getCapabilities(),hostInfo:this._hostInfo,hostContext:this._hostContext}}setHostContext(X){let Y={},Z=!1;for(let $ of Object.keys(X)){let J=this._hostContext[$],K=X[$];if(oQ(J,K))continue;Y[$]=K,Z=!0}if(Z)this._hostContext=X,this.sendHostContextChange(Y)}sendHostContextChange(X){return this.notification({method:"ui/notifications/host-context-changed",params:X})}sendToolInput(X){return this.notification({method:"ui/notifications/tool-input",params:X})}sendToolInputPartial(X){return this.notification({method:"ui/notifications/tool-input-partial",params:X})}sendToolResult(X){return this.notification({method:"ui/notifications/tool-result",params:X})}sendToolCancelled(X){return this.notification({method:"ui/notifications/tool-cancelled",params:X})}sendSandboxResourceReady(X){return this.notification({method:"ui/notifications/sandbox-resource-ready",params:X})}teardownResource(X,Y){return this.request({method:"ui/resource-teardown",params:X},H,Y)}sendResourceTeardown=this.teardownResource;async connect(X){if(this.transport)throw Error("AppBridge is already connected. Call close() before connecting again.");if(this._client){let Y=this._client.getServerCapabilities();if(!Y)throw Error("Client server capabilities not available");if(Y.tools){if(this.oncalltool=async(Z,$)=>{return this._client.request({method:"tools/call",params:Z},SQ,{signal:$.signal})},Y.tools.listChanged)this._client.setNotificationHandler(nQ,(Z)=>this.sendToolListChanged(Z.params))}if(Y.resources){if(this.onlistresources=async(Z,$)=>{return this._client.request({method:"resources/list",params:Z},fQ,{signal:$.signal})},this.onlistresourcetemplates=async(Z,$)=>{return this._client.request({method:"resources/templates/list",params:Z},bQ,{signal:$.signal})},this.onreadresource=async(Z,$)=>{return this._client.request({method:"resources/read",params:Z},pQ,{signal:$.signal})},Y.resources.listChanged)this._client.setNotificationHandler(cQ,(Z)=>this.sendResourceListChanged(Z.params))}if(Y.prompts){if(this.onlistprompts=async(Z,$)=>{return this._client.request({method:"prompts/list",params:Z},yQ,{signal:$.signal})},Y.prompts.listChanged)this._client.setNotificationHandler(hQ,(Z)=>this.sendPromptListChanged(Z.params))}}return super.connect(X)}}function oQ(X,Y){return JSON.stringify(X)===JSON.stringify(Y)}export{pY as isToolVisibilityModelOnly,cY as isToolVisibilityAppOnly,mY as getToolUiResourceUri,nY as buildAllowAttribute,YQ as TOOL_RESULT_METHOD,_ as TOOL_INPUT_PARTIAL_METHOD,XQ as TOOL_INPUT_METHOD,ZQ as TOOL_CANCELLED_METHOD,lQ as SUPPORTED_PROTOCOL_VERSIONS,QQ as SIZE_CHANGED_METHOD,e as SANDBOX_RESOURCE_READY_METHOD,s as SANDBOX_PROXY_READY_METHOD,x as RESOURCE_URI_META_KEY,KQ as RESOURCE_TEARDOWN_METHOD,vQ as RESOURCE_MIME_TYPE,JQ as REQUEST_TEARDOWN_METHOD,DQ as REQUEST_DISPLAY_MODE_METHOD,D as PostMessageTransport,o as OPEN_LINK_METHOD,f as McpUiUpdateModelContextRequestSchema,l as McpUiToolVisibilitySchema,q as McpUiToolResultNotificationSchema,IQ as McpUiToolMetaSchema,w as McpUiToolInputPartialNotificationSchema,T as McpUiToolInputNotificationSchema,R as McpUiToolCancelledNotificationSchema,m as McpUiThemeSchema,O as McpUiSupportedContentBlockModalitiesSchema,P as McpUiSizeChangedNotificationSchema,AQ as McpUiSandboxResourceReadyNotificationSchema,L as McpUiSandboxProxyReadyNotificationSchema,H as McpUiResourceTeardownResultSchema,U as McpUiResourceTeardownRequestSchema,j as McpUiResourcePermissionsSchema,VQ as McpUiResourceMetaSchema,N as McpUiResourceCspSchema,M as McpUiRequestTeardownNotificationSchema,g as McpUiRequestDisplayModeResultSchema,E as McpUiRequestDisplayModeRequestSchema,I as McpUiOpenLinkResultSchema,V as McpUiOpenLinkRequestSchema,F as McpUiMessageResultSchema,S as McpUiMessageRequestSchema,v as McpUiInitializedNotificationSchema,b as McpUiInitializeResultSchema,d as McpUiInitializeRequestSchema,c as McpUiHostStylesSchema,p as McpUiHostCssSchema,y as McpUiHostContextSchema,k as McpUiHostContextChangedNotificationSchema,n as McpUiHostCapabilitiesSchema,A as McpUiDownloadFileResultSchema,C as McpUiDownloadFileRequestSchema,W as McpUiDisplayModeSchema,i as McpUiAppCapabilitiesSchema,t as MESSAGE_METHOD,G as LATEST_PROTOCOL_VERSION,GQ as INITIALIZE_METHOD,WQ as INITIALIZED_METHOD,$Q as HOST_CONTEXT_CHANGED_METHOD,a as DOWNLOAD_FILE_METHOD,rQ as AppBridge};
- "app": Tool callable by the app from this server only`)}),YX=Q.object({mimeTypes:Q.array(Q.string()).optional().describe('Array of supported MIME types for UI resources.\nMust include `"text/html;profile=mcp-app"` for MCP Apps support.')}),f=Q.object({method:Q.literal("ui/download-file"),params:Q.object({contents:Q.array(Q.union([EQ,OQ])).describe("Resource contents to download — embedded (inline data) or linked (host fetches). Uses standard MCP resource types.")})}),y=Q.object({method:Q.literal("ui/message"),params:Q.object({role:Q.literal("user").describe('Message role, currently only "user" is supported.'),content:Q.array(m).describe("Message content blocks (text, image, etc.).")})}),PQ=Q.object({method:Q.literal("ui/notifications/sandbox-resource-ready"),params:Q.object({html:Q.string().describe("HTML content to load into the inner iframe."),sandbox:Q.string().optional().describe("Optional override for the inner iframe's sandbox attribute."),csp:B.optional().describe("CSP configuration from resource metadata."),permissions:E.optional().describe("Sandbox permissions from resource metadata.")})}),v=Q.object({method:Q.literal("ui/notifications/tool-result"),params:BQ.describe("Standard MCP tool execution result.")}),x=Q.object({toolInfo:Q.object({id:_Q.optional().describe("JSON-RPC id of the tools/call request."),tool:VQ.describe("Tool definition including name, inputSchema, etc.")}).optional().describe("Metadata of the tool call that instantiated this App."),theme:p.optional().describe("Current color theme preference."),styles:c.optional().describe("Style configuration for theming the app."),displayMode:D.optional().describe("How the UI is currently displayed."),availableDisplayModes:Q.array(D).optional().describe("Display modes the host supports."),containerDimensions:Q.union([Q.object({height:Q.number().describe("Fixed container height in pixels.")}),Q.object({maxHeight:Q.union([Q.number(),Q.undefined()]).optional().describe("Maximum container height in pixels.")})]).and(Q.union([Q.object({width:Q.number().describe("Fixed container width in pixels.")}),Q.object({maxWidth:Q.union([Q.number(),Q.undefined()]).optional().describe("Maximum container width in pixels.")})])).optional().describe(`Container dimensions. Represents the dimensions of the iframe or other
container holding the app. Specify either width or maxWidth, and either height or maxHeight.`),locale:Q.string().optional().describe("User's language and region preference in BCP 47 format."),timeZone:Q.string().optional().describe("User's timezone in IANA format."),userAgent:Q.string().optional().describe("Host application identifier."),platform:Q.union([Q.literal("web"),Q.literal("desktop"),Q.literal("mobile")]).optional().describe("Platform type for responsive design decisions."),deviceCapabilities:Q.object({touch:Q.boolean().optional().describe("Whether the device supports touch input."),hover:Q.boolean().optional().describe("Whether the device supports hover interactions.")}).optional().describe("Device input capabilities."),safeAreaInsets:Q.object({top:Q.number().describe("Top safe area inset in pixels."),right:Q.number().describe("Right safe area inset in pixels."),bottom:Q.number().describe("Bottom safe area inset in pixels."),left:Q.number().describe("Left safe area inset in pixels.")}).optional().describe("Mobile safe area boundaries in pixels.")}).passthrough(),k=Q.object({method:Q.literal("ui/notifications/host-context-changed"),params:x.describe("Partial context update containing only changed fields.")}),d=Q.object({method:Q.literal("ui/update-model-context"),params:Q.object({content:Q.array(m).optional().describe("Context content blocks (text, image, etc.)."),structuredContent:Q.record(Q.string(),Q.unknown().describe("Structured content for machine-readable context data.")).optional().describe("Structured content for machine-readable context data.")})}),b=Q.object({method:Q.literal("ui/initialize"),params:Q.object({appInfo:i.describe("App identification (name and version)."),appCapabilities:l.describe("Features and capabilities this app provides."),protocolVersion:Q.string().describe("Protocol version this app supports.")})}),u=Q.object({protocolVersion:Q.string().describe('Negotiated protocol version string (e.g., "2025-11-21").'),hostInfo:i.describe("Host application identification and version."),hostCapabilities:r.describe("Features and capabilities provided by the host."),hostContext:x.describe("Rich context about the host environment.")}).passthrough();import{CallToolRequestSchema as wQ,CallToolResultSchema as RQ,EmptyResultSchema as UQ,ListResourcesResultSchema as HQ,ListToolsRequestSchema as MQ,PingRequestSchema as gQ,ReadResourceResultSchema as CQ}from"@modelcontextprotocol/sdk/types.js";import{JSONRPCMessageSchema as TQ}from"@modelcontextprotocol/sdk/types.js";class z{eventTarget;eventSource;messageListener;constructor(X=window.parent,Y){this.eventTarget=X;this.eventSource=Y;this.messageListener=(Z)=>{if(Y&&Z.source!==this.eventSource){console.debug("Ignoring message from unknown source",Z);return}let $=TQ.safeParse(Z.data);if($.success)console.debug("Parsed message",$.data),this.onmessage?.($.data);else if(Z.data?.jsonrpc!=="2.0")console.debug("Ignoring non-JSON-RPC message",$.error.message,Z);else console.error("Failed to parse message",$.error.message,Z),this.onerror?.(Error("Invalid JSON-RPC message received: "+$.error.message))}}async start(){window.addEventListener("message",this.messageListener)}async send(X,Y){if(X.method!==V)console.debug("Sending message",X);this.eventTarget.postMessage(X,"*")}async close(){window.removeEventListener("message",this.messageListener),this.onclose?.()}onclose;onerror;onmessage;sessionId;setProtocolVersion}var h="ui/resourceUri",SQ="text/html;profile=mcp-app";class qQ extends j{_appInfo;_capabilities;options;_hostCapabilities;_hostInfo;_hostContext;eventSchemas={toolinput:R,toolinputpartial:U,toolresult:v,toolcancelled:H,hostcontextchanged:k};onEventDispatch(X,Y){if(X==="hostcontextchanged")this._hostContext={...this._hostContext,...Y}}constructor(X,Y={},Z={autoResize:!0}){super(Z);this._appInfo=X;this._capabilities=Y;this.options=Z;this.setRequestHandler(gQ,($)=>{return console.log("Received ping:",$.params),{}}),this.setEventHandler("hostcontextchanged",void 0)}getHostCapabilities(){return this._hostCapabilities}getHostVersion(){return this._hostInfo}getHostContext(){return this._hostContext}get ontoolinput(){return this.getEventHandler("toolinput")}set ontoolinput(X){this.setEventHandler("toolinput",X)}get ontoolinputpartial(){return this.getEventHandler("toolinputpartial")}set ontoolinputpartial(X){this.setEventHandler("toolinputpartial",X)}get ontoolresult(){return this.getEventHandler("toolresult")}set ontoolresult(X){this.setEventHandler("toolresult",X)}get ontoolcancelled(){return this.getEventHandler("toolcancelled")}set ontoolcancelled(X){this.setEventHandler("toolcancelled",X)}get onhostcontextchanged(){return this.getEventHandler("hostcontextchanged")}set onhostcontextchanged(X){this.setEventHandler("hostcontextchanged",X)}_onteardown;get onteardown(){return this._onteardown}set onteardown(X){this.warnIfRequestHandlerReplaced("onteardown",this._onteardown,X),this._onteardown=X,this.replaceRequestHandler(M,(Y,Z)=>{if(!this._onteardown)throw Error("No onteardown handler set");return this._onteardown(Y.params,Z)})}_oncalltool;get oncalltool(){return this._oncalltool}set oncalltool(X){this.warnIfRequestHandlerReplaced("oncalltool",this._oncalltool,X),this._oncalltool=X,this.replaceRequestHandler(wQ,(Y,Z)=>{if(!this._oncalltool)throw Error("No oncalltool handler set");return this._oncalltool(Y.params,Z)})}_onlisttools;get onlisttools(){return this._onlisttools}set onlisttools(X){this.warnIfRequestHandlerReplaced("onlisttools",this._onlisttools,X),this._onlisttools=X,this.replaceRequestHandler(MQ,(Y,Z)=>{if(!this._onlisttools)throw Error("No onlisttools handler set");return this._onlisttools(Y.params,Z)})}assertCapabilityForMethod(X){}assertRequestHandlerCapability(X){switch(X){case"tools/call":case"tools/list":if(!this._capabilities.tools)throw Error(`Client does not support tool capability (required for ${X})`);return;case"ping":case"ui/resource-teardown":return;default:throw Error(`No handler for method ${X} registered`)}}assertNotificationCapability(X){}assertTaskCapability(X){throw Error("Tasks are not supported in MCP Apps")}assertTaskHandlerCapability(X){throw Error("Task handlers are not supported in MCP Apps")}async callServerTool(X,Y){if(typeof X==="string")throw Error(`callServerTool() expects an object as its first argument, but received a string ("${X}"). Did you mean: callServerTool({ name: "${X}", arguments: { ... } })?`);return await this.request({method:"tools/call",params:X},RQ,Y)}async readServerResource(X,Y){return await this.request({method:"resources/read",params:X},CQ,Y)}async listServerResources(X,Y){return await this.request({method:"resources/list",params:X},HQ,Y)}sendMessage(X,Y){return this.request({method:"ui/message",params:X},P,Y)}sendLog(X){return this.notification({method:"notifications/message",params:X})}updateModelContext(X,Y){return this.request({method:"ui/update-model-context",params:X},UQ,Y)}openLink(X,Y){return this.request({method:"ui/open-link",params:X},F,Y)}sendOpenLink=this.openLink;downloadFile(X,Y){return this.request({method:"ui/download-file",params:X},L,Y)}requestTeardown(X={}){return this.notification({method:"ui/notifications/request-teardown",params:X})}requestDisplayMode(X,Y){return this.request({method:"ui/request-display-mode",params:X},q,Y)}sendSizeChanged(X){return this.notification({method:"ui/notifications/size-changed",params:X})}setupSizeChangedNotifications(){let X=!1,Y=0,Z=0,$=()=>{if(X)return;X=!0,requestAnimationFrame(()=>{X=!1;let K=document.documentElement,N=K.style.height;K.style.height="max-content";let W=Math.ceil(K.getBoundingClientRect().height);K.style.height=N;let O=Math.ceil(window.innerWidth);if(O!==Y||W!==Z)Y=O,Z=W,this.sendSizeChanged({width:O,height:W})})};$();let J=new ResizeObserver($);return J.observe(document.documentElement),J.observe(document.body),()=>J.disconnect()}async connect(X=new z(window.parent,window.parent),Y){if(this.transport)throw Error("App is already connected. Call close() before connecting again.");await super.connect(X);try{let Z=await this.request({method:"ui/initialize",params:{appCapabilities:this._capabilities,appInfo:this._appInfo,protocolVersion:G}},u,Y);if(Z===void 0)throw Error(`Server sent invalid initialize result: ${Z}`);if(this._hostCapabilities=Z.hostCapabilities,this._hostInfo=Z.hostInfo,this._hostContext=Z.hostContext,await this.notification({method:"ui/notifications/initialized"}),this.options?.autoResize)this.setupSizeChangedNotifications()}catch(Z){throw this.close(),Z}}}function nY(X){let Z=X._meta?.ui?.resourceUri;if(Z===void 0)Z=X._meta?.[h];if(typeof Z==="string"&&Z.startsWith("ui://"))return Z;else if(Z!==void 0)throw Error(`Invalid UI resource URI: ${JSON.stringify(Z)}`);return}function cY(X){let Z=X._meta?.ui?.visibility;if(!Z)return!1;if(Z.length===1&&Z[0]==="model")return!0;return!1}function rY(X){let Z=X._meta?.ui?.visibility;if(!Z)return!1;if(Z.length===1&&Z[0]==="app")return!0;return!1}function lY(X){if(!X)return"";let Y=[];if(X.camera)Y.push("camera");if(X.microphone)Y.push("microphone");if(X.geolocation)Y.push("geolocation");if(X.clipboardWrite)Y.push("clipboard-write");return Y.join("; ")}var lQ=[G];class oQ extends j{_client;_hostInfo;_capabilities;_appCapabilities;_hostContext={};_appInfo;eventSchemas={sizechange:w,sandboxready:T,initialized:S,requestteardown:C,loggingmessage:hQ};constructor(X,Y,Z,$){super($);this._client=X;this._hostInfo=Y;this._capabilities=Z;this._hostContext=$?.hostContext||{},this.setRequestHandler(b,(J)=>this._oninitialize(J)),this.setRequestHandler(mQ,(J,K)=>{return this.onping?.(J.params,K),{}}),this.replaceRequestHandler(_,(J)=>{return{mode:this._hostContext.displayMode??"inline"}})}getAppCapabilities(){return this._appCapabilities}getAppVersion(){return this._appInfo}onping;get onsizechange(){return this.getEventHandler("sizechange")}set onsizechange(X){this.setEventHandler("sizechange",X)}get onsandboxready(){return this.getEventHandler("sandboxready")}set onsandboxready(X){this.setEventHandler("sandboxready",X)}get oninitialized(){return this.getEventHandler("initialized")}set oninitialized(X){this.setEventHandler("initialized",X)}_onmessage;get onmessage(){return this._onmessage}set onmessage(X){this.warnIfRequestHandlerReplaced("onmessage",this._onmessage,X),this._onmessage=X,this.replaceRequestHandler(y,async(Y,Z)=>{if(!this._onmessage)throw Error("No onmessage handler set");return this._onmessage(Y.params,Z)})}_onopenlink;get onopenlink(){return this._onopenlink}set onopenlink(X){this.warnIfRequestHandlerReplaced("onopenlink",this._onopenlink,X),this._onopenlink=X,this.replaceRequestHandler(A,async(Y,Z)=>{if(!this._onopenlink)throw Error("No onopenlink handler set");return this._onopenlink(Y.params,Z)})}_ondownloadfile;get ondownloadfile(){return this._ondownloadfile}set ondownloadfile(X){this.warnIfRequestHandlerReplaced("ondownloadfile",this._ondownloadfile,X),this._ondownloadfile=X,this.replaceRequestHandler(f,async(Y,Z)=>{if(!this._ondownloadfile)throw Error("No ondownloadfile handler set");return this._ondownloadfile(Y.params,Z)})}get onrequestteardown(){return this.getEventHandler("requestteardown")}set onrequestteardown(X){this.setEventHandler("requestteardown",X)}_onrequestdisplaymode;get onrequestdisplaymode(){return this._onrequestdisplaymode}set onrequestdisplaymode(X){this.warnIfRequestHandlerReplaced("onrequestdisplaymode",this._onrequestdisplaymode,X),this._onrequestdisplaymode=X,this.replaceRequestHandler(_,async(Y,Z)=>{if(!this._onrequestdisplaymode)throw Error("No onrequestdisplaymode handler set");return this._onrequestdisplaymode(Y.params,Z)})}get onloggingmessage(){return this.getEventHandler("loggingmessage")}set onloggingmessage(X){this.setEventHandler("loggingmessage",X)}_onupdatemodelcontext;get onupdatemodelcontext(){return this._onupdatemodelcontext}set onupdatemodelcontext(X){this.warnIfRequestHandlerReplaced("onupdatemodelcontext",this._onupdatemodelcontext,X),this._onupdatemodelcontext=X,this.replaceRequestHandler(d,async(Y,Z)=>{if(!this._onupdatemodelcontext)throw Error("No onupdatemodelcontext handler set");return this._onupdatemodelcontext(Y.params,Z)})}_oncalltool;get oncalltool(){return this._oncalltool}set oncalltool(X){this.warnIfRequestHandlerReplaced("oncalltool",this._oncalltool,X),this._oncalltool=X,this.replaceRequestHandler(fQ,async(Y,Z)=>{if(!this._oncalltool)throw Error("No oncalltool handler set");return this._oncalltool(Y.params,Z)})}sendToolListChanged(X={}){return this.notification({method:"notifications/tools/list_changed",params:X})}_onlistresources;get onlistresources(){return this._onlistresources}set onlistresources(X){this.warnIfRequestHandlerReplaced("onlistresources",this._onlistresources,X),this._onlistresources=X,this.replaceRequestHandler(xQ,async(Y,Z)=>{if(!this._onlistresources)throw Error("No onlistresources handler set");return this._onlistresources(Y.params,Z)})}_onlistresourcetemplates;get onlistresourcetemplates(){return this._onlistresourcetemplates}set onlistresourcetemplates(X){this.warnIfRequestHandlerReplaced("onlistresourcetemplates",this._onlistresourcetemplates,X),this._onlistresourcetemplates=X,this.replaceRequestHandler(dQ,async(Y,Z)=>{if(!this._onlistresourcetemplates)throw Error("No onlistresourcetemplates handler set");return this._onlistresourcetemplates(Y.params,Z)})}_onreadresource;get onreadresource(){return this._onreadresource}set onreadresource(X){this.warnIfRequestHandlerReplaced("onreadresource",this._onreadresource,X),this._onreadresource=X,this.replaceRequestHandler(pQ,async(Y,Z)=>{if(!this._onreadresource)throw Error("No onreadresource handler set");return this._onreadresource(Y.params,Z)})}sendResourceListChanged(X={}){return this.notification({method:"notifications/resources/list_changed",params:X})}_onlistprompts;get onlistprompts(){return this._onlistprompts}set onlistprompts(X){this.warnIfRequestHandlerReplaced("onlistprompts",this._onlistprompts,X),this._onlistprompts=X,this.replaceRequestHandler(yQ,async(Y,Z)=>{if(!this._onlistprompts)throw Error("No onlistprompts handler set");return this._onlistprompts(Y.params,Z)})}sendPromptListChanged(X={}){return this.notification({method:"notifications/prompts/list_changed",params:X})}assertCapabilityForMethod(X){}assertRequestHandlerCapability(X){}assertNotificationCapability(X){}assertTaskCapability(X){throw Error("Tasks are not supported in MCP Apps")}assertTaskHandlerCapability(X){throw Error("Task handlers are not supported in MCP Apps")}getCapabilities(){return this._capabilities}async _oninitialize(X){let Y=X.params.protocolVersion;return this._appCapabilities=X.params.appCapabilities,this._appInfo=X.params.appInfo,{protocolVersion:lQ.includes(Y)?Y:G,hostCapabilities:this.getCapabilities(),hostInfo:this._hostInfo,hostContext:this._hostContext}}setHostContext(X){let Y={},Z=!1;for(let $ of Object.keys(X)){let J=this._hostContext[$],K=X[$];if(tQ(J,K))continue;Y[$]=K,Z=!0}if(Z)this._hostContext=X,this.sendHostContextChange(Y)}sendHostContextChange(X){return this.notification({method:"ui/notifications/host-context-changed",params:X})}sendToolInput(X){return this.notification({method:"ui/notifications/tool-input",params:X})}sendToolInputPartial(X){return this.notification({method:"ui/notifications/tool-input-partial",params:X})}sendToolResult(X){return this.notification({method:"ui/notifications/tool-result",params:X})}sendToolCancelled(X){return this.notification({method:"ui/notifications/tool-cancelled",params:X})}sendSandboxResourceReady(X){return this.notification({method:"ui/notifications/sandbox-resource-ready",params:X})}teardownResource(X,Y){return this.request({method:"ui/resource-teardown",params:X},g,Y)}sendResourceTeardown=this.teardownResource;callTool(X,Y){return this.request({method:"tools/call",params:X},t,Y)}listTools(X,Y){return this.request({method:"tools/list",params:X},uQ,Y)}async connect(X){if(this.transport)throw Error("AppBridge is already connected. Call close() before connecting again.");if(this._client){let Y=this._client.getServerCapabilities();if(!Y)throw Error("Client server capabilities not available");if(Y.tools){if(this.oncalltool=async(Z,$)=>{return this._client.request({method:"tools/call",params:Z},t,{signal:$.signal})},Y.tools.listChanged)this._client.setNotificationHandler(rQ,(Z)=>this.sendToolListChanged(Z.params))}if(Y.resources){if(this.onlistresources=async(Z,$)=>{return this._client.request({method:"resources/list",params:Z},kQ,{signal:$.signal})},this.onlistresourcetemplates=async(Z,$)=>{return this._client.request({method:"resources/templates/list",params:Z},bQ,{signal:$.signal})},this.onreadresource=async(Z,$)=>{return this._client.request({method:"resources/read",params:Z},nQ,{signal:$.signal})},Y.resources.listChanged)this._client.setNotificationHandler(cQ,(Z)=>this.sendResourceListChanged(Z.params))}if(Y.prompts){if(this.onlistprompts=async(Z,$)=>{return this._client.request({method:"prompts/list",params:Z},vQ,{signal:$.signal})},Y.prompts.listChanged)this._client.setNotificationHandler(iQ,(Z)=>this.sendPromptListChanged(Z.params))}}return super.connect(X)}}function tQ(X,Y){return JSON.stringify(X)===JSON.stringify(Y)}export{cY as isToolVisibilityModelOnly,rY as isToolVisibilityAppOnly,nY as getToolUiResourceUri,lY as buildAllowAttribute,JQ as TOOL_RESULT_METHOD,V as TOOL_INPUT_PARTIAL_METHOD,$Q as TOOL_INPUT_METHOD,KQ as TOOL_CANCELLED_METHOD,lQ as SUPPORTED_PROTOCOL_VERSIONS,ZQ as SIZE_CHANGED_METHOD,YQ as SANDBOX_RESOURCE_READY_METHOD,XQ as SANDBOX_PROXY_READY_METHOD,h as RESOURCE_URI_META_KEY,NQ as RESOURCE_TEARDOWN_METHOD,SQ as RESOURCE_MIME_TYPE,DQ as REQUEST_TEARDOWN_METHOD,zQ as REQUEST_DISPLAY_MODE_METHOD,z as PostMessageTransport,a as OPEN_LINK_METHOD,d as McpUiUpdateModelContextRequestSchema,o as McpUiToolVisibilitySchema,v as McpUiToolResultNotificationSchema,LQ as McpUiToolMetaSchema,U as McpUiToolInputPartialNotificationSchema,R as McpUiToolInputNotificationSchema,H as McpUiToolCancelledNotificationSchema,p as McpUiThemeSchema,I as McpUiSupportedContentBlockModalitiesSchema,w as McpUiSizeChangedNotificationSchema,PQ as McpUiSandboxResourceReadyNotificationSchema,T as McpUiSandboxProxyReadyNotificationSchema,g as McpUiResourceTeardownResultSchema,M as McpUiResourceTeardownRequestSchema,E as McpUiResourcePermissionsSchema,FQ as McpUiResourceMetaSchema,B as McpUiResourceCspSchema,C as McpUiRequestTeardownNotificationSchema,q as McpUiRequestDisplayModeResultSchema,_ as McpUiRequestDisplayModeRequestSchema,F as McpUiOpenLinkResultSchema,A as McpUiOpenLinkRequestSchema,P as McpUiMessageResultSchema,y as McpUiMessageRequestSchema,S as McpUiInitializedNotificationSchema,u as McpUiInitializeResultSchema,b as McpUiInitializeRequestSchema,c as McpUiHostStylesSchema,n as McpUiHostCssSchema,x as McpUiHostContextSchema,k as McpUiHostContextChangedNotificationSchema,r as McpUiHostCapabilitiesSchema,L as McpUiDownloadFileResultSchema,f as McpUiDownloadFileRequestSchema,D as McpUiDisplayModeSchema,l as McpUiAppCapabilitiesSchema,QQ as MESSAGE_METHOD,G as LATEST_PROTOCOL_VERSION,WQ as INITIALIZE_METHOD,jQ as INITIALIZED_METHOD,GQ as HOST_CONTEXT_CHANGED_METHOD,e as DOWNLOAD_FILE_METHOD,oQ as AppBridge};

@@ -1,2 +0,2 @@

import{Protocol as qQ}from"@modelcontextprotocol/sdk/shared/protocol.js";import{CallToolRequestSchema as TQ,CallToolResultSchema as RQ,EmptyResultSchema as UQ,ListResourcesResultSchema as HQ,ListToolsRequestSchema as MQ,PingRequestSchema as vQ,ReadResourceResultSchema as bQ}from"@modelcontextprotocol/sdk/types.js";import{JSONRPCMessageSchema as t}from"@modelcontextprotocol/sdk/types.js";var E="2026-01-26",y="ui/open-link",u="ui/download-file",f="ui/message",d="ui/notifications/sandbox-proxy-ready",h="ui/notifications/sandbox-resource-ready",m="ui/notifications/size-changed",i="ui/notifications/tool-input",z="ui/notifications/tool-input-partial",l="ui/notifications/tool-result",r="ui/notifications/tool-cancelled",c="ui/notifications/host-context-changed",p="ui/notifications/request-teardown",n="ui/resource-teardown",a="ui/initialize",o="ui/notifications/initialized",s="ui/request-display-mode";class K{eventTarget;eventSource;messageListener;constructor(X=window.parent,Y){this.eventTarget=X;this.eventSource=Y;this.messageListener=(Z)=>{if(Y&&Z.source!==this.eventSource){console.debug("Ignoring message from unknown source",Z);return}let $=t.safeParse(Z.data);if($.success)console.debug("Parsed message",$.data),this.onmessage?.($.data);else if(Z.data?.jsonrpc!=="2.0")console.debug("Ignoring non-JSON-RPC message",$.error.message,Z);else console.error("Failed to parse message",$.error.message,Z),this.onerror?.(Error("Invalid JSON-RPC message received: "+$.error.message))}}async start(){window.addEventListener("message",this.messageListener)}async send(X,Y){if(X.method!==z)console.debug("Sending message",X);this.eventTarget.postMessage(X,"*")}async close(){window.removeEventListener("message",this.messageListener),this.onclose?.()}onclose;onerror;onmessage;sessionId;setProtocolVersion}import{z as Q}from"zod/v4";import{ContentBlockSchema as H,CallToolResultSchema as e,EmbeddedResourceSchema as QQ,ImplementationSchema as M,RequestIdSchema as XQ,ResourceLinkSchema as YQ,ToolSchema as ZQ}from"@modelcontextprotocol/sdk/types.js";var v=Q.union([Q.literal("light"),Q.literal("dark")]).describe("Color theme preference for the host environment."),D=Q.union([Q.literal("inline"),Q.literal("fullscreen"),Q.literal("pip")]).describe("Display mode for UI presentation."),$Q=Q.union([Q.literal("--color-background-primary"),Q.literal("--color-background-secondary"),Q.literal("--color-background-tertiary"),Q.literal("--color-background-inverse"),Q.literal("--color-background-ghost"),Q.literal("--color-background-info"),Q.literal("--color-background-danger"),Q.literal("--color-background-success"),Q.literal("--color-background-warning"),Q.literal("--color-background-disabled"),Q.literal("--color-text-primary"),Q.literal("--color-text-secondary"),Q.literal("--color-text-tertiary"),Q.literal("--color-text-inverse"),Q.literal("--color-text-ghost"),Q.literal("--color-text-info"),Q.literal("--color-text-danger"),Q.literal("--color-text-success"),Q.literal("--color-text-warning"),Q.literal("--color-text-disabled"),Q.literal("--color-border-primary"),Q.literal("--color-border-secondary"),Q.literal("--color-border-tertiary"),Q.literal("--color-border-inverse"),Q.literal("--color-border-ghost"),Q.literal("--color-border-info"),Q.literal("--color-border-danger"),Q.literal("--color-border-success"),Q.literal("--color-border-warning"),Q.literal("--color-border-disabled"),Q.literal("--color-ring-primary"),Q.literal("--color-ring-secondary"),Q.literal("--color-ring-inverse"),Q.literal("--color-ring-info"),Q.literal("--color-ring-danger"),Q.literal("--color-ring-success"),Q.literal("--color-ring-warning"),Q.literal("--font-sans"),Q.literal("--font-mono"),Q.literal("--font-weight-normal"),Q.literal("--font-weight-medium"),Q.literal("--font-weight-semibold"),Q.literal("--font-weight-bold"),Q.literal("--font-text-xs-size"),Q.literal("--font-text-sm-size"),Q.literal("--font-text-md-size"),Q.literal("--font-text-lg-size"),Q.literal("--font-heading-xs-size"),Q.literal("--font-heading-sm-size"),Q.literal("--font-heading-md-size"),Q.literal("--font-heading-lg-size"),Q.literal("--font-heading-xl-size"),Q.literal("--font-heading-2xl-size"),Q.literal("--font-heading-3xl-size"),Q.literal("--font-text-xs-line-height"),Q.literal("--font-text-sm-line-height"),Q.literal("--font-text-md-line-height"),Q.literal("--font-text-lg-line-height"),Q.literal("--font-heading-xs-line-height"),Q.literal("--font-heading-sm-line-height"),Q.literal("--font-heading-md-line-height"),Q.literal("--font-heading-lg-line-height"),Q.literal("--font-heading-xl-line-height"),Q.literal("--font-heading-2xl-line-height"),Q.literal("--font-heading-3xl-line-height"),Q.literal("--border-radius-xs"),Q.literal("--border-radius-sm"),Q.literal("--border-radius-md"),Q.literal("--border-radius-lg"),Q.literal("--border-radius-xl"),Q.literal("--border-radius-full"),Q.literal("--border-width-regular"),Q.literal("--shadow-hairline"),Q.literal("--shadow-sm"),Q.literal("--shadow-md"),Q.literal("--shadow-lg")]).describe("CSS variable keys available to MCP apps for theming."),DQ=Q.record($Q.describe(`Style variables for theming MCP apps.
import{CallToolRequestSchema as RQ,CallToolResultSchema as UQ,EmptyResultSchema as HQ,ListResourcesResultSchema as MQ,ListToolsRequestSchema as CQ,PingRequestSchema as bQ,ReadResourceResultSchema as kQ}from"@modelcontextprotocol/sdk/types.js";import{Protocol as f}from"@modelcontextprotocol/sdk/shared/protocol.js";class z extends f{_registeredMethods=new Set;_eventSlots=new Map;onEventDispatch(X,Y){}_ensureEventSlot(X){let Y=this._eventSlots.get(X);if(!Y){let Z=this.eventSchemas[X];if(!Z)throw Error(`Unknown event: ${String(X)}`);Y={listeners:[]},this._eventSlots.set(X,Y);let $=Z.shape.method.value;this._registeredMethods.add($);let D=Y;super.setNotificationHandler(Z,(J)=>{let G=J.params;this.onEventDispatch(X,G),D.onHandler?.(G);for(let V of[...D.listeners])V(G)})}return Y}setEventHandler(X,Y){let Z=this._ensureEventSlot(X);if(Z.onHandler&&Y)console.warn(`[MCP Apps] on${String(X)} handler replaced. Use addEventListener("${String(X)}", …) to add multiple listeners without replacing.`);Z.onHandler=Y}getEventHandler(X){return this._eventSlots.get(X)?.onHandler}addEventListener(X,Y){this._ensureEventSlot(X).listeners.push(Y)}removeEventListener(X,Y){let Z=this._eventSlots.get(X);if(!Z)return;let $=Z.listeners.indexOf(Y);if($!==-1)Z.listeners.splice($,1)}setRequestHandler=(X,Y)=>{this._assertMethodNotRegistered(X,"setRequestHandler"),super.setRequestHandler(X,Y)};setNotificationHandler=(X,Y)=>{this._assertMethodNotRegistered(X,"setNotificationHandler"),super.setNotificationHandler(X,Y)};warnIfRequestHandlerReplaced(X,Y,Z){if(Y&&Z)console.warn(`[MCP Apps] ${X} handler replaced. Previous handler will no longer be called.`)}replaceRequestHandler=(X,Y)=>{let Z=X.shape.method.value;this._registeredMethods.add(Z),super.setRequestHandler(X,Y)};_assertMethodNotRegistered(X,Y){let Z=X.shape.method.value;if(this._registeredMethods.has(Z))throw Error(`Handler for "${Z}" already registered (via ${Y}). Use addEventListener() to attach multiple listeners, or the on* setter for replace semantics.`);this._registeredMethods.add(Z)}}import{JSONRPCMessageSchema as QQ}from"@modelcontextprotocol/sdk/types.js";var B="2026-01-26",u="ui/open-link",d="ui/download-file",h="ui/message",i="ui/notifications/sandbox-proxy-ready",m="ui/notifications/sandbox-resource-ready",p="ui/notifications/size-changed",r="ui/notifications/tool-input",E="ui/notifications/tool-input-partial",c="ui/notifications/tool-result",l="ui/notifications/tool-cancelled",n="ui/notifications/host-context-changed",a="ui/notifications/request-teardown",o="ui/resource-teardown",s="ui/initialize",t="ui/notifications/initialized",e="ui/request-display-mode";class N{eventTarget;eventSource;messageListener;constructor(X=window.parent,Y){this.eventTarget=X;this.eventSource=Y;this.messageListener=(Z)=>{if(Y&&Z.source!==this.eventSource){console.debug("Ignoring message from unknown source",Z);return}let $=QQ.safeParse(Z.data);if($.success)console.debug("Parsed message",$.data),this.onmessage?.($.data);else if(Z.data?.jsonrpc!=="2.0")console.debug("Ignoring non-JSON-RPC message",$.error.message,Z);else console.error("Failed to parse message",$.error.message,Z),this.onerror?.(Error("Invalid JSON-RPC message received: "+$.error.message))}}async start(){window.addEventListener("message",this.messageListener)}async send(X,Y){if(X.method!==E)console.debug("Sending message",X);this.eventTarget.postMessage(X,"*")}async close(){window.removeEventListener("message",this.messageListener),this.onclose?.()}onclose;onerror;onmessage;sessionId;setProtocolVersion}import{z as Q}from"zod/v4";import{ContentBlockSchema as C,CallToolResultSchema as XQ,EmbeddedResourceSchema as YQ,ImplementationSchema as b,RequestIdSchema as ZQ,ResourceLinkSchema as $Q,ToolSchema as DQ}from"@modelcontextprotocol/sdk/types.js";var k=Q.union([Q.literal("light"),Q.literal("dark")]).describe("Color theme preference for the host environment."),K=Q.union([Q.literal("inline"),Q.literal("fullscreen"),Q.literal("pip")]).describe("Display mode for UI presentation."),JQ=Q.union([Q.literal("--color-background-primary"),Q.literal("--color-background-secondary"),Q.literal("--color-background-tertiary"),Q.literal("--color-background-inverse"),Q.literal("--color-background-ghost"),Q.literal("--color-background-info"),Q.literal("--color-background-danger"),Q.literal("--color-background-success"),Q.literal("--color-background-warning"),Q.literal("--color-background-disabled"),Q.literal("--color-text-primary"),Q.literal("--color-text-secondary"),Q.literal("--color-text-tertiary"),Q.literal("--color-text-inverse"),Q.literal("--color-text-ghost"),Q.literal("--color-text-info"),Q.literal("--color-text-danger"),Q.literal("--color-text-success"),Q.literal("--color-text-warning"),Q.literal("--color-text-disabled"),Q.literal("--color-border-primary"),Q.literal("--color-border-secondary"),Q.literal("--color-border-tertiary"),Q.literal("--color-border-inverse"),Q.literal("--color-border-ghost"),Q.literal("--color-border-info"),Q.literal("--color-border-danger"),Q.literal("--color-border-success"),Q.literal("--color-border-warning"),Q.literal("--color-border-disabled"),Q.literal("--color-ring-primary"),Q.literal("--color-ring-secondary"),Q.literal("--color-ring-inverse"),Q.literal("--color-ring-info"),Q.literal("--color-ring-danger"),Q.literal("--color-ring-success"),Q.literal("--color-ring-warning"),Q.literal("--font-sans"),Q.literal("--font-mono"),Q.literal("--font-weight-normal"),Q.literal("--font-weight-medium"),Q.literal("--font-weight-semibold"),Q.literal("--font-weight-bold"),Q.literal("--font-text-xs-size"),Q.literal("--font-text-sm-size"),Q.literal("--font-text-md-size"),Q.literal("--font-text-lg-size"),Q.literal("--font-heading-xs-size"),Q.literal("--font-heading-sm-size"),Q.literal("--font-heading-md-size"),Q.literal("--font-heading-lg-size"),Q.literal("--font-heading-xl-size"),Q.literal("--font-heading-2xl-size"),Q.literal("--font-heading-3xl-size"),Q.literal("--font-text-xs-line-height"),Q.literal("--font-text-sm-line-height"),Q.literal("--font-text-md-line-height"),Q.literal("--font-text-lg-line-height"),Q.literal("--font-heading-xs-line-height"),Q.literal("--font-heading-sm-line-height"),Q.literal("--font-heading-md-line-height"),Q.literal("--font-heading-lg-line-height"),Q.literal("--font-heading-xl-line-height"),Q.literal("--font-heading-2xl-line-height"),Q.literal("--font-heading-3xl-line-height"),Q.literal("--border-radius-xs"),Q.literal("--border-radius-sm"),Q.literal("--border-radius-md"),Q.literal("--border-radius-lg"),Q.literal("--border-radius-xl"),Q.literal("--border-radius-full"),Q.literal("--border-width-regular"),Q.literal("--shadow-hairline"),Q.literal("--shadow-sm"),Q.literal("--shadow-md"),Q.literal("--shadow-lg")]).describe("CSS variable keys available to MCP apps for theming."),KQ=Q.record(JQ.describe(`Style variables for theming MCP apps.

@@ -19,6 +19,6 @@ Individual style keys are optional - hosts may provide any subset of these values.

Note: This type uses \`Record<K, string | undefined>\` rather than \`Partial<Record<K, string>>\`
for compatibility with Zod schema generation. Both are functionally equivalent for validation.`),JQ=Q.object({method:Q.literal("ui/open-link"),params:Q.object({url:Q.string().describe("URL to open in the host's browser")})}),B=Q.object({isError:Q.boolean().optional().describe("True if the host failed to open the URL (e.g., due to security policy).")}).passthrough(),_=Q.object({isError:Q.boolean().optional().describe("True if the download failed (e.g., user cancelled or host denied).")}).passthrough(),O=Q.object({isError:Q.boolean().optional().describe("True if the host rejected or failed to deliver the message.")}).passthrough(),KQ=Q.object({method:Q.literal("ui/notifications/sandbox-proxy-ready"),params:Q.object({})}),G=Q.object({connectDomains:Q.array(Q.string()).optional().describe(`Origins for network requests (fetch/XHR/WebSocket).
for compatibility with Zod schema generation. Both are functionally equivalent for validation.`),GQ=Q.object({method:Q.literal("ui/open-link"),params:Q.object({url:Q.string().describe("URL to open in the host's browser")})}),O=Q.object({isError:Q.boolean().optional().describe("True if the host failed to open the URL (e.g., due to security policy).")}).passthrough(),I=Q.object({isError:Q.boolean().optional().describe("True if the download failed (e.g., user cancelled or host denied).")}).passthrough(),w=Q.object({isError:Q.boolean().optional().describe("True if the host rejected or failed to deliver the message.")}).passthrough(),VQ=Q.object({method:Q.literal("ui/notifications/sandbox-proxy-ready"),params:Q.object({})}),W=Q.object({connectDomains:Q.array(Q.string()).optional().describe(`Origins for network requests (fetch/XHR/WebSocket).
- Maps to CSP \`connect-src\` directive
- Empty or omitted → no network connections (secure default)`),resourceDomains:Q.array(Q.string()).optional().describe("Origins for static resources (images, scripts, stylesheets, fonts, media).\n\n- Maps to CSP `img-src`, `script-src`, `style-src`, `font-src`, `media-src` directives\n- Wildcard subdomains supported: `https://*.example.com`\n- Empty or omitted → no network resources (secure default)"),frameDomains:Q.array(Q.string()).optional().describe("Origins for nested iframes.\n\n- Maps to CSP `frame-src` directive\n- Empty or omitted → no nested iframes allowed (`frame-src 'none'`)"),baseUriDomains:Q.array(Q.string()).optional().describe("Allowed base URIs for the document.\n\n- Maps to CSP `base-uri` directive\n- Empty or omitted → only same origin allowed (`base-uri 'self'`)")}),V=Q.object({camera:Q.object({}).optional().describe("Request camera access.\n\nMaps to Permission Policy `camera` feature."),microphone:Q.object({}).optional().describe("Request microphone access.\n\nMaps to Permission Policy `microphone` feature."),geolocation:Q.object({}).optional().describe("Request geolocation access.\n\nMaps to Permission Policy `geolocation` feature."),clipboardWrite:Q.object({}).optional().describe("Request clipboard write access.\n\nMaps to Permission Policy `clipboard-write` feature.")}),GQ=Q.object({method:Q.literal("ui/notifications/size-changed"),params:Q.object({width:Q.number().optional().describe("New width in pixels."),height:Q.number().optional().describe("New height in pixels.")})}),I=Q.object({method:Q.literal("ui/notifications/tool-input"),params:Q.object({arguments:Q.record(Q.string(),Q.unknown().describe("Complete tool call arguments as key-value pairs.")).optional().describe("Complete tool call arguments as key-value pairs.")})}),w=Q.object({method:Q.literal("ui/notifications/tool-input-partial"),params:Q.object({arguments:Q.record(Q.string(),Q.unknown().describe("Partial tool call arguments (incomplete, may change).")).optional().describe("Partial tool call arguments (incomplete, may change).")})}),A=Q.object({method:Q.literal("ui/notifications/tool-cancelled"),params:Q.object({reason:Q.string().optional().describe('Optional reason for the cancellation (e.g., "user action", "timeout").')})}),b=Q.object({fonts:Q.string().optional()}),k=Q.object({variables:DQ.optional().describe("CSS variables for theming the app."),css:b.optional().describe("CSS blocks that apps can inject.")}),F=Q.object({method:Q.literal("ui/resource-teardown"),params:Q.object({})}),VQ=Q.record(Q.string(),Q.unknown()),L=Q.object({text:Q.object({}).optional().describe("Host supports text content blocks."),image:Q.object({}).optional().describe("Host supports image content blocks."),audio:Q.object({}).optional().describe("Host supports audio content blocks."),resource:Q.object({}).optional().describe("Host supports resource content blocks."),resourceLink:Q.object({}).optional().describe("Host supports resource link content blocks."),structuredContent:Q.object({}).optional().describe("Host supports structured content.")}),WQ=Q.object({method:Q.literal("ui/notifications/request-teardown"),params:Q.object({}).optional()}),C=Q.object({experimental:Q.object({}).optional().describe("Experimental features (structure TBD)."),openLinks:Q.object({}).optional().describe("Host supports opening external URLs."),downloadFile:Q.object({}).optional().describe("Host supports file downloads via ui/download-file."),serverTools:Q.object({listChanged:Q.boolean().optional().describe("Host supports tools/list_changed notifications.")}).optional().describe("Host can proxy tool calls to the MCP server."),serverResources:Q.object({listChanged:Q.boolean().optional().describe("Host supports resources/list_changed notifications.")}).optional().describe("Host can proxy resource reads to the MCP server."),logging:Q.object({}).optional().describe("Host accepts log messages."),sandbox:Q.object({permissions:V.optional().describe("Permissions granted by the host (camera, microphone, geolocation)."),csp:G.optional().describe("CSP domains approved by the host.")}).optional().describe("Sandbox configuration applied by the host."),updateModelContext:L.optional().describe("Host accepts context updates (ui/update-model-context) to be included in the model's context for future turns."),message:L.optional().describe("Host supports receiving content messages (ui/message) from the view.")}),x=Q.object({experimental:Q.object({}).optional().describe("Experimental features (structure TBD)."),tools:Q.object({listChanged:Q.boolean().optional().describe("App supports tools/list_changed notifications.")}).optional().describe("App exposes MCP-style tools that the host can call."),availableDisplayModes:Q.array(D).optional().describe("Display modes the app supports.")}),NQ=Q.object({method:Q.literal("ui/notifications/initialized"),params:Q.object({}).optional()}),jQ=Q.object({csp:G.optional().describe("Content Security Policy configuration for UI resources."),permissions:V.optional().describe("Sandbox permissions requested by the UI resource."),domain:Q.string().optional().describe(`Dedicated origin for view sandbox.
- Empty or omitted → no network connections (secure default)`),resourceDomains:Q.array(Q.string()).optional().describe("Origins for static resources (images, scripts, stylesheets, fonts, media).\n\n- Maps to CSP `img-src`, `script-src`, `style-src`, `font-src`, `media-src` directives\n- Wildcard subdomains supported: `https://*.example.com`\n- Empty or omitted → no network resources (secure default)"),frameDomains:Q.array(Q.string()).optional().describe("Origins for nested iframes.\n\n- Maps to CSP `frame-src` directive\n- Empty or omitted → no nested iframes allowed (`frame-src 'none'`)"),baseUriDomains:Q.array(Q.string()).optional().describe("Allowed base URIs for the document.\n\n- Maps to CSP `base-uri` directive\n- Empty or omitted → only same origin allowed (`base-uri 'self'`)")}),j=Q.object({camera:Q.object({}).optional().describe("Request camera access.\n\nMaps to Permission Policy `camera` feature."),microphone:Q.object({}).optional().describe("Request microphone access.\n\nMaps to Permission Policy `microphone` feature."),geolocation:Q.object({}).optional().describe("Request geolocation access.\n\nMaps to Permission Policy `geolocation` feature."),clipboardWrite:Q.object({}).optional().describe("Request clipboard write access.\n\nMaps to Permission Policy `clipboard-write` feature.")}),NQ=Q.object({method:Q.literal("ui/notifications/size-changed"),params:Q.object({width:Q.number().optional().describe("New width in pixels."),height:Q.number().optional().describe("New height in pixels.")})}),A=Q.object({method:Q.literal("ui/notifications/tool-input"),params:Q.object({arguments:Q.record(Q.string(),Q.unknown().describe("Complete tool call arguments as key-value pairs.")).optional().describe("Complete tool call arguments as key-value pairs.")})}),F=Q.object({method:Q.literal("ui/notifications/tool-input-partial"),params:Q.object({arguments:Q.record(Q.string(),Q.unknown().describe("Partial tool call arguments (incomplete, may change).")).optional().describe("Partial tool call arguments (incomplete, may change).")})}),P=Q.object({method:Q.literal("ui/notifications/tool-cancelled"),params:Q.object({reason:Q.string().optional().describe('Optional reason for the cancellation (e.g., "user action", "timeout").')})}),g=Q.object({fonts:Q.string().optional()}),x=Q.object({variables:KQ.optional().describe("CSS variables for theming the app."),css:g.optional().describe("CSS blocks that apps can inject.")}),q=Q.object({method:Q.literal("ui/resource-teardown"),params:Q.object({})}),WQ=Q.record(Q.string(),Q.unknown()),_=Q.object({text:Q.object({}).optional().describe("Host supports text content blocks."),image:Q.object({}).optional().describe("Host supports image content blocks."),audio:Q.object({}).optional().describe("Host supports audio content blocks."),resource:Q.object({}).optional().describe("Host supports resource content blocks."),resourceLink:Q.object({}).optional().describe("Host supports resource link content blocks."),structuredContent:Q.object({}).optional().describe("Host supports structured content.")}),jQ=Q.object({method:Q.literal("ui/notifications/request-teardown"),params:Q.object({}).optional()}),S=Q.object({experimental:Q.object({}).optional().describe("Experimental features (structure TBD)."),openLinks:Q.object({}).optional().describe("Host supports opening external URLs."),downloadFile:Q.object({}).optional().describe("Host supports file downloads via ui/download-file."),serverTools:Q.object({listChanged:Q.boolean().optional().describe("Host supports tools/list_changed notifications.")}).optional().describe("Host can proxy tool calls to the MCP server."),serverResources:Q.object({listChanged:Q.boolean().optional().describe("Host supports resources/list_changed notifications.")}).optional().describe("Host can proxy resource reads to the MCP server."),logging:Q.object({}).optional().describe("Host accepts log messages."),sandbox:Q.object({permissions:j.optional().describe("Permissions granted by the host (camera, microphone, geolocation)."),csp:W.optional().describe("CSP domains approved by the host.")}).optional().describe("Sandbox configuration applied by the host."),updateModelContext:_.optional().describe("Host accepts context updates (ui/update-model-context) to be included in the model's context for future turns."),message:_.optional().describe("Host supports receiving content messages (ui/message) from the view.")}),y=Q.object({experimental:Q.object({}).optional().describe("Experimental features (structure TBD)."),tools:Q.object({listChanged:Q.boolean().optional().describe("App supports tools/list_changed notifications.")}).optional().describe("App exposes MCP-style tools that the host can call."),availableDisplayModes:Q.array(K).optional().describe("Display modes the app supports.")}),LQ=Q.object({method:Q.literal("ui/notifications/initialized"),params:Q.object({}).optional()}),zQ=Q.object({csp:W.optional().describe("Content Security Policy configuration for UI resources."),permissions:j.optional().describe("Sandbox permissions requested by the UI resource."),domain:Q.string().optional().describe(`Dedicated origin for view sandbox.

@@ -37,5 +37,5 @@ Useful when views need stable, dedicated origins for OAuth callbacks, CORS policies, or API key allowlists.

- \`false\`: request no visible border + background
- omitted: host decides border`)}),EQ=Q.object({method:Q.literal("ui/request-display-mode"),params:Q.object({mode:D.describe("The display mode being requested.")})}),P=Q.object({mode:D.describe("The display mode that was actually set. May differ from requested if not supported.")}).passthrough(),g=Q.union([Q.literal("model"),Q.literal("app")]).describe("Tool visibility scope - who can access the tool."),zQ=Q.object({resourceUri:Q.string().optional(),visibility:Q.array(g).optional().describe(`Who can access this tool. Default: ["model", "app"]
- omitted: host decides border`)}),BQ=Q.object({method:Q.literal("ui/request-display-mode"),params:Q.object({mode:K.describe("The display mode being requested.")})}),T=Q.object({mode:K.describe("The display mode that was actually set. May differ from requested if not supported.")}).passthrough(),v=Q.union([Q.literal("model"),Q.literal("app")]).describe("Tool visibility scope - who can access the tool."),EQ=Q.object({resourceUri:Q.string().optional(),visibility:Q.array(v).optional().describe(`Who can access this tool. Default: ["model", "app"]
- "model": Tool visible to and callable by the agent
- "app": Tool callable by the app from this server only`)}),hQ=Q.object({mimeTypes:Q.array(Q.string()).optional().describe('Array of supported MIME types for UI resources.\nMust include `"text/html;profile=mcp-app"` for MCP Apps support.')}),LQ=Q.object({method:Q.literal("ui/download-file"),params:Q.object({contents:Q.array(Q.union([QQ,YQ])).describe("Resource contents to download — embedded (inline data) or linked (host fetches). Uses standard MCP resource types.")})}),BQ=Q.object({method:Q.literal("ui/message"),params:Q.object({role:Q.literal("user").describe('Message role, currently only "user" is supported.'),content:Q.array(H).describe("Message content blocks (text, image, etc.).")})}),_Q=Q.object({method:Q.literal("ui/notifications/sandbox-resource-ready"),params:Q.object({html:Q.string().describe("HTML content to load into the inner iframe."),sandbox:Q.string().optional().describe("Optional override for the inner iframe's sandbox attribute."),csp:G.optional().describe("CSP configuration from resource metadata."),permissions:V.optional().describe("Sandbox permissions from resource metadata.")})}),q=Q.object({method:Q.literal("ui/notifications/tool-result"),params:e.describe("Standard MCP tool execution result.")}),T=Q.object({toolInfo:Q.object({id:XQ.optional().describe("JSON-RPC id of the tools/call request."),tool:ZQ.describe("Tool definition including name, inputSchema, etc.")}).optional().describe("Metadata of the tool call that instantiated this App."),theme:v.optional().describe("Current color theme preference."),styles:k.optional().describe("Style configuration for theming the app."),displayMode:D.optional().describe("How the UI is currently displayed."),availableDisplayModes:Q.array(D).optional().describe("Display modes the host supports."),containerDimensions:Q.union([Q.object({height:Q.number().describe("Fixed container height in pixels.")}),Q.object({maxHeight:Q.union([Q.number(),Q.undefined()]).optional().describe("Maximum container height in pixels.")})]).and(Q.union([Q.object({width:Q.number().describe("Fixed container width in pixels.")}),Q.object({maxWidth:Q.union([Q.number(),Q.undefined()]).optional().describe("Maximum container width in pixels.")})])).optional().describe(`Container dimensions. Represents the dimensions of the iframe or other
container holding the app. Specify either width or maxWidth, and either height or maxHeight.`),locale:Q.string().optional().describe("User's language and region preference in BCP 47 format."),timeZone:Q.string().optional().describe("User's timezone in IANA format."),userAgent:Q.string().optional().describe("Host application identifier."),platform:Q.union([Q.literal("web"),Q.literal("desktop"),Q.literal("mobile")]).optional().describe("Platform type for responsive design decisions."),deviceCapabilities:Q.object({touch:Q.boolean().optional().describe("Whether the device supports touch input."),hover:Q.boolean().optional().describe("Whether the device supports hover interactions.")}).optional().describe("Device input capabilities."),safeAreaInsets:Q.object({top:Q.number().describe("Top safe area inset in pixels."),right:Q.number().describe("Right safe area inset in pixels."),bottom:Q.number().describe("Bottom safe area inset in pixels."),left:Q.number().describe("Left safe area inset in pixels.")}).optional().describe("Mobile safe area boundaries in pixels.")}).passthrough(),R=Q.object({method:Q.literal("ui/notifications/host-context-changed"),params:T.describe("Partial context update containing only changed fields.")}),OQ=Q.object({method:Q.literal("ui/update-model-context"),params:Q.object({content:Q.array(H).optional().describe("Context content blocks (text, image, etc.)."),structuredContent:Q.record(Q.string(),Q.unknown().describe("Structured content for machine-readable context data.")).optional().describe("Structured content for machine-readable context data.")})}),IQ=Q.object({method:Q.literal("ui/initialize"),params:Q.object({appInfo:M.describe("App identification (name and version)."),appCapabilities:x.describe("Features and capabilities this app provides."),protocolVersion:Q.string().describe("Protocol version this app supports.")})}),U=Q.object({protocolVersion:Q.string().describe('Negotiated protocol version string (e.g., "2025-11-21").'),hostInfo:M.describe("Host application identification and version."),hostCapabilities:C.describe("Features and capabilities provided by the host."),hostContext:T.describe("Rich context about the host environment.")}).passthrough();function wQ(){let X=document.documentElement.getAttribute("data-theme");if(X==="dark"||X==="light")return X;return document.documentElement.classList.contains("dark")?"dark":"light"}function AQ(X){let Y=document.documentElement;Y.setAttribute("data-theme",X),Y.style.colorScheme=X}function FQ(X,Y=document.documentElement){for(let[Z,$]of Object.entries(X))if($!==void 0)Y.style.setProperty(Z,$)}function PQ(X){if(document.getElementById("__mcp-host-fonts"))return;let Z=document.createElement("style");Z.id="__mcp-host-fonts",Z.textContent=X,document.head.appendChild(Z)}var RX="ui/resourceUri",UX="text/html;profile=mcp-app";class kQ extends qQ{_appInfo;_capabilities;options;_hostCapabilities;_hostInfo;_hostContext;constructor(X,Y={},Z={autoResize:!0}){super(Z);this._appInfo=X;this._capabilities=Y;this.options=Z;this.setRequestHandler(vQ,($)=>{return console.log("Received ping:",$.params),{}}),this.onhostcontextchanged=()=>{}}getHostCapabilities(){return this._hostCapabilities}getHostVersion(){return this._hostInfo}getHostContext(){return this._hostContext}set ontoolinput(X){this.setNotificationHandler(I,(Y)=>X(Y.params))}set ontoolinputpartial(X){this.setNotificationHandler(w,(Y)=>X(Y.params))}set ontoolresult(X){this.setNotificationHandler(q,(Y)=>X(Y.params))}set ontoolcancelled(X){this.setNotificationHandler(A,(Y)=>X(Y.params))}set onhostcontextchanged(X){this.setNotificationHandler(R,(Y)=>{this._hostContext={...this._hostContext,...Y.params},X(Y.params)})}set onteardown(X){this.setRequestHandler(F,(Y,Z)=>X(Y.params,Z))}set oncalltool(X){this.setRequestHandler(TQ,(Y,Z)=>X(Y.params,Z))}set onlisttools(X){this.setRequestHandler(MQ,(Y,Z)=>X(Y.params,Z))}assertCapabilityForMethod(X){}assertRequestHandlerCapability(X){switch(X){case"tools/call":case"tools/list":if(!this._capabilities.tools)throw Error(`Client does not support tool capability (required for ${X})`);return;case"ping":case"ui/resource-teardown":return;default:throw Error(`No handler for method ${X} registered`)}}assertNotificationCapability(X){}assertTaskCapability(X){throw Error("Tasks are not supported in MCP Apps")}assertTaskHandlerCapability(X){throw Error("Task handlers are not supported in MCP Apps")}async callServerTool(X,Y){if(typeof X==="string")throw Error(`callServerTool() expects an object as its first argument, but received a string ("${X}"). Did you mean: callServerTool({ name: "${X}", arguments: { ... } })?`);return await this.request({method:"tools/call",params:X},RQ,Y)}async readServerResource(X,Y){return await this.request({method:"resources/read",params:X},bQ,Y)}async listServerResources(X,Y){return await this.request({method:"resources/list",params:X},HQ,Y)}sendMessage(X,Y){return this.request({method:"ui/message",params:X},O,Y)}sendLog(X){return this.notification({method:"notifications/message",params:X})}updateModelContext(X,Y){return this.request({method:"ui/update-model-context",params:X},UQ,Y)}openLink(X,Y){return this.request({method:"ui/open-link",params:X},B,Y)}sendOpenLink=this.openLink;downloadFile(X,Y){return this.request({method:"ui/download-file",params:X},_,Y)}requestTeardown(X={}){return this.notification({method:"ui/notifications/request-teardown",params:X})}requestDisplayMode(X,Y){return this.request({method:"ui/request-display-mode",params:X},P,Y)}sendSizeChanged(X){return this.notification({method:"ui/notifications/size-changed",params:X})}setupSizeChangedNotifications(){let X=!1,Y=0,Z=0,$=()=>{if(X)return;X=!0,requestAnimationFrame(()=>{X=!1;let J=document.documentElement,S=J.style.height;J.style.height="max-content";let N=Math.ceil(J.getBoundingClientRect().height);J.style.height=S;let j=Math.ceil(window.innerWidth);if(j!==Y||N!==Z)Y=j,Z=N,this.sendSizeChanged({width:j,height:N})})};$();let W=new ResizeObserver($);return W.observe(document.documentElement),W.observe(document.body),()=>W.disconnect()}async connect(X=new K(window.parent,window.parent),Y){if(this.transport)throw Error("App is already connected. Call close() before connecting again.");await super.connect(X);try{let Z=await this.request({method:"ui/initialize",params:{appCapabilities:this._capabilities,appInfo:this._appInfo,protocolVersion:E}},U,Y);if(Z===void 0)throw Error(`Server sent invalid initialize result: ${Z}`);if(this._hostCapabilities=Z.hostCapabilities,this._hostInfo=Z.hostInfo,this._hostContext=Z.hostContext,await this.notification({method:"ui/notifications/initialized"}),this.options?.autoResize)this.setupSizeChangedNotifications()}catch(Z){throw this.close(),Z}}}export{wQ as getDocumentTheme,FQ as applyHostStyleVariables,PQ as applyHostFonts,AQ as applyDocumentTheme,l as TOOL_RESULT_METHOD,z as TOOL_INPUT_PARTIAL_METHOD,i as TOOL_INPUT_METHOD,r as TOOL_CANCELLED_METHOD,m as SIZE_CHANGED_METHOD,h as SANDBOX_RESOURCE_READY_METHOD,d as SANDBOX_PROXY_READY_METHOD,RX as RESOURCE_URI_META_KEY,n as RESOURCE_TEARDOWN_METHOD,UX as RESOURCE_MIME_TYPE,p as REQUEST_TEARDOWN_METHOD,s as REQUEST_DISPLAY_MODE_METHOD,K as PostMessageTransport,y as OPEN_LINK_METHOD,OQ as McpUiUpdateModelContextRequestSchema,g as McpUiToolVisibilitySchema,q as McpUiToolResultNotificationSchema,zQ as McpUiToolMetaSchema,w as McpUiToolInputPartialNotificationSchema,I as McpUiToolInputNotificationSchema,A as McpUiToolCancelledNotificationSchema,v as McpUiThemeSchema,L as McpUiSupportedContentBlockModalitiesSchema,GQ as McpUiSizeChangedNotificationSchema,_Q as McpUiSandboxResourceReadyNotificationSchema,KQ as McpUiSandboxProxyReadyNotificationSchema,VQ as McpUiResourceTeardownResultSchema,F as McpUiResourceTeardownRequestSchema,V as McpUiResourcePermissionsSchema,jQ as McpUiResourceMetaSchema,G as McpUiResourceCspSchema,WQ as McpUiRequestTeardownNotificationSchema,P as McpUiRequestDisplayModeResultSchema,EQ as McpUiRequestDisplayModeRequestSchema,B as McpUiOpenLinkResultSchema,JQ as McpUiOpenLinkRequestSchema,O as McpUiMessageResultSchema,BQ as McpUiMessageRequestSchema,NQ as McpUiInitializedNotificationSchema,U as McpUiInitializeResultSchema,IQ as McpUiInitializeRequestSchema,k as McpUiHostStylesSchema,b as McpUiHostCssSchema,T as McpUiHostContextSchema,R as McpUiHostContextChangedNotificationSchema,C as McpUiHostCapabilitiesSchema,_ as McpUiDownloadFileResultSchema,LQ as McpUiDownloadFileRequestSchema,D as McpUiDisplayModeSchema,x as McpUiAppCapabilitiesSchema,f as MESSAGE_METHOD,E as LATEST_PROTOCOL_VERSION,a as INITIALIZE_METHOD,o as INITIALIZED_METHOD,c as HOST_CONTEXT_CHANGED_METHOD,u as DOWNLOAD_FILE_METHOD,kQ as App};
- "app": Tool callable by the app from this server only`)}),pQ=Q.object({mimeTypes:Q.array(Q.string()).optional().describe('Array of supported MIME types for UI resources.\nMust include `"text/html;profile=mcp-app"` for MCP Apps support.')}),_Q=Q.object({method:Q.literal("ui/download-file"),params:Q.object({contents:Q.array(Q.union([YQ,$Q])).describe("Resource contents to download — embedded (inline data) or linked (host fetches). Uses standard MCP resource types.")})}),OQ=Q.object({method:Q.literal("ui/message"),params:Q.object({role:Q.literal("user").describe('Message role, currently only "user" is supported.'),content:Q.array(C).describe("Message content blocks (text, image, etc.).")})}),IQ=Q.object({method:Q.literal("ui/notifications/sandbox-resource-ready"),params:Q.object({html:Q.string().describe("HTML content to load into the inner iframe."),sandbox:Q.string().optional().describe("Optional override for the inner iframe's sandbox attribute."),csp:W.optional().describe("CSP configuration from resource metadata."),permissions:j.optional().describe("Sandbox permissions from resource metadata.")})}),R=Q.object({method:Q.literal("ui/notifications/tool-result"),params:XQ.describe("Standard MCP tool execution result.")}),U=Q.object({toolInfo:Q.object({id:ZQ.optional().describe("JSON-RPC id of the tools/call request."),tool:DQ.describe("Tool definition including name, inputSchema, etc.")}).optional().describe("Metadata of the tool call that instantiated this App."),theme:k.optional().describe("Current color theme preference."),styles:x.optional().describe("Style configuration for theming the app."),displayMode:K.optional().describe("How the UI is currently displayed."),availableDisplayModes:Q.array(K).optional().describe("Display modes the host supports."),containerDimensions:Q.union([Q.object({height:Q.number().describe("Fixed container height in pixels.")}),Q.object({maxHeight:Q.union([Q.number(),Q.undefined()]).optional().describe("Maximum container height in pixels.")})]).and(Q.union([Q.object({width:Q.number().describe("Fixed container width in pixels.")}),Q.object({maxWidth:Q.union([Q.number(),Q.undefined()]).optional().describe("Maximum container width in pixels.")})])).optional().describe(`Container dimensions. Represents the dimensions of the iframe or other
container holding the app. Specify either width or maxWidth, and either height or maxHeight.`),locale:Q.string().optional().describe("User's language and region preference in BCP 47 format."),timeZone:Q.string().optional().describe("User's timezone in IANA format."),userAgent:Q.string().optional().describe("Host application identifier."),platform:Q.union([Q.literal("web"),Q.literal("desktop"),Q.literal("mobile")]).optional().describe("Platform type for responsive design decisions."),deviceCapabilities:Q.object({touch:Q.boolean().optional().describe("Whether the device supports touch input."),hover:Q.boolean().optional().describe("Whether the device supports hover interactions.")}).optional().describe("Device input capabilities."),safeAreaInsets:Q.object({top:Q.number().describe("Top safe area inset in pixels."),right:Q.number().describe("Right safe area inset in pixels."),bottom:Q.number().describe("Bottom safe area inset in pixels."),left:Q.number().describe("Left safe area inset in pixels.")}).optional().describe("Mobile safe area boundaries in pixels.")}).passthrough(),H=Q.object({method:Q.literal("ui/notifications/host-context-changed"),params:U.describe("Partial context update containing only changed fields.")}),wQ=Q.object({method:Q.literal("ui/update-model-context"),params:Q.object({content:Q.array(C).optional().describe("Context content blocks (text, image, etc.)."),structuredContent:Q.record(Q.string(),Q.unknown().describe("Structured content for machine-readable context data.")).optional().describe("Structured content for machine-readable context data.")})}),AQ=Q.object({method:Q.literal("ui/initialize"),params:Q.object({appInfo:b.describe("App identification (name and version)."),appCapabilities:y.describe("Features and capabilities this app provides."),protocolVersion:Q.string().describe("Protocol version this app supports.")})}),M=Q.object({protocolVersion:Q.string().describe('Negotiated protocol version string (e.g., "2025-11-21").'),hostInfo:b.describe("Host application identification and version."),hostCapabilities:S.describe("Features and capabilities provided by the host."),hostContext:U.describe("Rich context about the host environment.")}).passthrough();function FQ(){let X=document.documentElement.getAttribute("data-theme");if(X==="dark"||X==="light")return X;return document.documentElement.classList.contains("dark")?"dark":"light"}function PQ(X){let Y=document.documentElement;Y.setAttribute("data-theme",X),Y.style.colorScheme=X}function qQ(X,Y=document.documentElement){for(let[Z,$]of Object.entries(X))if($!==void 0)Y.style.setProperty(Z,$)}function TQ(X){if(document.getElementById("__mcp-host-fonts"))return;let Z=document.createElement("style");Z.id="__mcp-host-fonts",Z.textContent=X,document.head.appendChild(Z)}var MX="ui/resourceUri",CX="text/html;profile=mcp-app";class gQ extends z{_appInfo;_capabilities;options;_hostCapabilities;_hostInfo;_hostContext;eventSchemas={toolinput:A,toolinputpartial:F,toolresult:R,toolcancelled:P,hostcontextchanged:H};onEventDispatch(X,Y){if(X==="hostcontextchanged")this._hostContext={...this._hostContext,...Y}}constructor(X,Y={},Z={autoResize:!0}){super(Z);this._appInfo=X;this._capabilities=Y;this.options=Z;this.setRequestHandler(bQ,($)=>{return console.log("Received ping:",$.params),{}}),this.setEventHandler("hostcontextchanged",void 0)}getHostCapabilities(){return this._hostCapabilities}getHostVersion(){return this._hostInfo}getHostContext(){return this._hostContext}get ontoolinput(){return this.getEventHandler("toolinput")}set ontoolinput(X){this.setEventHandler("toolinput",X)}get ontoolinputpartial(){return this.getEventHandler("toolinputpartial")}set ontoolinputpartial(X){this.setEventHandler("toolinputpartial",X)}get ontoolresult(){return this.getEventHandler("toolresult")}set ontoolresult(X){this.setEventHandler("toolresult",X)}get ontoolcancelled(){return this.getEventHandler("toolcancelled")}set ontoolcancelled(X){this.setEventHandler("toolcancelled",X)}get onhostcontextchanged(){return this.getEventHandler("hostcontextchanged")}set onhostcontextchanged(X){this.setEventHandler("hostcontextchanged",X)}_onteardown;get onteardown(){return this._onteardown}set onteardown(X){this.warnIfRequestHandlerReplaced("onteardown",this._onteardown,X),this._onteardown=X,this.replaceRequestHandler(q,(Y,Z)=>{if(!this._onteardown)throw Error("No onteardown handler set");return this._onteardown(Y.params,Z)})}_oncalltool;get oncalltool(){return this._oncalltool}set oncalltool(X){this.warnIfRequestHandlerReplaced("oncalltool",this._oncalltool,X),this._oncalltool=X,this.replaceRequestHandler(RQ,(Y,Z)=>{if(!this._oncalltool)throw Error("No oncalltool handler set");return this._oncalltool(Y.params,Z)})}_onlisttools;get onlisttools(){return this._onlisttools}set onlisttools(X){this.warnIfRequestHandlerReplaced("onlisttools",this._onlisttools,X),this._onlisttools=X,this.replaceRequestHandler(CQ,(Y,Z)=>{if(!this._onlisttools)throw Error("No onlisttools handler set");return this._onlisttools(Y.params,Z)})}assertCapabilityForMethod(X){}assertRequestHandlerCapability(X){switch(X){case"tools/call":case"tools/list":if(!this._capabilities.tools)throw Error(`Client does not support tool capability (required for ${X})`);return;case"ping":case"ui/resource-teardown":return;default:throw Error(`No handler for method ${X} registered`)}}assertNotificationCapability(X){}assertTaskCapability(X){throw Error("Tasks are not supported in MCP Apps")}assertTaskHandlerCapability(X){throw Error("Task handlers are not supported in MCP Apps")}async callServerTool(X,Y){if(typeof X==="string")throw Error(`callServerTool() expects an object as its first argument, but received a string ("${X}"). Did you mean: callServerTool({ name: "${X}", arguments: { ... } })?`);return await this.request({method:"tools/call",params:X},UQ,Y)}async readServerResource(X,Y){return await this.request({method:"resources/read",params:X},kQ,Y)}async listServerResources(X,Y){return await this.request({method:"resources/list",params:X},MQ,Y)}sendMessage(X,Y){return this.request({method:"ui/message",params:X},w,Y)}sendLog(X){return this.notification({method:"notifications/message",params:X})}updateModelContext(X,Y){return this.request({method:"ui/update-model-context",params:X},HQ,Y)}openLink(X,Y){return this.request({method:"ui/open-link",params:X},O,Y)}sendOpenLink=this.openLink;downloadFile(X,Y){return this.request({method:"ui/download-file",params:X},I,Y)}requestTeardown(X={}){return this.notification({method:"ui/notifications/request-teardown",params:X})}requestDisplayMode(X,Y){return this.request({method:"ui/request-display-mode",params:X},T,Y)}sendSizeChanged(X){return this.notification({method:"ui/notifications/size-changed",params:X})}setupSizeChangedNotifications(){let X=!1,Y=0,Z=0,$=()=>{if(X)return;X=!0,requestAnimationFrame(()=>{X=!1;let J=document.documentElement,G=J.style.height;J.style.height="max-content";let V=Math.ceil(J.getBoundingClientRect().height);J.style.height=G;let L=Math.ceil(window.innerWidth);if(L!==Y||V!==Z)Y=L,Z=V,this.sendSizeChanged({width:L,height:V})})};$();let D=new ResizeObserver($);return D.observe(document.documentElement),D.observe(document.body),()=>D.disconnect()}async connect(X=new N(window.parent,window.parent),Y){if(this.transport)throw Error("App is already connected. Call close() before connecting again.");await super.connect(X);try{let Z=await this.request({method:"ui/initialize",params:{appCapabilities:this._capabilities,appInfo:this._appInfo,protocolVersion:B}},M,Y);if(Z===void 0)throw Error(`Server sent invalid initialize result: ${Z}`);if(this._hostCapabilities=Z.hostCapabilities,this._hostInfo=Z.hostInfo,this._hostContext=Z.hostContext,await this.notification({method:"ui/notifications/initialized"}),this.options?.autoResize)this.setupSizeChangedNotifications()}catch(Z){throw this.close(),Z}}}export{FQ as getDocumentTheme,qQ as applyHostStyleVariables,TQ as applyHostFonts,PQ as applyDocumentTheme,c as TOOL_RESULT_METHOD,E as TOOL_INPUT_PARTIAL_METHOD,r as TOOL_INPUT_METHOD,l as TOOL_CANCELLED_METHOD,p as SIZE_CHANGED_METHOD,m as SANDBOX_RESOURCE_READY_METHOD,i as SANDBOX_PROXY_READY_METHOD,MX as RESOURCE_URI_META_KEY,o as RESOURCE_TEARDOWN_METHOD,CX as RESOURCE_MIME_TYPE,a as REQUEST_TEARDOWN_METHOD,e as REQUEST_DISPLAY_MODE_METHOD,z as ProtocolWithEvents,N as PostMessageTransport,u as OPEN_LINK_METHOD,wQ as McpUiUpdateModelContextRequestSchema,v as McpUiToolVisibilitySchema,R as McpUiToolResultNotificationSchema,EQ as McpUiToolMetaSchema,F as McpUiToolInputPartialNotificationSchema,A as McpUiToolInputNotificationSchema,P as McpUiToolCancelledNotificationSchema,k as McpUiThemeSchema,_ as McpUiSupportedContentBlockModalitiesSchema,NQ as McpUiSizeChangedNotificationSchema,IQ as McpUiSandboxResourceReadyNotificationSchema,VQ as McpUiSandboxProxyReadyNotificationSchema,WQ as McpUiResourceTeardownResultSchema,q as McpUiResourceTeardownRequestSchema,j as McpUiResourcePermissionsSchema,zQ as McpUiResourceMetaSchema,W as McpUiResourceCspSchema,jQ as McpUiRequestTeardownNotificationSchema,T as McpUiRequestDisplayModeResultSchema,BQ as McpUiRequestDisplayModeRequestSchema,O as McpUiOpenLinkResultSchema,GQ as McpUiOpenLinkRequestSchema,w as McpUiMessageResultSchema,OQ as McpUiMessageRequestSchema,LQ as McpUiInitializedNotificationSchema,M as McpUiInitializeResultSchema,AQ as McpUiInitializeRequestSchema,x as McpUiHostStylesSchema,g as McpUiHostCssSchema,U as McpUiHostContextSchema,H as McpUiHostContextChangedNotificationSchema,S as McpUiHostCapabilitiesSchema,I as McpUiDownloadFileResultSchema,_Q as McpUiDownloadFileRequestSchema,K as McpUiDisplayModeSchema,y as McpUiAppCapabilitiesSchema,h as MESSAGE_METHOD,B as LATEST_PROTOCOL_VERSION,s as INITIALIZE_METHOD,t as INITIALIZED_METHOD,n as HOST_CONTEXT_CHANGED_METHOD,d as DOWNLOAD_FILE_METHOD,gQ as App};

@@ -1,2 +0,2 @@

import{useEffect as uJ,useState as f}from"react";import{Protocol as bJ}from"@modelcontextprotocol/sdk/shared/protocol.js";import{CallToolRequestSchema as SJ,CallToolResultSchema as CJ,EmptyResultSchema as gJ,ListResourcesResultSchema as xJ,ListToolsRequestSchema as yJ,PingRequestSchema as fJ,ReadResourceResultSchema as dJ}from"@modelcontextprotocol/sdk/types.js";import{JSONRPCMessageSchema as LJ}from"@modelcontextprotocol/sdk/types.js";var R="2026-01-26",o="ui/open-link",a="ui/download-file",s="ui/message",t="ui/notifications/sandbox-proxy-ready",e="ui/notifications/sandbox-resource-ready",JJ="ui/notifications/size-changed",KJ="ui/notifications/tool-input",z="ui/notifications/tool-input-partial",QJ="ui/notifications/tool-result",XJ="ui/notifications/tool-cancelled",YJ="ui/notifications/host-context-changed",ZJ="ui/notifications/request-teardown",$J="ui/resource-teardown",GJ="ui/initialize",WJ="ui/notifications/initialized",jJ="ui/request-display-mode";class W{eventTarget;eventSource;messageListener;constructor(K=window.parent,Q){this.eventTarget=K;this.eventSource=Q;this.messageListener=(X)=>{if(Q&&X.source!==this.eventSource){console.debug("Ignoring message from unknown source",X);return}let Y=LJ.safeParse(X.data);if(Y.success)console.debug("Parsed message",Y.data),this.onmessage?.(Y.data);else if(X.data?.jsonrpc!=="2.0")console.debug("Ignoring non-JSON-RPC message",Y.error.message,X);else console.error("Failed to parse message",Y.error.message,X),this.onerror?.(Error("Invalid JSON-RPC message received: "+Y.error.message))}}async start(){window.addEventListener("message",this.messageListener)}async send(K,Q){if(K.method!==z)console.debug("Sending message",K);this.eventTarget.postMessage(K,"*")}async close(){window.removeEventListener("message",this.messageListener),this.onclose?.()}onclose;onerror;onmessage;sessionId;setProtocolVersion}import{z as J}from"zod/v4";import{ContentBlockSchema as d,CallToolResultSchema as NJ,EmbeddedResourceSchema as BJ,ImplementationSchema as u,RequestIdSchema as VJ,ResourceLinkSchema as PJ,ToolSchema as _J}from"@modelcontextprotocol/sdk/types.js";var h=J.union([J.literal("light"),J.literal("dark")]).describe("Color theme preference for the host environment."),j=J.union([J.literal("inline"),J.literal("fullscreen"),J.literal("pip")]).describe("Display mode for UI presentation."),OJ=J.union([J.literal("--color-background-primary"),J.literal("--color-background-secondary"),J.literal("--color-background-tertiary"),J.literal("--color-background-inverse"),J.literal("--color-background-ghost"),J.literal("--color-background-info"),J.literal("--color-background-danger"),J.literal("--color-background-success"),J.literal("--color-background-warning"),J.literal("--color-background-disabled"),J.literal("--color-text-primary"),J.literal("--color-text-secondary"),J.literal("--color-text-tertiary"),J.literal("--color-text-inverse"),J.literal("--color-text-ghost"),J.literal("--color-text-info"),J.literal("--color-text-danger"),J.literal("--color-text-success"),J.literal("--color-text-warning"),J.literal("--color-text-disabled"),J.literal("--color-border-primary"),J.literal("--color-border-secondary"),J.literal("--color-border-tertiary"),J.literal("--color-border-inverse"),J.literal("--color-border-ghost"),J.literal("--color-border-info"),J.literal("--color-border-danger"),J.literal("--color-border-success"),J.literal("--color-border-warning"),J.literal("--color-border-disabled"),J.literal("--color-ring-primary"),J.literal("--color-ring-secondary"),J.literal("--color-ring-inverse"),J.literal("--color-ring-info"),J.literal("--color-ring-danger"),J.literal("--color-ring-success"),J.literal("--color-ring-warning"),J.literal("--font-sans"),J.literal("--font-mono"),J.literal("--font-weight-normal"),J.literal("--font-weight-medium"),J.literal("--font-weight-semibold"),J.literal("--font-weight-bold"),J.literal("--font-text-xs-size"),J.literal("--font-text-sm-size"),J.literal("--font-text-md-size"),J.literal("--font-text-lg-size"),J.literal("--font-heading-xs-size"),J.literal("--font-heading-sm-size"),J.literal("--font-heading-md-size"),J.literal("--font-heading-lg-size"),J.literal("--font-heading-xl-size"),J.literal("--font-heading-2xl-size"),J.literal("--font-heading-3xl-size"),J.literal("--font-text-xs-line-height"),J.literal("--font-text-sm-line-height"),J.literal("--font-text-md-line-height"),J.literal("--font-text-lg-line-height"),J.literal("--font-heading-xs-line-height"),J.literal("--font-heading-sm-line-height"),J.literal("--font-heading-md-line-height"),J.literal("--font-heading-lg-line-height"),J.literal("--font-heading-xl-line-height"),J.literal("--font-heading-2xl-line-height"),J.literal("--font-heading-3xl-line-height"),J.literal("--border-radius-xs"),J.literal("--border-radius-sm"),J.literal("--border-radius-md"),J.literal("--border-radius-lg"),J.literal("--border-radius-xl"),J.literal("--border-radius-full"),J.literal("--border-width-regular"),J.literal("--shadow-hairline"),J.literal("--shadow-sm"),J.literal("--shadow-md"),J.literal("--shadow-lg")]).describe("CSS variable keys available to MCP apps for theming."),qJ=J.record(OJ.describe(`Style variables for theming MCP apps.
import{useEffect as hJ,useState as d}from"react";import{CallToolRequestSchema as gJ,CallToolResultSchema as vJ,EmptyResultSchema as xJ,ListResourcesResultSchema as yJ,ListToolsRequestSchema as fJ,PingRequestSchema as dJ,ReadResourceResultSchema as uJ}from"@modelcontextprotocol/sdk/types.js";import{Protocol as a}from"@modelcontextprotocol/sdk/shared/protocol.js";class R extends a{_registeredMethods=new Set;_eventSlots=new Map;onEventDispatch(K,Q){}_ensureEventSlot(K){let Q=this._eventSlots.get(K);if(!Q){let X=this.eventSchemas[K];if(!X)throw Error(`Unknown event: ${String(K)}`);Q={listeners:[]},this._eventSlots.set(K,Q);let Y=X.shape.method.value;this._registeredMethods.add(Y);let Z=Q;super.setNotificationHandler(X,($)=>{let G=$.params;this.onEventDispatch(K,G),Z.onHandler?.(G);for(let j of[...Z.listeners])j(G)})}return Q}setEventHandler(K,Q){let X=this._ensureEventSlot(K);if(X.onHandler&&Q)console.warn(`[MCP Apps] on${String(K)} handler replaced. Use addEventListener("${String(K)}", …) to add multiple listeners without replacing.`);X.onHandler=Q}getEventHandler(K){return this._eventSlots.get(K)?.onHandler}addEventListener(K,Q){this._ensureEventSlot(K).listeners.push(Q)}removeEventListener(K,Q){let X=this._eventSlots.get(K);if(!X)return;let Y=X.listeners.indexOf(Q);if(Y!==-1)X.listeners.splice(Y,1)}setRequestHandler=(K,Q)=>{this._assertMethodNotRegistered(K,"setRequestHandler"),super.setRequestHandler(K,Q)};setNotificationHandler=(K,Q)=>{this._assertMethodNotRegistered(K,"setNotificationHandler"),super.setNotificationHandler(K,Q)};warnIfRequestHandlerReplaced(K,Q,X){if(Q&&X)console.warn(`[MCP Apps] ${K} handler replaced. Previous handler will no longer be called.`)}replaceRequestHandler=(K,Q)=>{let X=K.shape.method.value;this._registeredMethods.add(X),super.setRequestHandler(K,Q)};_assertMethodNotRegistered(K,Q){let X=K.shape.method.value;if(this._registeredMethods.has(X))throw Error(`Handler for "${X}" already registered (via ${Q}). Use addEventListener() to attach multiple listeners, or the on* setter for replace semantics.`);this._registeredMethods.add(X)}}import{JSONRPCMessageSchema as BJ}from"@modelcontextprotocol/sdk/types.js";var z="2026-01-26",s="ui/open-link",t="ui/download-file",e="ui/message",JJ="ui/notifications/sandbox-proxy-ready",KJ="ui/notifications/sandbox-resource-ready",QJ="ui/notifications/size-changed",XJ="ui/notifications/tool-input",U="ui/notifications/tool-input-partial",YJ="ui/notifications/tool-result",ZJ="ui/notifications/tool-cancelled",$J="ui/notifications/host-context-changed",GJ="ui/notifications/request-teardown",jJ="ui/resource-teardown",WJ="ui/initialize",LJ="ui/notifications/initialized",NJ="ui/request-display-mode";class L{eventTarget;eventSource;messageListener;constructor(K=window.parent,Q){this.eventTarget=K;this.eventSource=Q;this.messageListener=(X)=>{if(Q&&X.source!==this.eventSource){console.debug("Ignoring message from unknown source",X);return}let Y=BJ.safeParse(X.data);if(Y.success)console.debug("Parsed message",Y.data),this.onmessage?.(Y.data);else if(X.data?.jsonrpc!=="2.0")console.debug("Ignoring non-JSON-RPC message",Y.error.message,X);else console.error("Failed to parse message",Y.error.message,X),this.onerror?.(Error("Invalid JSON-RPC message received: "+Y.error.message))}}async start(){window.addEventListener("message",this.messageListener)}async send(K,Q){if(K.method!==U)console.debug("Sending message",K);this.eventTarget.postMessage(K,"*")}async close(){window.removeEventListener("message",this.messageListener),this.onclose?.()}onclose;onerror;onmessage;sessionId;setProtocolVersion}import{z as J}from"zod/v4";import{ContentBlockSchema as u,CallToolResultSchema as VJ,EmbeddedResourceSchema as _J,ImplementationSchema as h,RequestIdSchema as OJ,ResourceLinkSchema as PJ,ToolSchema as qJ}from"@modelcontextprotocol/sdk/types.js";var m=J.union([J.literal("light"),J.literal("dark")]).describe("Color theme preference for the host environment."),N=J.union([J.literal("inline"),J.literal("fullscreen"),J.literal("pip")]).describe("Display mode for UI presentation."),DJ=J.union([J.literal("--color-background-primary"),J.literal("--color-background-secondary"),J.literal("--color-background-tertiary"),J.literal("--color-background-inverse"),J.literal("--color-background-ghost"),J.literal("--color-background-info"),J.literal("--color-background-danger"),J.literal("--color-background-success"),J.literal("--color-background-warning"),J.literal("--color-background-disabled"),J.literal("--color-text-primary"),J.literal("--color-text-secondary"),J.literal("--color-text-tertiary"),J.literal("--color-text-inverse"),J.literal("--color-text-ghost"),J.literal("--color-text-info"),J.literal("--color-text-danger"),J.literal("--color-text-success"),J.literal("--color-text-warning"),J.literal("--color-text-disabled"),J.literal("--color-border-primary"),J.literal("--color-border-secondary"),J.literal("--color-border-tertiary"),J.literal("--color-border-inverse"),J.literal("--color-border-ghost"),J.literal("--color-border-info"),J.literal("--color-border-danger"),J.literal("--color-border-success"),J.literal("--color-border-warning"),J.literal("--color-border-disabled"),J.literal("--color-ring-primary"),J.literal("--color-ring-secondary"),J.literal("--color-ring-inverse"),J.literal("--color-ring-info"),J.literal("--color-ring-danger"),J.literal("--color-ring-success"),J.literal("--color-ring-warning"),J.literal("--font-sans"),J.literal("--font-mono"),J.literal("--font-weight-normal"),J.literal("--font-weight-medium"),J.literal("--font-weight-semibold"),J.literal("--font-weight-bold"),J.literal("--font-text-xs-size"),J.literal("--font-text-sm-size"),J.literal("--font-text-md-size"),J.literal("--font-text-lg-size"),J.literal("--font-heading-xs-size"),J.literal("--font-heading-sm-size"),J.literal("--font-heading-md-size"),J.literal("--font-heading-lg-size"),J.literal("--font-heading-xl-size"),J.literal("--font-heading-2xl-size"),J.literal("--font-heading-3xl-size"),J.literal("--font-text-xs-line-height"),J.literal("--font-text-sm-line-height"),J.literal("--font-text-md-line-height"),J.literal("--font-text-lg-line-height"),J.literal("--font-heading-xs-line-height"),J.literal("--font-heading-sm-line-height"),J.literal("--font-heading-md-line-height"),J.literal("--font-heading-lg-line-height"),J.literal("--font-heading-xl-line-height"),J.literal("--font-heading-2xl-line-height"),J.literal("--font-heading-3xl-line-height"),J.literal("--border-radius-xs"),J.literal("--border-radius-sm"),J.literal("--border-radius-md"),J.literal("--border-radius-lg"),J.literal("--border-radius-xl"),J.literal("--border-radius-full"),J.literal("--border-width-regular"),J.literal("--shadow-hairline"),J.literal("--shadow-sm"),J.literal("--shadow-md"),J.literal("--shadow-lg")]).describe("CSS variable keys available to MCP apps for theming."),IJ=J.record(DJ.describe(`Style variables for theming MCP apps.

@@ -19,6 +19,6 @@ Individual style keys are optional - hosts may provide any subset of these values.

Note: This type uses \`Record<K, string | undefined>\` rather than \`Partial<Record<K, string>>\`
for compatibility with Zod schema generation. Both are functionally equivalent for validation.`),DJ=J.object({method:J.literal("ui/open-link"),params:J.object({url:J.string().describe("URL to open in the host's browser")})}),w=J.object({isError:J.boolean().optional().describe("True if the host failed to open the URL (e.g., due to security policy).")}).passthrough(),M=J.object({isError:J.boolean().optional().describe("True if the download failed (e.g., user cancelled or host denied).")}).passthrough(),T=J.object({isError:J.boolean().optional().describe("True if the host rejected or failed to deliver the message.")}).passthrough(),IJ=J.object({method:J.literal("ui/notifications/sandbox-proxy-ready"),params:J.object({})}),V=J.object({connectDomains:J.array(J.string()).optional().describe(`Origins for network requests (fetch/XHR/WebSocket).
for compatibility with Zod schema generation. Both are functionally equivalent for validation.`),FJ=J.object({method:J.literal("ui/open-link"),params:J.object({url:J.string().describe("URL to open in the host's browser")})}),M=J.object({isError:J.boolean().optional().describe("True if the host failed to open the URL (e.g., due to security policy).")}).passthrough(),T=J.object({isError:J.boolean().optional().describe("True if the download failed (e.g., user cancelled or host denied).")}).passthrough(),H=J.object({isError:J.boolean().optional().describe("True if the host rejected or failed to deliver the message.")}).passthrough(),EJ=J.object({method:J.literal("ui/notifications/sandbox-proxy-ready"),params:J.object({})}),V=J.object({connectDomains:J.array(J.string()).optional().describe(`Origins for network requests (fetch/XHR/WebSocket).
- Maps to CSP \`connect-src\` directive
- Empty or omitted → no network connections (secure default)`),resourceDomains:J.array(J.string()).optional().describe("Origins for static resources (images, scripts, stylesheets, fonts, media).\n\n- Maps to CSP `img-src`, `script-src`, `style-src`, `font-src`, `media-src` directives\n- Wildcard subdomains supported: `https://*.example.com`\n- Empty or omitted → no network resources (secure default)"),frameDomains:J.array(J.string()).optional().describe("Origins for nested iframes.\n\n- Maps to CSP `frame-src` directive\n- Empty or omitted → no nested iframes allowed (`frame-src 'none'`)"),baseUriDomains:J.array(J.string()).optional().describe("Allowed base URIs for the document.\n\n- Maps to CSP `base-uri` directive\n- Empty or omitted → only same origin allowed (`base-uri 'self'`)")}),P=J.object({camera:J.object({}).optional().describe("Request camera access.\n\nMaps to Permission Policy `camera` feature."),microphone:J.object({}).optional().describe("Request microphone access.\n\nMaps to Permission Policy `microphone` feature."),geolocation:J.object({}).optional().describe("Request geolocation access.\n\nMaps to Permission Policy `geolocation` feature."),clipboardWrite:J.object({}).optional().describe("Request clipboard write access.\n\nMaps to Permission Policy `clipboard-write` feature.")}),FJ=J.object({method:J.literal("ui/notifications/size-changed"),params:J.object({width:J.number().optional().describe("New width in pixels."),height:J.number().optional().describe("New height in pixels.")})}),H=J.object({method:J.literal("ui/notifications/tool-input"),params:J.object({arguments:J.record(J.string(),J.unknown().describe("Complete tool call arguments as key-value pairs.")).optional().describe("Complete tool call arguments as key-value pairs.")})}),v=J.object({method:J.literal("ui/notifications/tool-input-partial"),params:J.object({arguments:J.record(J.string(),J.unknown().describe("Partial tool call arguments (incomplete, may change).")).optional().describe("Partial tool call arguments (incomplete, may change).")})}),A=J.object({method:J.literal("ui/notifications/tool-cancelled"),params:J.object({reason:J.string().optional().describe('Optional reason for the cancellation (e.g., "user action", "timeout").')})}),m=J.object({fonts:J.string().optional()}),c=J.object({variables:qJ.optional().describe("CSS variables for theming the app."),css:m.optional().describe("CSS blocks that apps can inject.")}),k=J.object({method:J.literal("ui/resource-teardown"),params:J.object({})}),EJ=J.record(J.string(),J.unknown()),U=J.object({text:J.object({}).optional().describe("Host supports text content blocks."),image:J.object({}).optional().describe("Host supports image content blocks."),audio:J.object({}).optional().describe("Host supports audio content blocks."),resource:J.object({}).optional().describe("Host supports resource content blocks."),resourceLink:J.object({}).optional().describe("Host supports resource link content blocks."),structuredContent:J.object({}).optional().describe("Host supports structured content.")}),RJ=J.object({method:J.literal("ui/notifications/request-teardown"),params:J.object({}).optional()}),r=J.object({experimental:J.object({}).optional().describe("Experimental features (structure TBD)."),openLinks:J.object({}).optional().describe("Host supports opening external URLs."),downloadFile:J.object({}).optional().describe("Host supports file downloads via ui/download-file."),serverTools:J.object({listChanged:J.boolean().optional().describe("Host supports tools/list_changed notifications.")}).optional().describe("Host can proxy tool calls to the MCP server."),serverResources:J.object({listChanged:J.boolean().optional().describe("Host supports resources/list_changed notifications.")}).optional().describe("Host can proxy resource reads to the MCP server."),logging:J.object({}).optional().describe("Host accepts log messages."),sandbox:J.object({permissions:P.optional().describe("Permissions granted by the host (camera, microphone, geolocation)."),csp:V.optional().describe("CSP domains approved by the host.")}).optional().describe("Sandbox configuration applied by the host."),updateModelContext:U.optional().describe("Host accepts context updates (ui/update-model-context) to be included in the model's context for future turns."),message:U.optional().describe("Host supports receiving content messages (ui/message) from the view.")}),l=J.object({experimental:J.object({}).optional().describe("Experimental features (structure TBD)."),tools:J.object({listChanged:J.boolean().optional().describe("App supports tools/list_changed notifications.")}).optional().describe("App exposes MCP-style tools that the host can call."),availableDisplayModes:J.array(j).optional().describe("Display modes the app supports.")}),zJ=J.object({method:J.literal("ui/notifications/initialized"),params:J.object({}).optional()}),UJ=J.object({csp:V.optional().describe("Content Security Policy configuration for UI resources."),permissions:P.optional().describe("Sandbox permissions requested by the UI resource."),domain:J.string().optional().describe(`Dedicated origin for view sandbox.
- Empty or omitted → no network connections (secure default)`),resourceDomains:J.array(J.string()).optional().describe("Origins for static resources (images, scripts, stylesheets, fonts, media).\n\n- Maps to CSP `img-src`, `script-src`, `style-src`, `font-src`, `media-src` directives\n- Wildcard subdomains supported: `https://*.example.com`\n- Empty or omitted → no network resources (secure default)"),frameDomains:J.array(J.string()).optional().describe("Origins for nested iframes.\n\n- Maps to CSP `frame-src` directive\n- Empty or omitted → no nested iframes allowed (`frame-src 'none'`)"),baseUriDomains:J.array(J.string()).optional().describe("Allowed base URIs for the document.\n\n- Maps to CSP `base-uri` directive\n- Empty or omitted → only same origin allowed (`base-uri 'self'`)")}),_=J.object({camera:J.object({}).optional().describe("Request camera access.\n\nMaps to Permission Policy `camera` feature."),microphone:J.object({}).optional().describe("Request microphone access.\n\nMaps to Permission Policy `microphone` feature."),geolocation:J.object({}).optional().describe("Request geolocation access.\n\nMaps to Permission Policy `geolocation` feature."),clipboardWrite:J.object({}).optional().describe("Request clipboard write access.\n\nMaps to Permission Policy `clipboard-write` feature.")}),RJ=J.object({method:J.literal("ui/notifications/size-changed"),params:J.object({width:J.number().optional().describe("New width in pixels."),height:J.number().optional().describe("New height in pixels.")})}),A=J.object({method:J.literal("ui/notifications/tool-input"),params:J.object({arguments:J.record(J.string(),J.unknown().describe("Complete tool call arguments as key-value pairs.")).optional().describe("Complete tool call arguments as key-value pairs.")})}),k=J.object({method:J.literal("ui/notifications/tool-input-partial"),params:J.object({arguments:J.record(J.string(),J.unknown().describe("Partial tool call arguments (incomplete, may change).")).optional().describe("Partial tool call arguments (incomplete, may change).")})}),b=J.object({method:J.literal("ui/notifications/tool-cancelled"),params:J.object({reason:J.string().optional().describe('Optional reason for the cancellation (e.g., "user action", "timeout").')})}),c=J.object({fonts:J.string().optional()}),r=J.object({variables:IJ.optional().describe("CSS variables for theming the app."),css:c.optional().describe("CSS blocks that apps can inject.")}),S=J.object({method:J.literal("ui/resource-teardown"),params:J.object({})}),zJ=J.record(J.string(),J.unknown()),w=J.object({text:J.object({}).optional().describe("Host supports text content blocks."),image:J.object({}).optional().describe("Host supports image content blocks."),audio:J.object({}).optional().describe("Host supports audio content blocks."),resource:J.object({}).optional().describe("Host supports resource content blocks."),resourceLink:J.object({}).optional().describe("Host supports resource link content blocks."),structuredContent:J.object({}).optional().describe("Host supports structured content.")}),UJ=J.object({method:J.literal("ui/notifications/request-teardown"),params:J.object({}).optional()}),l=J.object({experimental:J.object({}).optional().describe("Experimental features (structure TBD)."),openLinks:J.object({}).optional().describe("Host supports opening external URLs."),downloadFile:J.object({}).optional().describe("Host supports file downloads via ui/download-file."),serverTools:J.object({listChanged:J.boolean().optional().describe("Host supports tools/list_changed notifications.")}).optional().describe("Host can proxy tool calls to the MCP server."),serverResources:J.object({listChanged:J.boolean().optional().describe("Host supports resources/list_changed notifications.")}).optional().describe("Host can proxy resource reads to the MCP server."),logging:J.object({}).optional().describe("Host accepts log messages."),sandbox:J.object({permissions:_.optional().describe("Permissions granted by the host (camera, microphone, geolocation)."),csp:V.optional().describe("CSP domains approved by the host.")}).optional().describe("Sandbox configuration applied by the host."),updateModelContext:w.optional().describe("Host accepts context updates (ui/update-model-context) to be included in the model's context for future turns."),message:w.optional().describe("Host supports receiving content messages (ui/message) from the view.")}),i=J.object({experimental:J.object({}).optional().describe("Experimental features (structure TBD)."),tools:J.object({listChanged:J.boolean().optional().describe("App supports tools/list_changed notifications.")}).optional().describe("App exposes MCP-style tools that the host can call."),availableDisplayModes:J.array(N).optional().describe("Display modes the app supports.")}),wJ=J.object({method:J.literal("ui/notifications/initialized"),params:J.object({}).optional()}),MJ=J.object({csp:V.optional().describe("Content Security Policy configuration for UI resources."),permissions:_.optional().describe("Sandbox permissions requested by the UI resource."),domain:J.string().optional().describe(`Dedicated origin for view sandbox.

@@ -37,5 +37,5 @@ Useful when views need stable, dedicated origins for OAuth callbacks, CORS policies, or API key allowlists.

- \`false\`: request no visible border + background
- omitted: host decides border`)}),wJ=J.object({method:J.literal("ui/request-display-mode"),params:J.object({mode:j.describe("The display mode being requested.")})}),b=J.object({mode:j.describe("The display mode that was actually set. May differ from requested if not supported.")}).passthrough(),i=J.union([J.literal("model"),J.literal("app")]).describe("Tool visibility scope - who can access the tool."),MJ=J.object({resourceUri:J.string().optional(),visibility:J.array(i).optional().describe(`Who can access this tool. Default: ["model", "app"]
- omitted: host decides border`)}),TJ=J.object({method:J.literal("ui/request-display-mode"),params:J.object({mode:N.describe("The display mode being requested.")})}),C=J.object({mode:N.describe("The display mode that was actually set. May differ from requested if not supported.")}).passthrough(),p=J.union([J.literal("model"),J.literal("app")]).describe("Tool visibility scope - who can access the tool."),HJ=J.object({resourceUri:J.string().optional(),visibility:J.array(p).optional().describe(`Who can access this tool. Default: ["model", "app"]
- "model": Tool visible to and callable by the agent
- "app": Tool callable by the app from this server only`)}),JK=J.object({mimeTypes:J.array(J.string()).optional().describe('Array of supported MIME types for UI resources.\nMust include `"text/html;profile=mcp-app"` for MCP Apps support.')}),TJ=J.object({method:J.literal("ui/download-file"),params:J.object({contents:J.array(J.union([BJ,PJ])).describe("Resource contents to download — embedded (inline data) or linked (host fetches). Uses standard MCP resource types.")})}),HJ=J.object({method:J.literal("ui/message"),params:J.object({role:J.literal("user").describe('Message role, currently only "user" is supported.'),content:J.array(d).describe("Message content blocks (text, image, etc.).")})}),vJ=J.object({method:J.literal("ui/notifications/sandbox-resource-ready"),params:J.object({html:J.string().describe("HTML content to load into the inner iframe."),sandbox:J.string().optional().describe("Optional override for the inner iframe's sandbox attribute."),csp:V.optional().describe("CSP configuration from resource metadata."),permissions:P.optional().describe("Sandbox permissions from resource metadata.")})}),S=J.object({method:J.literal("ui/notifications/tool-result"),params:NJ.describe("Standard MCP tool execution result.")}),C=J.object({toolInfo:J.object({id:VJ.optional().describe("JSON-RPC id of the tools/call request."),tool:_J.describe("Tool definition including name, inputSchema, etc.")}).optional().describe("Metadata of the tool call that instantiated this App."),theme:h.optional().describe("Current color theme preference."),styles:c.optional().describe("Style configuration for theming the app."),displayMode:j.optional().describe("How the UI is currently displayed."),availableDisplayModes:J.array(j).optional().describe("Display modes the host supports."),containerDimensions:J.union([J.object({height:J.number().describe("Fixed container height in pixels.")}),J.object({maxHeight:J.union([J.number(),J.undefined()]).optional().describe("Maximum container height in pixels.")})]).and(J.union([J.object({width:J.number().describe("Fixed container width in pixels.")}),J.object({maxWidth:J.union([J.number(),J.undefined()]).optional().describe("Maximum container width in pixels.")})])).optional().describe(`Container dimensions. Represents the dimensions of the iframe or other
container holding the app. Specify either width or maxWidth, and either height or maxHeight.`),locale:J.string().optional().describe("User's language and region preference in BCP 47 format."),timeZone:J.string().optional().describe("User's timezone in IANA format."),userAgent:J.string().optional().describe("Host application identifier."),platform:J.union([J.literal("web"),J.literal("desktop"),J.literal("mobile")]).optional().describe("Platform type for responsive design decisions."),deviceCapabilities:J.object({touch:J.boolean().optional().describe("Whether the device supports touch input."),hover:J.boolean().optional().describe("Whether the device supports hover interactions.")}).optional().describe("Device input capabilities."),safeAreaInsets:J.object({top:J.number().describe("Top safe area inset in pixels."),right:J.number().describe("Right safe area inset in pixels."),bottom:J.number().describe("Bottom safe area inset in pixels."),left:J.number().describe("Left safe area inset in pixels.")}).optional().describe("Mobile safe area boundaries in pixels.")}).passthrough(),g=J.object({method:J.literal("ui/notifications/host-context-changed"),params:C.describe("Partial context update containing only changed fields.")}),AJ=J.object({method:J.literal("ui/update-model-context"),params:J.object({content:J.array(d).optional().describe("Context content blocks (text, image, etc.)."),structuredContent:J.record(J.string(),J.unknown().describe("Structured content for machine-readable context data.")).optional().describe("Structured content for machine-readable context data.")})}),kJ=J.object({method:J.literal("ui/initialize"),params:J.object({appInfo:u.describe("App identification (name and version)."),appCapabilities:l.describe("Features and capabilities this app provides."),protocolVersion:J.string().describe("Protocol version this app supports.")})}),x=J.object({protocolVersion:J.string().describe('Negotiated protocol version string (e.g., "2025-11-21").'),hostInfo:u.describe("Host application identification and version."),hostCapabilities:r.describe("Features and capabilities provided by the host."),hostContext:C.describe("Rich context about the host environment.")}).passthrough();function _(){let K=document.documentElement.getAttribute("data-theme");if(K==="dark"||K==="light")return K;return document.documentElement.classList.contains("dark")?"dark":"light"}function O(K){let Q=document.documentElement;Q.setAttribute("data-theme",K),Q.style.colorScheme=K}function q(K,Q=document.documentElement){for(let[X,Y]of Object.entries(K))if(Y!==void 0)Q.style.setProperty(X,Y)}function D(K){if(document.getElementById("__mcp-host-fonts"))return;let X=document.createElement("style");X.id="__mcp-host-fonts",X.textContent=K,document.head.appendChild(X)}var dK="ui/resourceUri",uK="text/html;profile=mcp-app";class y extends bJ{_appInfo;_capabilities;options;_hostCapabilities;_hostInfo;_hostContext;constructor(K,Q={},X={autoResize:!0}){super(X);this._appInfo=K;this._capabilities=Q;this.options=X;this.setRequestHandler(fJ,(Y)=>{return console.log("Received ping:",Y.params),{}}),this.onhostcontextchanged=()=>{}}getHostCapabilities(){return this._hostCapabilities}getHostVersion(){return this._hostInfo}getHostContext(){return this._hostContext}set ontoolinput(K){this.setNotificationHandler(H,(Q)=>K(Q.params))}set ontoolinputpartial(K){this.setNotificationHandler(v,(Q)=>K(Q.params))}set ontoolresult(K){this.setNotificationHandler(S,(Q)=>K(Q.params))}set ontoolcancelled(K){this.setNotificationHandler(A,(Q)=>K(Q.params))}set onhostcontextchanged(K){this.setNotificationHandler(g,(Q)=>{this._hostContext={...this._hostContext,...Q.params},K(Q.params)})}set onteardown(K){this.setRequestHandler(k,(Q,X)=>K(Q.params,X))}set oncalltool(K){this.setRequestHandler(SJ,(Q,X)=>K(Q.params,X))}set onlisttools(K){this.setRequestHandler(yJ,(Q,X)=>K(Q.params,X))}assertCapabilityForMethod(K){}assertRequestHandlerCapability(K){switch(K){case"tools/call":case"tools/list":if(!this._capabilities.tools)throw Error(`Client does not support tool capability (required for ${K})`);return;case"ping":case"ui/resource-teardown":return;default:throw Error(`No handler for method ${K} registered`)}}assertNotificationCapability(K){}assertTaskCapability(K){throw Error("Tasks are not supported in MCP Apps")}assertTaskHandlerCapability(K){throw Error("Task handlers are not supported in MCP Apps")}async callServerTool(K,Q){if(typeof K==="string")throw Error(`callServerTool() expects an object as its first argument, but received a string ("${K}"). Did you mean: callServerTool({ name: "${K}", arguments: { ... } })?`);return await this.request({method:"tools/call",params:K},CJ,Q)}async readServerResource(K,Q){return await this.request({method:"resources/read",params:K},dJ,Q)}async listServerResources(K,Q){return await this.request({method:"resources/list",params:K},xJ,Q)}sendMessage(K,Q){return this.request({method:"ui/message",params:K},T,Q)}sendLog(K){return this.notification({method:"notifications/message",params:K})}updateModelContext(K,Q){return this.request({method:"ui/update-model-context",params:K},gJ,Q)}openLink(K,Q){return this.request({method:"ui/open-link",params:K},w,Q)}sendOpenLink=this.openLink;downloadFile(K,Q){return this.request({method:"ui/download-file",params:K},M,Q)}requestTeardown(K={}){return this.notification({method:"ui/notifications/request-teardown",params:K})}requestDisplayMode(K,Q){return this.request({method:"ui/request-display-mode",params:K},b,Q)}sendSizeChanged(K){return this.notification({method:"ui/notifications/size-changed",params:K})}setupSizeChangedNotifications(){let K=!1,Q=0,X=0,Y=()=>{if(K)return;K=!0,requestAnimationFrame(()=>{K=!1;let $=document.documentElement,N=$.style.height;$.style.height="max-content";let L=Math.ceil($.getBoundingClientRect().height);$.style.height=N;let G=Math.ceil(window.innerWidth);if(G!==Q||L!==X)Q=G,X=L,this.sendSizeChanged({width:G,height:L})})};Y();let Z=new ResizeObserver(Y);return Z.observe(document.documentElement),Z.observe(document.body),()=>Z.disconnect()}async connect(K=new W(window.parent,window.parent),Q){if(this.transport)throw Error("App is already connected. Call close() before connecting again.");await super.connect(K);try{let X=await this.request({method:"ui/initialize",params:{appCapabilities:this._capabilities,appInfo:this._appInfo,protocolVersion:R}},x,Q);if(X===void 0)throw Error(`Server sent invalid initialize result: ${X}`);if(this._hostCapabilities=X.hostCapabilities,this._hostInfo=X.hostInfo,this._hostContext=X.hostContext,await this.notification({method:"ui/notifications/initialized"}),this.options?.autoResize)this.setupSizeChangedNotifications()}catch(X){throw this.close(),X}}}function nK({appInfo:K,capabilities:Q,onAppCreated:X}){let[Y,Z]=f(null),[$,N]=f(!1),[L,G]=f(null);return uJ(()=>{let F=!0;async function n(){try{let B=new W(window.parent,window.parent),E=new y(K,Q);if(X?.(E),await E.connect(B),F)Z(E),N(!0),G(null)}catch(B){if(F)Z(null),N(!1),G(B instanceof Error?B:Error("Failed to connect"))}}return n(),()=>{F=!1}},[]),{app:Y,isConnected:$,error:L}}import{useEffect as hJ}from"react";function eK(K,Q){hJ(()=>{if(!K)return;return K.setupSizeChangedNotifications()},[K,Q])}import{useEffect as mJ,useState as cJ}from"react";function XQ(){let[K,Q]=cJ(_);return mJ(()=>{let X=new MutationObserver(()=>{Q(_())});return X.observe(document.documentElement,{attributes:!0,attributeFilter:["data-theme","class"],characterData:!1,childList:!1,subtree:!1}),()=>X.disconnect()},[]),K}import{useEffect as I,useRef as p}from"react";function rJ(K,Q){let X=p(!1);I(()=>{if(X.current)return;if(Q?.theme)O(Q.theme);if(Q?.styles?.variables)q(Q.styles.variables);if(Q?.theme||Q?.styles?.variables)X.current=!0},[Q]),I(()=>{if(!K)return;K.onhostcontextchanged=(Y)=>{if(Y.theme)O(Y.theme);if(Y.styles?.variables)q(Y.styles.variables)}},[K])}function lJ(K,Q){let X=p(!1);I(()=>{if(X.current)return;if(Q?.styles?.css?.fonts)D(Q.styles.css.fonts),X.current=!0},[Q]),I(()=>{if(!K)return;K.onhostcontextchanged=(Y)=>{if(Y.styles?.css?.fonts)D(Y.styles.css.fonts)}},[K])}function GQ(K,Q){rJ(K,Q),lJ(K,Q)}export{GQ as useHostStyles,rJ as useHostStyleVariables,lJ as useHostFonts,XQ as useDocumentTheme,eK as useAutoResize,nK as useApp,_ as getDocumentTheme,q as applyHostStyleVariables,D as applyHostFonts,O as applyDocumentTheme,QJ as TOOL_RESULT_METHOD,z as TOOL_INPUT_PARTIAL_METHOD,KJ as TOOL_INPUT_METHOD,XJ as TOOL_CANCELLED_METHOD,JJ as SIZE_CHANGED_METHOD,e as SANDBOX_RESOURCE_READY_METHOD,t as SANDBOX_PROXY_READY_METHOD,dK as RESOURCE_URI_META_KEY,$J as RESOURCE_TEARDOWN_METHOD,uK as RESOURCE_MIME_TYPE,ZJ as REQUEST_TEARDOWN_METHOD,jJ as REQUEST_DISPLAY_MODE_METHOD,W as PostMessageTransport,o as OPEN_LINK_METHOD,AJ as McpUiUpdateModelContextRequestSchema,i as McpUiToolVisibilitySchema,S as McpUiToolResultNotificationSchema,MJ as McpUiToolMetaSchema,v as McpUiToolInputPartialNotificationSchema,H as McpUiToolInputNotificationSchema,A as McpUiToolCancelledNotificationSchema,h as McpUiThemeSchema,U as McpUiSupportedContentBlockModalitiesSchema,FJ as McpUiSizeChangedNotificationSchema,vJ as McpUiSandboxResourceReadyNotificationSchema,IJ as McpUiSandboxProxyReadyNotificationSchema,EJ as McpUiResourceTeardownResultSchema,k as McpUiResourceTeardownRequestSchema,P as McpUiResourcePermissionsSchema,UJ as McpUiResourceMetaSchema,V as McpUiResourceCspSchema,RJ as McpUiRequestTeardownNotificationSchema,b as McpUiRequestDisplayModeResultSchema,wJ as McpUiRequestDisplayModeRequestSchema,w as McpUiOpenLinkResultSchema,DJ as McpUiOpenLinkRequestSchema,T as McpUiMessageResultSchema,HJ as McpUiMessageRequestSchema,zJ as McpUiInitializedNotificationSchema,x as McpUiInitializeResultSchema,kJ as McpUiInitializeRequestSchema,c as McpUiHostStylesSchema,m as McpUiHostCssSchema,C as McpUiHostContextSchema,g as McpUiHostContextChangedNotificationSchema,r as McpUiHostCapabilitiesSchema,M as McpUiDownloadFileResultSchema,TJ as McpUiDownloadFileRequestSchema,j as McpUiDisplayModeSchema,l as McpUiAppCapabilitiesSchema,s as MESSAGE_METHOD,R as LATEST_PROTOCOL_VERSION,GJ as INITIALIZE_METHOD,WJ as INITIALIZED_METHOD,YJ as HOST_CONTEXT_CHANGED_METHOD,a as DOWNLOAD_FILE_METHOD,y as App};
- "app": Tool callable by the app from this server only`)}),XK=J.object({mimeTypes:J.array(J.string()).optional().describe('Array of supported MIME types for UI resources.\nMust include `"text/html;profile=mcp-app"` for MCP Apps support.')}),AJ=J.object({method:J.literal("ui/download-file"),params:J.object({contents:J.array(J.union([_J,PJ])).describe("Resource contents to download — embedded (inline data) or linked (host fetches). Uses standard MCP resource types.")})}),kJ=J.object({method:J.literal("ui/message"),params:J.object({role:J.literal("user").describe('Message role, currently only "user" is supported.'),content:J.array(u).describe("Message content blocks (text, image, etc.).")})}),bJ=J.object({method:J.literal("ui/notifications/sandbox-resource-ready"),params:J.object({html:J.string().describe("HTML content to load into the inner iframe."),sandbox:J.string().optional().describe("Optional override for the inner iframe's sandbox attribute."),csp:V.optional().describe("CSP configuration from resource metadata."),permissions:_.optional().describe("Sandbox permissions from resource metadata.")})}),g=J.object({method:J.literal("ui/notifications/tool-result"),params:VJ.describe("Standard MCP tool execution result.")}),v=J.object({toolInfo:J.object({id:OJ.optional().describe("JSON-RPC id of the tools/call request."),tool:qJ.describe("Tool definition including name, inputSchema, etc.")}).optional().describe("Metadata of the tool call that instantiated this App."),theme:m.optional().describe("Current color theme preference."),styles:r.optional().describe("Style configuration for theming the app."),displayMode:N.optional().describe("How the UI is currently displayed."),availableDisplayModes:J.array(N).optional().describe("Display modes the host supports."),containerDimensions:J.union([J.object({height:J.number().describe("Fixed container height in pixels.")}),J.object({maxHeight:J.union([J.number(),J.undefined()]).optional().describe("Maximum container height in pixels.")})]).and(J.union([J.object({width:J.number().describe("Fixed container width in pixels.")}),J.object({maxWidth:J.union([J.number(),J.undefined()]).optional().describe("Maximum container width in pixels.")})])).optional().describe(`Container dimensions. Represents the dimensions of the iframe or other
container holding the app. Specify either width or maxWidth, and either height or maxHeight.`),locale:J.string().optional().describe("User's language and region preference in BCP 47 format."),timeZone:J.string().optional().describe("User's timezone in IANA format."),userAgent:J.string().optional().describe("Host application identifier."),platform:J.union([J.literal("web"),J.literal("desktop"),J.literal("mobile")]).optional().describe("Platform type for responsive design decisions."),deviceCapabilities:J.object({touch:J.boolean().optional().describe("Whether the device supports touch input."),hover:J.boolean().optional().describe("Whether the device supports hover interactions.")}).optional().describe("Device input capabilities."),safeAreaInsets:J.object({top:J.number().describe("Top safe area inset in pixels."),right:J.number().describe("Right safe area inset in pixels."),bottom:J.number().describe("Bottom safe area inset in pixels."),left:J.number().describe("Left safe area inset in pixels.")}).optional().describe("Mobile safe area boundaries in pixels.")}).passthrough(),x=J.object({method:J.literal("ui/notifications/host-context-changed"),params:v.describe("Partial context update containing only changed fields.")}),SJ=J.object({method:J.literal("ui/update-model-context"),params:J.object({content:J.array(u).optional().describe("Context content blocks (text, image, etc.)."),structuredContent:J.record(J.string(),J.unknown().describe("Structured content for machine-readable context data.")).optional().describe("Structured content for machine-readable context data.")})}),CJ=J.object({method:J.literal("ui/initialize"),params:J.object({appInfo:h.describe("App identification (name and version)."),appCapabilities:i.describe("Features and capabilities this app provides."),protocolVersion:J.string().describe("Protocol version this app supports.")})}),y=J.object({protocolVersion:J.string().describe('Negotiated protocol version string (e.g., "2025-11-21").'),hostInfo:h.describe("Host application identification and version."),hostCapabilities:l.describe("Features and capabilities provided by the host."),hostContext:v.describe("Rich context about the host environment.")}).passthrough();function O(){let K=document.documentElement.getAttribute("data-theme");if(K==="dark"||K==="light")return K;return document.documentElement.classList.contains("dark")?"dark":"light"}function P(K){let Q=document.documentElement;Q.setAttribute("data-theme",K),Q.style.colorScheme=K}function q(K,Q=document.documentElement){for(let[X,Y]of Object.entries(K))if(Y!==void 0)Q.style.setProperty(X,Y)}function D(K){if(document.getElementById("__mcp-host-fonts"))return;let X=document.createElement("style");X.id="__mcp-host-fonts",X.textContent=K,document.head.appendChild(X)}var mK="ui/resourceUri",cK="text/html;profile=mcp-app";class f extends R{_appInfo;_capabilities;options;_hostCapabilities;_hostInfo;_hostContext;eventSchemas={toolinput:A,toolinputpartial:k,toolresult:g,toolcancelled:b,hostcontextchanged:x};onEventDispatch(K,Q){if(K==="hostcontextchanged")this._hostContext={...this._hostContext,...Q}}constructor(K,Q={},X={autoResize:!0}){super(X);this._appInfo=K;this._capabilities=Q;this.options=X;this.setRequestHandler(dJ,(Y)=>{return console.log("Received ping:",Y.params),{}}),this.setEventHandler("hostcontextchanged",void 0)}getHostCapabilities(){return this._hostCapabilities}getHostVersion(){return this._hostInfo}getHostContext(){return this._hostContext}get ontoolinput(){return this.getEventHandler("toolinput")}set ontoolinput(K){this.setEventHandler("toolinput",K)}get ontoolinputpartial(){return this.getEventHandler("toolinputpartial")}set ontoolinputpartial(K){this.setEventHandler("toolinputpartial",K)}get ontoolresult(){return this.getEventHandler("toolresult")}set ontoolresult(K){this.setEventHandler("toolresult",K)}get ontoolcancelled(){return this.getEventHandler("toolcancelled")}set ontoolcancelled(K){this.setEventHandler("toolcancelled",K)}get onhostcontextchanged(){return this.getEventHandler("hostcontextchanged")}set onhostcontextchanged(K){this.setEventHandler("hostcontextchanged",K)}_onteardown;get onteardown(){return this._onteardown}set onteardown(K){this.warnIfRequestHandlerReplaced("onteardown",this._onteardown,K),this._onteardown=K,this.replaceRequestHandler(S,(Q,X)=>{if(!this._onteardown)throw Error("No onteardown handler set");return this._onteardown(Q.params,X)})}_oncalltool;get oncalltool(){return this._oncalltool}set oncalltool(K){this.warnIfRequestHandlerReplaced("oncalltool",this._oncalltool,K),this._oncalltool=K,this.replaceRequestHandler(gJ,(Q,X)=>{if(!this._oncalltool)throw Error("No oncalltool handler set");return this._oncalltool(Q.params,X)})}_onlisttools;get onlisttools(){return this._onlisttools}set onlisttools(K){this.warnIfRequestHandlerReplaced("onlisttools",this._onlisttools,K),this._onlisttools=K,this.replaceRequestHandler(fJ,(Q,X)=>{if(!this._onlisttools)throw Error("No onlisttools handler set");return this._onlisttools(Q.params,X)})}assertCapabilityForMethod(K){}assertRequestHandlerCapability(K){switch(K){case"tools/call":case"tools/list":if(!this._capabilities.tools)throw Error(`Client does not support tool capability (required for ${K})`);return;case"ping":case"ui/resource-teardown":return;default:throw Error(`No handler for method ${K} registered`)}}assertNotificationCapability(K){}assertTaskCapability(K){throw Error("Tasks are not supported in MCP Apps")}assertTaskHandlerCapability(K){throw Error("Task handlers are not supported in MCP Apps")}async callServerTool(K,Q){if(typeof K==="string")throw Error(`callServerTool() expects an object as its first argument, but received a string ("${K}"). Did you mean: callServerTool({ name: "${K}", arguments: { ... } })?`);return await this.request({method:"tools/call",params:K},vJ,Q)}async readServerResource(K,Q){return await this.request({method:"resources/read",params:K},uJ,Q)}async listServerResources(K,Q){return await this.request({method:"resources/list",params:K},yJ,Q)}sendMessage(K,Q){return this.request({method:"ui/message",params:K},H,Q)}sendLog(K){return this.notification({method:"notifications/message",params:K})}updateModelContext(K,Q){return this.request({method:"ui/update-model-context",params:K},xJ,Q)}openLink(K,Q){return this.request({method:"ui/open-link",params:K},M,Q)}sendOpenLink=this.openLink;downloadFile(K,Q){return this.request({method:"ui/download-file",params:K},T,Q)}requestTeardown(K={}){return this.notification({method:"ui/notifications/request-teardown",params:K})}requestDisplayMode(K,Q){return this.request({method:"ui/request-display-mode",params:K},C,Q)}sendSizeChanged(K){return this.notification({method:"ui/notifications/size-changed",params:K})}setupSizeChangedNotifications(){let K=!1,Q=0,X=0,Y=()=>{if(K)return;K=!0,requestAnimationFrame(()=>{K=!1;let $=document.documentElement,G=$.style.height;$.style.height="max-content";let j=Math.ceil($.getBoundingClientRect().height);$.style.height=G;let W=Math.ceil(window.innerWidth);if(W!==Q||j!==X)Q=W,X=j,this.sendSizeChanged({width:W,height:j})})};Y();let Z=new ResizeObserver(Y);return Z.observe(document.documentElement),Z.observe(document.body),()=>Z.disconnect()}async connect(K=new L(window.parent,window.parent),Q){if(this.transport)throw Error("App is already connected. Call close() before connecting again.");await super.connect(K);try{let X=await this.request({method:"ui/initialize",params:{appCapabilities:this._capabilities,appInfo:this._appInfo,protocolVersion:z}},y,Q);if(X===void 0)throw Error(`Server sent invalid initialize result: ${X}`);if(this._hostCapabilities=X.hostCapabilities,this._hostInfo=X.hostInfo,this._hostContext=X.hostContext,await this.notification({method:"ui/notifications/initialized"}),this.options?.autoResize)this.setupSizeChangedNotifications()}catch(X){throw this.close(),X}}}function sK({appInfo:K,capabilities:Q,onAppCreated:X}){let[Y,Z]=d(null),[$,G]=d(!1),[j,W]=d(null);return hJ(()=>{let F=!0;async function o(){try{let B=new L(window.parent,window.parent),E=new f(K,Q);if(X?.(E),await E.connect(B),F)Z(E),G(!0),W(null)}catch(B){if(F)Z(null),G(!1),W(B instanceof Error?B:Error("Failed to connect"))}}return o(),()=>{F=!1}},[]),{app:Y,isConnected:$,error:j}}import{useEffect as mJ}from"react";function QQ(K,Q){mJ(()=>{if(!K)return;return K.setupSizeChangedNotifications()},[K,Q])}import{useEffect as cJ,useState as rJ}from"react";function $Q(){let[K,Q]=rJ(O);return cJ(()=>{let X=new MutationObserver(()=>{Q(O())});return X.observe(document.documentElement,{attributes:!0,attributeFilter:["data-theme","class"],characterData:!1,childList:!1,subtree:!1}),()=>X.disconnect()},[]),K}import{useEffect as I,useRef as n}from"react";function lJ(K,Q){let X=n(!1);I(()=>{if(X.current)return;if(Q?.theme)P(Q.theme);if(Q?.styles?.variables)q(Q.styles.variables);if(Q?.theme||Q?.styles?.variables)X.current=!0},[Q]),I(()=>{if(!K)return;let Y=(Z)=>{if(Z.theme)P(Z.theme);if(Z.styles?.variables)q(Z.styles.variables)};return K.addEventListener("hostcontextchanged",Y),()=>K.removeEventListener("hostcontextchanged",Y)},[K])}function iJ(K,Q){let X=n(!1);I(()=>{if(X.current)return;if(Q?.styles?.css?.fonts)D(Q.styles.css.fonts),X.current=!0},[Q]),I(()=>{if(!K)return;let Y=(Z)=>{if(Z.styles?.css?.fonts)D(Z.styles.css.fonts)};return K.addEventListener("hostcontextchanged",Y),()=>K.removeEventListener("hostcontextchanged",Y)},[K])}function LQ(K,Q){lJ(K,Q),iJ(K,Q)}export{LQ as useHostStyles,lJ as useHostStyleVariables,iJ as useHostFonts,$Q as useDocumentTheme,QQ as useAutoResize,sK as useApp,O as getDocumentTheme,q as applyHostStyleVariables,D as applyHostFonts,P as applyDocumentTheme,YJ as TOOL_RESULT_METHOD,U as TOOL_INPUT_PARTIAL_METHOD,XJ as TOOL_INPUT_METHOD,ZJ as TOOL_CANCELLED_METHOD,QJ as SIZE_CHANGED_METHOD,KJ as SANDBOX_RESOURCE_READY_METHOD,JJ as SANDBOX_PROXY_READY_METHOD,mK as RESOURCE_URI_META_KEY,jJ as RESOURCE_TEARDOWN_METHOD,cK as RESOURCE_MIME_TYPE,GJ as REQUEST_TEARDOWN_METHOD,NJ as REQUEST_DISPLAY_MODE_METHOD,R as ProtocolWithEvents,L as PostMessageTransport,s as OPEN_LINK_METHOD,SJ as McpUiUpdateModelContextRequestSchema,p as McpUiToolVisibilitySchema,g as McpUiToolResultNotificationSchema,HJ as McpUiToolMetaSchema,k as McpUiToolInputPartialNotificationSchema,A as McpUiToolInputNotificationSchema,b as McpUiToolCancelledNotificationSchema,m as McpUiThemeSchema,w as McpUiSupportedContentBlockModalitiesSchema,RJ as McpUiSizeChangedNotificationSchema,bJ as McpUiSandboxResourceReadyNotificationSchema,EJ as McpUiSandboxProxyReadyNotificationSchema,zJ as McpUiResourceTeardownResultSchema,S as McpUiResourceTeardownRequestSchema,_ as McpUiResourcePermissionsSchema,MJ as McpUiResourceMetaSchema,V as McpUiResourceCspSchema,UJ as McpUiRequestTeardownNotificationSchema,C as McpUiRequestDisplayModeResultSchema,TJ as McpUiRequestDisplayModeRequestSchema,M as McpUiOpenLinkResultSchema,FJ as McpUiOpenLinkRequestSchema,H as McpUiMessageResultSchema,kJ as McpUiMessageRequestSchema,wJ as McpUiInitializedNotificationSchema,y as McpUiInitializeResultSchema,CJ as McpUiInitializeRequestSchema,r as McpUiHostStylesSchema,c as McpUiHostCssSchema,v as McpUiHostContextSchema,x as McpUiHostContextChangedNotificationSchema,l as McpUiHostCapabilitiesSchema,T as McpUiDownloadFileResultSchema,AJ as McpUiDownloadFileRequestSchema,N as McpUiDisplayModeSchema,i as McpUiAppCapabilitiesSchema,e as MESSAGE_METHOD,z as LATEST_PROTOCOL_VERSION,WJ as INITIALIZE_METHOD,LJ as INITIALIZED_METHOD,$J as HOST_CONTEXT_CHANGED_METHOD,t as DOWNLOAD_FILE_METHOD,f as App};

@@ -1,2 +0,2 @@

import{Protocol as DQ}from"@modelcontextprotocol/sdk/shared/protocol.js";import{CallToolRequestSchema as GQ,CallToolResultSchema as LQ,EmptyResultSchema as jQ,ListResourcesResultSchema as BQ,ListToolsRequestSchema as KQ,PingRequestSchema as NQ,ReadResourceResultSchema as YQ}from"@modelcontextprotocol/sdk/types.js";import{JSONRPCMessageSchema as u}from"@modelcontextprotocol/sdk/types.js";var Y="2026-01-26";var F="ui/notifications/tool-input-partial";class j{eventTarget;eventSource;messageListener;constructor(Z=window.parent,$){this.eventTarget=Z;this.eventSource=$;this.messageListener=(J)=>{if($&&J.source!==this.eventSource){console.debug("Ignoring message from unknown source",J);return}let X=u.safeParse(J.data);if(X.success)console.debug("Parsed message",X.data),this.onmessage?.(X.data);else if(J.data?.jsonrpc!=="2.0")console.debug("Ignoring non-JSON-RPC message",X.error.message,J);else console.error("Failed to parse message",X.error.message,J),this.onerror?.(Error("Invalid JSON-RPC message received: "+X.error.message))}}async start(){window.addEventListener("message",this.messageListener)}async send(Z,$){if(Z.method!==F)console.debug("Sending message",Z);this.eventTarget.postMessage(Z,"*")}async close(){window.removeEventListener("message",this.messageListener),this.onclose?.()}onclose;onerror;onmessage;sessionId;setProtocolVersion}import{z as Q}from"zod/v4";import{ContentBlockSchema as v,CallToolResultSchema as d,EmbeddedResourceSchema as h,ImplementationSchema as x,RequestIdSchema as m,ResourceLinkSchema as c,ToolSchema as l}from"@modelcontextprotocol/sdk/types.js";var M=Q.union([Q.literal("light"),Q.literal("dark")]).describe("Color theme preference for the host environment."),G=Q.union([Q.literal("inline"),Q.literal("fullscreen"),Q.literal("pip")]).describe("Display mode for UI presentation."),p=Q.union([Q.literal("--color-background-primary"),Q.literal("--color-background-secondary"),Q.literal("--color-background-tertiary"),Q.literal("--color-background-inverse"),Q.literal("--color-background-ghost"),Q.literal("--color-background-info"),Q.literal("--color-background-danger"),Q.literal("--color-background-success"),Q.literal("--color-background-warning"),Q.literal("--color-background-disabled"),Q.literal("--color-text-primary"),Q.literal("--color-text-secondary"),Q.literal("--color-text-tertiary"),Q.literal("--color-text-inverse"),Q.literal("--color-text-ghost"),Q.literal("--color-text-info"),Q.literal("--color-text-danger"),Q.literal("--color-text-success"),Q.literal("--color-text-warning"),Q.literal("--color-text-disabled"),Q.literal("--color-border-primary"),Q.literal("--color-border-secondary"),Q.literal("--color-border-tertiary"),Q.literal("--color-border-inverse"),Q.literal("--color-border-ghost"),Q.literal("--color-border-info"),Q.literal("--color-border-danger"),Q.literal("--color-border-success"),Q.literal("--color-border-warning"),Q.literal("--color-border-disabled"),Q.literal("--color-ring-primary"),Q.literal("--color-ring-secondary"),Q.literal("--color-ring-inverse"),Q.literal("--color-ring-info"),Q.literal("--color-ring-danger"),Q.literal("--color-ring-success"),Q.literal("--color-ring-warning"),Q.literal("--font-sans"),Q.literal("--font-mono"),Q.literal("--font-weight-normal"),Q.literal("--font-weight-medium"),Q.literal("--font-weight-semibold"),Q.literal("--font-weight-bold"),Q.literal("--font-text-xs-size"),Q.literal("--font-text-sm-size"),Q.literal("--font-text-md-size"),Q.literal("--font-text-lg-size"),Q.literal("--font-heading-xs-size"),Q.literal("--font-heading-sm-size"),Q.literal("--font-heading-md-size"),Q.literal("--font-heading-lg-size"),Q.literal("--font-heading-xl-size"),Q.literal("--font-heading-2xl-size"),Q.literal("--font-heading-3xl-size"),Q.literal("--font-text-xs-line-height"),Q.literal("--font-text-sm-line-height"),Q.literal("--font-text-md-line-height"),Q.literal("--font-text-lg-line-height"),Q.literal("--font-heading-xs-line-height"),Q.literal("--font-heading-sm-line-height"),Q.literal("--font-heading-md-line-height"),Q.literal("--font-heading-lg-line-height"),Q.literal("--font-heading-xl-line-height"),Q.literal("--font-heading-2xl-line-height"),Q.literal("--font-heading-3xl-line-height"),Q.literal("--border-radius-xs"),Q.literal("--border-radius-sm"),Q.literal("--border-radius-md"),Q.literal("--border-radius-lg"),Q.literal("--border-radius-xl"),Q.literal("--border-radius-full"),Q.literal("--border-width-regular"),Q.literal("--shadow-hairline"),Q.literal("--shadow-sm"),Q.literal("--shadow-md"),Q.literal("--shadow-lg")]).describe("CSS variable keys available to MCP apps for theming."),r=Q.record(p.describe(`Style variables for theming MCP apps.
import{CallToolRequestSchema as WQ,CallToolResultSchema as BQ,EmptyResultSchema as KQ,ListResourcesResultSchema as NQ,ListToolsRequestSchema as YQ,PingRequestSchema as jQ,ReadResourceResultSchema as FQ}from"@modelcontextprotocol/sdk/types.js";import{Protocol as d}from"@modelcontextprotocol/sdk/shared/protocol.js";class j extends d{_registeredMethods=new Set;_eventSlots=new Map;onEventDispatch(Z,$){}_ensureEventSlot(Z){let $=this._eventSlots.get(Z);if(!$){let J=this.eventSchemas[Z];if(!J)throw Error(`Unknown event: ${String(Z)}`);$={listeners:[]},this._eventSlots.set(Z,$);let X=J.shape.method.value;this._registeredMethods.add(X);let V=$;super.setNotificationHandler(J,(D)=>{let G=D.params;this.onEventDispatch(Z,G),V.onHandler?.(G);for(let L of[...V.listeners])L(G)})}return $}setEventHandler(Z,$){let J=this._ensureEventSlot(Z);if(J.onHandler&&$)console.warn(`[MCP Apps] on${String(Z)} handler replaced. Use addEventListener("${String(Z)}", …) to add multiple listeners without replacing.`);J.onHandler=$}getEventHandler(Z){return this._eventSlots.get(Z)?.onHandler}addEventListener(Z,$){this._ensureEventSlot(Z).listeners.push($)}removeEventListener(Z,$){let J=this._eventSlots.get(Z);if(!J)return;let X=J.listeners.indexOf($);if(X!==-1)J.listeners.splice(X,1)}setRequestHandler=(Z,$)=>{this._assertMethodNotRegistered(Z,"setRequestHandler"),super.setRequestHandler(Z,$)};setNotificationHandler=(Z,$)=>{this._assertMethodNotRegistered(Z,"setNotificationHandler"),super.setNotificationHandler(Z,$)};warnIfRequestHandlerReplaced(Z,$,J){if($&&J)console.warn(`[MCP Apps] ${Z} handler replaced. Previous handler will no longer be called.`)}replaceRequestHandler=(Z,$)=>{let J=Z.shape.method.value;this._registeredMethods.add(J),super.setRequestHandler(Z,$)};_assertMethodNotRegistered(Z,$){let J=Z.shape.method.value;if(this._registeredMethods.has(J))throw Error(`Handler for "${J}" already registered (via ${$}). Use addEventListener() to attach multiple listeners, or the on* setter for replace semantics.`);this._registeredMethods.add(J)}}import{JSONRPCMessageSchema as h}from"@modelcontextprotocol/sdk/types.js";var F="2026-01-26";var z="ui/notifications/tool-input-partial";class B{eventTarget;eventSource;messageListener;constructor(Z=window.parent,$){this.eventTarget=Z;this.eventSource=$;this.messageListener=(J)=>{if($&&J.source!==this.eventSource){console.debug("Ignoring message from unknown source",J);return}let X=h.safeParse(J.data);if(X.success)console.debug("Parsed message",X.data),this.onmessage?.(X.data);else if(J.data?.jsonrpc!=="2.0")console.debug("Ignoring non-JSON-RPC message",X.error.message,J);else console.error("Failed to parse message",X.error.message,J),this.onerror?.(Error("Invalid JSON-RPC message received: "+X.error.message))}}async start(){window.addEventListener("message",this.messageListener)}async send(Z,$){if(Z.method!==z)console.debug("Sending message",Z);this.eventTarget.postMessage(Z,"*")}async close(){window.removeEventListener("message",this.messageListener),this.onclose?.()}onclose;onerror;onmessage;sessionId;setProtocolVersion}import{z as Q}from"zod/v4";import{ContentBlockSchema as x,CallToolResultSchema as m,EmbeddedResourceSchema as p,ImplementationSchema as g,RequestIdSchema as c,ResourceLinkSchema as l,ToolSchema as r}from"@modelcontextprotocol/sdk/types.js";var S=Q.union([Q.literal("light"),Q.literal("dark")]).describe("Color theme preference for the host environment."),W=Q.union([Q.literal("inline"),Q.literal("fullscreen"),Q.literal("pip")]).describe("Display mode for UI presentation."),i=Q.union([Q.literal("--color-background-primary"),Q.literal("--color-background-secondary"),Q.literal("--color-background-tertiary"),Q.literal("--color-background-inverse"),Q.literal("--color-background-ghost"),Q.literal("--color-background-info"),Q.literal("--color-background-danger"),Q.literal("--color-background-success"),Q.literal("--color-background-warning"),Q.literal("--color-background-disabled"),Q.literal("--color-text-primary"),Q.literal("--color-text-secondary"),Q.literal("--color-text-tertiary"),Q.literal("--color-text-inverse"),Q.literal("--color-text-ghost"),Q.literal("--color-text-info"),Q.literal("--color-text-danger"),Q.literal("--color-text-success"),Q.literal("--color-text-warning"),Q.literal("--color-text-disabled"),Q.literal("--color-border-primary"),Q.literal("--color-border-secondary"),Q.literal("--color-border-tertiary"),Q.literal("--color-border-inverse"),Q.literal("--color-border-ghost"),Q.literal("--color-border-info"),Q.literal("--color-border-danger"),Q.literal("--color-border-success"),Q.literal("--color-border-warning"),Q.literal("--color-border-disabled"),Q.literal("--color-ring-primary"),Q.literal("--color-ring-secondary"),Q.literal("--color-ring-inverse"),Q.literal("--color-ring-info"),Q.literal("--color-ring-danger"),Q.literal("--color-ring-success"),Q.literal("--color-ring-warning"),Q.literal("--font-sans"),Q.literal("--font-mono"),Q.literal("--font-weight-normal"),Q.literal("--font-weight-medium"),Q.literal("--font-weight-semibold"),Q.literal("--font-weight-bold"),Q.literal("--font-text-xs-size"),Q.literal("--font-text-sm-size"),Q.literal("--font-text-md-size"),Q.literal("--font-text-lg-size"),Q.literal("--font-heading-xs-size"),Q.literal("--font-heading-sm-size"),Q.literal("--font-heading-md-size"),Q.literal("--font-heading-lg-size"),Q.literal("--font-heading-xl-size"),Q.literal("--font-heading-2xl-size"),Q.literal("--font-heading-3xl-size"),Q.literal("--font-text-xs-line-height"),Q.literal("--font-text-sm-line-height"),Q.literal("--font-text-md-line-height"),Q.literal("--font-text-lg-line-height"),Q.literal("--font-heading-xs-line-height"),Q.literal("--font-heading-sm-line-height"),Q.literal("--font-heading-md-line-height"),Q.literal("--font-heading-lg-line-height"),Q.literal("--font-heading-xl-line-height"),Q.literal("--font-heading-2xl-line-height"),Q.literal("--font-heading-3xl-line-height"),Q.literal("--border-radius-xs"),Q.literal("--border-radius-sm"),Q.literal("--border-radius-md"),Q.literal("--border-radius-lg"),Q.literal("--border-radius-xl"),Q.literal("--border-radius-full"),Q.literal("--border-width-regular"),Q.literal("--shadow-hairline"),Q.literal("--shadow-sm"),Q.literal("--shadow-md"),Q.literal("--shadow-lg")]).describe("CSS variable keys available to MCP apps for theming."),n=Q.record(i.describe(`Style variables for theming MCP apps.

@@ -19,6 +19,6 @@ Individual style keys are optional - hosts may provide any subset of these values.

Note: This type uses \`Record<K, string | undefined>\` rather than \`Partial<Record<K, string>>\`
for compatibility with Zod schema generation. Both are functionally equivalent for validation.`),n=Q.object({method:Q.literal("ui/open-link"),params:Q.object({url:Q.string().describe("URL to open in the host's browser")})}),q=Q.object({isError:Q.boolean().optional().describe("True if the host failed to open the URL (e.g., due to security policy).")}).passthrough(),O=Q.object({isError:Q.boolean().optional().describe("True if the download failed (e.g., user cancelled or host denied).")}).passthrough(),I=Q.object({isError:Q.boolean().optional().describe("True if the host rejected or failed to deliver the message.")}).passthrough(),i=Q.object({method:Q.literal("ui/notifications/sandbox-proxy-ready"),params:Q.object({})}),B=Q.object({connectDomains:Q.array(Q.string()).optional().describe(`Origins for network requests (fetch/XHR/WebSocket).
for compatibility with Zod schema generation. Both are functionally equivalent for validation.`),o=Q.object({method:Q.literal("ui/open-link"),params:Q.object({url:Q.string().describe("URL to open in the host's browser")})}),O=Q.object({isError:Q.boolean().optional().describe("True if the host failed to open the URL (e.g., due to security policy).")}).passthrough(),I=Q.object({isError:Q.boolean().optional().describe("True if the download failed (e.g., user cancelled or host denied).")}).passthrough(),w=Q.object({isError:Q.boolean().optional().describe("True if the host rejected or failed to deliver the message.")}).passthrough(),a=Q.object({method:Q.literal("ui/notifications/sandbox-proxy-ready"),params:Q.object({})}),K=Q.object({connectDomains:Q.array(Q.string()).optional().describe(`Origins for network requests (fetch/XHR/WebSocket).
- Maps to CSP \`connect-src\` directive
- Empty or omitted → no network connections (secure default)`),resourceDomains:Q.array(Q.string()).optional().describe("Origins for static resources (images, scripts, stylesheets, fonts, media).\n\n- Maps to CSP `img-src`, `script-src`, `style-src`, `font-src`, `media-src` directives\n- Wildcard subdomains supported: `https://*.example.com`\n- Empty or omitted → no network resources (secure default)"),frameDomains:Q.array(Q.string()).optional().describe("Origins for nested iframes.\n\n- Maps to CSP `frame-src` directive\n- Empty or omitted → no nested iframes allowed (`frame-src 'none'`)"),baseUriDomains:Q.array(Q.string()).optional().describe("Allowed base URIs for the document.\n\n- Maps to CSP `base-uri` directive\n- Empty or omitted → only same origin allowed (`base-uri 'self'`)")}),K=Q.object({camera:Q.object({}).optional().describe("Request camera access.\n\nMaps to Permission Policy `camera` feature."),microphone:Q.object({}).optional().describe("Request microphone access.\n\nMaps to Permission Policy `microphone` feature."),geolocation:Q.object({}).optional().describe("Request geolocation access.\n\nMaps to Permission Policy `geolocation` feature."),clipboardWrite:Q.object({}).optional().describe("Request clipboard write access.\n\nMaps to Permission Policy `clipboard-write` feature.")}),o=Q.object({method:Q.literal("ui/notifications/size-changed"),params:Q.object({width:Q.number().optional().describe("New width in pixels."),height:Q.number().optional().describe("New height in pixels.")})}),w=Q.object({method:Q.literal("ui/notifications/tool-input"),params:Q.object({arguments:Q.record(Q.string(),Q.unknown().describe("Complete tool call arguments as key-value pairs.")).optional().describe("Complete tool call arguments as key-value pairs.")})}),A=Q.object({method:Q.literal("ui/notifications/tool-input-partial"),params:Q.object({arguments:Q.record(Q.string(),Q.unknown().describe("Partial tool call arguments (incomplete, may change).")).optional().describe("Partial tool call arguments (incomplete, may change).")})}),P=Q.object({method:Q.literal("ui/notifications/tool-cancelled"),params:Q.object({reason:Q.string().optional().describe('Optional reason for the cancellation (e.g., "user action", "timeout").')})}),b=Q.object({fonts:Q.string().optional()}),g=Q.object({variables:r.optional().describe("CSS variables for theming the app."),css:b.optional().describe("CSS blocks that apps can inject.")}),H=Q.object({method:Q.literal("ui/resource-teardown"),params:Q.object({})}),a=Q.record(Q.string(),Q.unknown()),z=Q.object({text:Q.object({}).optional().describe("Host supports text content blocks."),image:Q.object({}).optional().describe("Host supports image content blocks."),audio:Q.object({}).optional().describe("Host supports audio content blocks."),resource:Q.object({}).optional().describe("Host supports resource content blocks."),resourceLink:Q.object({}).optional().describe("Host supports resource link content blocks."),structuredContent:Q.object({}).optional().describe("Host supports structured content.")}),s=Q.object({method:Q.literal("ui/notifications/request-teardown"),params:Q.object({}).optional()}),S=Q.object({experimental:Q.object({}).optional().describe("Experimental features (structure TBD)."),openLinks:Q.object({}).optional().describe("Host supports opening external URLs."),downloadFile:Q.object({}).optional().describe("Host supports file downloads via ui/download-file."),serverTools:Q.object({listChanged:Q.boolean().optional().describe("Host supports tools/list_changed notifications.")}).optional().describe("Host can proxy tool calls to the MCP server."),serverResources:Q.object({listChanged:Q.boolean().optional().describe("Host supports resources/list_changed notifications.")}).optional().describe("Host can proxy resource reads to the MCP server."),logging:Q.object({}).optional().describe("Host accepts log messages."),sandbox:Q.object({permissions:K.optional().describe("Permissions granted by the host (camera, microphone, geolocation)."),csp:B.optional().describe("CSP domains approved by the host.")}).optional().describe("Sandbox configuration applied by the host."),updateModelContext:z.optional().describe("Host accepts context updates (ui/update-model-context) to be included in the model's context for future turns."),message:z.optional().describe("Host supports receiving content messages (ui/message) from the view.")}),y=Q.object({experimental:Q.object({}).optional().describe("Experimental features (structure TBD)."),tools:Q.object({listChanged:Q.boolean().optional().describe("App supports tools/list_changed notifications.")}).optional().describe("App exposes MCP-style tools that the host can call."),availableDisplayModes:Q.array(G).optional().describe("Display modes the app supports.")}),t=Q.object({method:Q.literal("ui/notifications/initialized"),params:Q.object({}).optional()}),e=Q.object({csp:B.optional().describe("Content Security Policy configuration for UI resources."),permissions:K.optional().describe("Sandbox permissions requested by the UI resource."),domain:Q.string().optional().describe(`Dedicated origin for view sandbox.
- Empty or omitted → no network connections (secure default)`),resourceDomains:Q.array(Q.string()).optional().describe("Origins for static resources (images, scripts, stylesheets, fonts, media).\n\n- Maps to CSP `img-src`, `script-src`, `style-src`, `font-src`, `media-src` directives\n- Wildcard subdomains supported: `https://*.example.com`\n- Empty or omitted → no network resources (secure default)"),frameDomains:Q.array(Q.string()).optional().describe("Origins for nested iframes.\n\n- Maps to CSP `frame-src` directive\n- Empty or omitted → no nested iframes allowed (`frame-src 'none'`)"),baseUriDomains:Q.array(Q.string()).optional().describe("Allowed base URIs for the document.\n\n- Maps to CSP `base-uri` directive\n- Empty or omitted → only same origin allowed (`base-uri 'self'`)")}),N=Q.object({camera:Q.object({}).optional().describe("Request camera access.\n\nMaps to Permission Policy `camera` feature."),microphone:Q.object({}).optional().describe("Request microphone access.\n\nMaps to Permission Policy `microphone` feature."),geolocation:Q.object({}).optional().describe("Request geolocation access.\n\nMaps to Permission Policy `geolocation` feature."),clipboardWrite:Q.object({}).optional().describe("Request clipboard write access.\n\nMaps to Permission Policy `clipboard-write` feature.")}),s=Q.object({method:Q.literal("ui/notifications/size-changed"),params:Q.object({width:Q.number().optional().describe("New width in pixels."),height:Q.number().optional().describe("New height in pixels.")})}),A=Q.object({method:Q.literal("ui/notifications/tool-input"),params:Q.object({arguments:Q.record(Q.string(),Q.unknown().describe("Complete tool call arguments as key-value pairs.")).optional().describe("Complete tool call arguments as key-value pairs.")})}),P=Q.object({method:Q.literal("ui/notifications/tool-input-partial"),params:Q.object({arguments:Q.record(Q.string(),Q.unknown().describe("Partial tool call arguments (incomplete, may change).")).optional().describe("Partial tool call arguments (incomplete, may change).")})}),H=Q.object({method:Q.literal("ui/notifications/tool-cancelled"),params:Q.object({reason:Q.string().optional().describe('Optional reason for the cancellation (e.g., "user action", "timeout").')})}),b=Q.object({fonts:Q.string().optional()}),C=Q.object({variables:n.optional().describe("CSS variables for theming the app."),css:b.optional().describe("CSS blocks that apps can inject.")}),_=Q.object({method:Q.literal("ui/resource-teardown"),params:Q.object({})}),t=Q.record(Q.string(),Q.unknown()),q=Q.object({text:Q.object({}).optional().describe("Host supports text content blocks."),image:Q.object({}).optional().describe("Host supports image content blocks."),audio:Q.object({}).optional().describe("Host supports audio content blocks."),resource:Q.object({}).optional().describe("Host supports resource content blocks."),resourceLink:Q.object({}).optional().describe("Host supports resource link content blocks."),structuredContent:Q.object({}).optional().describe("Host supports structured content.")}),e=Q.object({method:Q.literal("ui/notifications/request-teardown"),params:Q.object({}).optional()}),y=Q.object({experimental:Q.object({}).optional().describe("Experimental features (structure TBD)."),openLinks:Q.object({}).optional().describe("Host supports opening external URLs."),downloadFile:Q.object({}).optional().describe("Host supports file downloads via ui/download-file."),serverTools:Q.object({listChanged:Q.boolean().optional().describe("Host supports tools/list_changed notifications.")}).optional().describe("Host can proxy tool calls to the MCP server."),serverResources:Q.object({listChanged:Q.boolean().optional().describe("Host supports resources/list_changed notifications.")}).optional().describe("Host can proxy resource reads to the MCP server."),logging:Q.object({}).optional().describe("Host accepts log messages."),sandbox:Q.object({permissions:N.optional().describe("Permissions granted by the host (camera, microphone, geolocation)."),csp:K.optional().describe("CSP domains approved by the host.")}).optional().describe("Sandbox configuration applied by the host."),updateModelContext:q.optional().describe("Host accepts context updates (ui/update-model-context) to be included in the model's context for future turns."),message:q.optional().describe("Host supports receiving content messages (ui/message) from the view.")}),v=Q.object({experimental:Q.object({}).optional().describe("Experimental features (structure TBD)."),tools:Q.object({listChanged:Q.boolean().optional().describe("App supports tools/list_changed notifications.")}).optional().describe("App exposes MCP-style tools that the host can call."),availableDisplayModes:Q.array(W).optional().describe("Display modes the app supports.")}),QQ=Q.object({method:Q.literal("ui/notifications/initialized"),params:Q.object({}).optional()}),ZQ=Q.object({csp:K.optional().describe("Content Security Policy configuration for UI resources."),permissions:N.optional().describe("Sandbox permissions requested by the UI resource."),domain:Q.string().optional().describe(`Dedicated origin for view sandbox.

@@ -37,5 +37,5 @@ Useful when views need stable, dedicated origins for OAuth callbacks, CORS policies, or API key allowlists.

- \`false\`: request no visible border + background
- omitted: host decides border`)}),QQ=Q.object({method:Q.literal("ui/request-display-mode"),params:Q.object({mode:G.describe("The display mode being requested.")})}),_=Q.object({mode:G.describe("The display mode that was actually set. May differ from requested if not supported.")}).passthrough(),C=Q.union([Q.literal("model"),Q.literal("app")]).describe("Tool visibility scope - who can access the tool."),ZQ=Q.object({resourceUri:Q.string().optional(),visibility:Q.array(C).optional().describe(`Who can access this tool. Default: ["model", "app"]
- omitted: host decides border`)}),$Q=Q.object({method:Q.literal("ui/request-display-mode"),params:Q.object({mode:W.describe("The display mode being requested.")})}),T=Q.object({mode:W.describe("The display mode that was actually set. May differ from requested if not supported.")}).passthrough(),f=Q.union([Q.literal("model"),Q.literal("app")]).describe("Tool visibility scope - who can access the tool."),JQ=Q.object({resourceUri:Q.string().optional(),visibility:Q.array(f).optional().describe(`Who can access this tool. Default: ["model", "app"]
- "model": Tool visible to and callable by the agent
- "app": Tool callable by the app from this server only`)}),TQ=Q.object({mimeTypes:Q.array(Q.string()).optional().describe('Array of supported MIME types for UI resources.\nMust include `"text/html;profile=mcp-app"` for MCP Apps support.')}),$Q=Q.object({method:Q.literal("ui/download-file"),params:Q.object({contents:Q.array(Q.union([h,c])).describe("Resource contents to download — embedded (inline data) or linked (host fetches). Uses standard MCP resource types.")})}),JQ=Q.object({method:Q.literal("ui/message"),params:Q.object({role:Q.literal("user").describe('Message role, currently only "user" is supported.'),content:Q.array(v).describe("Message content blocks (text, image, etc.).")})}),XQ=Q.object({method:Q.literal("ui/notifications/sandbox-resource-ready"),params:Q.object({html:Q.string().describe("HTML content to load into the inner iframe."),sandbox:Q.string().optional().describe("Optional override for the inner iframe's sandbox attribute."),csp:B.optional().describe("CSP configuration from resource metadata."),permissions:K.optional().describe("Sandbox permissions from resource metadata.")})}),T=Q.object({method:Q.literal("ui/notifications/tool-result"),params:d.describe("Standard MCP tool execution result.")}),E=Q.object({toolInfo:Q.object({id:m.optional().describe("JSON-RPC id of the tools/call request."),tool:l.describe("Tool definition including name, inputSchema, etc.")}).optional().describe("Metadata of the tool call that instantiated this App."),theme:M.optional().describe("Current color theme preference."),styles:g.optional().describe("Style configuration for theming the app."),displayMode:G.optional().describe("How the UI is currently displayed."),availableDisplayModes:Q.array(G).optional().describe("Display modes the host supports."),containerDimensions:Q.union([Q.object({height:Q.number().describe("Fixed container height in pixels.")}),Q.object({maxHeight:Q.union([Q.number(),Q.undefined()]).optional().describe("Maximum container height in pixels.")})]).and(Q.union([Q.object({width:Q.number().describe("Fixed container width in pixels.")}),Q.object({maxWidth:Q.union([Q.number(),Q.undefined()]).optional().describe("Maximum container width in pixels.")})])).optional().describe(`Container dimensions. Represents the dimensions of the iframe or other
container holding the app. Specify either width or maxWidth, and either height or maxHeight.`),locale:Q.string().optional().describe("User's language and region preference in BCP 47 format."),timeZone:Q.string().optional().describe("User's timezone in IANA format."),userAgent:Q.string().optional().describe("Host application identifier."),platform:Q.union([Q.literal("web"),Q.literal("desktop"),Q.literal("mobile")]).optional().describe("Platform type for responsive design decisions."),deviceCapabilities:Q.object({touch:Q.boolean().optional().describe("Whether the device supports touch input."),hover:Q.boolean().optional().describe("Whether the device supports hover interactions.")}).optional().describe("Device input capabilities."),safeAreaInsets:Q.object({top:Q.number().describe("Top safe area inset in pixels."),right:Q.number().describe("Right safe area inset in pixels."),bottom:Q.number().describe("Bottom safe area inset in pixels."),left:Q.number().describe("Left safe area inset in pixels.")}).optional().describe("Mobile safe area boundaries in pixels.")}).passthrough(),k=Q.object({method:Q.literal("ui/notifications/host-context-changed"),params:E.describe("Partial context update containing only changed fields.")}),VQ=Q.object({method:Q.literal("ui/update-model-context"),params:Q.object({content:Q.array(v).optional().describe("Context content blocks (text, image, etc.)."),structuredContent:Q.record(Q.string(),Q.unknown().describe("Structured content for machine-readable context data.")).optional().describe("Structured content for machine-readable context data.")})}),WQ=Q.object({method:Q.literal("ui/initialize"),params:Q.object({appInfo:x.describe("App identification (name and version)."),appCapabilities:y.describe("Features and capabilities this app provides."),protocolVersion:Q.string().describe("Protocol version this app supports.")})}),R=Q.object({protocolVersion:Q.string().describe('Negotiated protocol version string (e.g., "2025-11-21").'),hostInfo:x.describe("Host application identification and version."),hostCapabilities:S.describe("Features and capabilities provided by the host."),hostContext:E.describe("Rich context about the host environment.")}).passthrough();var U="ui/resourceUri",f="text/html;profile=mcp-app";class FQ extends DQ{_appInfo;_capabilities;options;_hostCapabilities;_hostInfo;_hostContext;constructor(Z,$={},J={autoResize:!0}){super(J);this._appInfo=Z;this._capabilities=$;this.options=J;this.setRequestHandler(NQ,(X)=>{return console.log("Received ping:",X.params),{}}),this.onhostcontextchanged=()=>{}}getHostCapabilities(){return this._hostCapabilities}getHostVersion(){return this._hostInfo}getHostContext(){return this._hostContext}set ontoolinput(Z){this.setNotificationHandler(w,($)=>Z($.params))}set ontoolinputpartial(Z){this.setNotificationHandler(A,($)=>Z($.params))}set ontoolresult(Z){this.setNotificationHandler(T,($)=>Z($.params))}set ontoolcancelled(Z){this.setNotificationHandler(P,($)=>Z($.params))}set onhostcontextchanged(Z){this.setNotificationHandler(k,($)=>{this._hostContext={...this._hostContext,...$.params},Z($.params)})}set onteardown(Z){this.setRequestHandler(H,($,J)=>Z($.params,J))}set oncalltool(Z){this.setRequestHandler(GQ,($,J)=>Z($.params,J))}set onlisttools(Z){this.setRequestHandler(KQ,($,J)=>Z($.params,J))}assertCapabilityForMethod(Z){}assertRequestHandlerCapability(Z){switch(Z){case"tools/call":case"tools/list":if(!this._capabilities.tools)throw Error(`Client does not support tool capability (required for ${Z})`);return;case"ping":case"ui/resource-teardown":return;default:throw Error(`No handler for method ${Z} registered`)}}assertNotificationCapability(Z){}assertTaskCapability(Z){throw Error("Tasks are not supported in MCP Apps")}assertTaskHandlerCapability(Z){throw Error("Task handlers are not supported in MCP Apps")}async callServerTool(Z,$){if(typeof Z==="string")throw Error(`callServerTool() expects an object as its first argument, but received a string ("${Z}"). Did you mean: callServerTool({ name: "${Z}", arguments: { ... } })?`);return await this.request({method:"tools/call",params:Z},LQ,$)}async readServerResource(Z,$){return await this.request({method:"resources/read",params:Z},YQ,$)}async listServerResources(Z,$){return await this.request({method:"resources/list",params:Z},BQ,$)}sendMessage(Z,$){return this.request({method:"ui/message",params:Z},I,$)}sendLog(Z){return this.notification({method:"notifications/message",params:Z})}updateModelContext(Z,$){return this.request({method:"ui/update-model-context",params:Z},jQ,$)}openLink(Z,$){return this.request({method:"ui/open-link",params:Z},q,$)}sendOpenLink=this.openLink;downloadFile(Z,$){return this.request({method:"ui/download-file",params:Z},O,$)}requestTeardown(Z={}){return this.notification({method:"ui/notifications/request-teardown",params:Z})}requestDisplayMode(Z,$){return this.request({method:"ui/request-display-mode",params:Z},_,$)}sendSizeChanged(Z){return this.notification({method:"ui/notifications/size-changed",params:Z})}setupSizeChangedNotifications(){let Z=!1,$=0,J=0,X=()=>{if(Z)return;Z=!0,requestAnimationFrame(()=>{Z=!1;let W=document.documentElement,L=W.style.height;W.style.height="max-content";let D=Math.ceil(W.getBoundingClientRect().height);W.style.height=L;let N=Math.ceil(window.innerWidth);if(N!==$||D!==J)$=N,J=D,this.sendSizeChanged({width:N,height:D})})};X();let V=new ResizeObserver(X);return V.observe(document.documentElement),V.observe(document.body),()=>V.disconnect()}async connect(Z=new j(window.parent,window.parent),$){if(this.transport)throw Error("App is already connected. Call close() before connecting again.");await super.connect(Z);try{let J=await this.request({method:"ui/initialize",params:{appCapabilities:this._capabilities,appInfo:this._appInfo,protocolVersion:Y}},R,$);if(J===void 0)throw Error(`Server sent invalid initialize result: ${J}`);if(this._hostCapabilities=J.hostCapabilities,this._hostInfo=J.hostInfo,this._hostContext=J.hostContext,await this.notification({method:"ui/notifications/initialized"}),this.options?.autoResize)this.setupSizeChangedNotifications()}catch(J){throw this.close(),J}}}function fZ(Z,$,J,X){let V=J._meta,W=V.ui,L=V[U],D=V;if(W?.resourceUri&&!L)D={...V,[U]:W.resourceUri};else if(L&&!W?.resourceUri)D={...V,ui:{...W,resourceUri:L}};return Z.registerTool($,{...J,_meta:D},X)}function uZ(Z,$,J,X,V){return Z.registerResource($,J,{mimeType:f,...X},V)}var zQ="io.modelcontextprotocol/ui";function dZ(Z){if(!Z)return;return Z.extensions?.[zQ]}export{fZ as registerAppTool,uZ as registerAppResource,dZ as getUiCapability,U as RESOURCE_URI_META_KEY,f as RESOURCE_MIME_TYPE,zQ as EXTENSION_ID};
- "app": Tool callable by the app from this server only`)}),UQ=Q.object({mimeTypes:Q.array(Q.string()).optional().describe('Array of supported MIME types for UI resources.\nMust include `"text/html;profile=mcp-app"` for MCP Apps support.')}),XQ=Q.object({method:Q.literal("ui/download-file"),params:Q.object({contents:Q.array(Q.union([p,l])).describe("Resource contents to download — embedded (inline data) or linked (host fetches). Uses standard MCP resource types.")})}),VQ=Q.object({method:Q.literal("ui/message"),params:Q.object({role:Q.literal("user").describe('Message role, currently only "user" is supported.'),content:Q.array(x).describe("Message content blocks (text, image, etc.).")})}),DQ=Q.object({method:Q.literal("ui/notifications/sandbox-resource-ready"),params:Q.object({html:Q.string().describe("HTML content to load into the inner iframe."),sandbox:Q.string().optional().describe("Optional override for the inner iframe's sandbox attribute."),csp:K.optional().describe("CSP configuration from resource metadata."),permissions:N.optional().describe("Sandbox permissions from resource metadata.")})}),R=Q.object({method:Q.literal("ui/notifications/tool-result"),params:m.describe("Standard MCP tool execution result.")}),E=Q.object({toolInfo:Q.object({id:c.optional().describe("JSON-RPC id of the tools/call request."),tool:r.describe("Tool definition including name, inputSchema, etc.")}).optional().describe("Metadata of the tool call that instantiated this App."),theme:S.optional().describe("Current color theme preference."),styles:C.optional().describe("Style configuration for theming the app."),displayMode:W.optional().describe("How the UI is currently displayed."),availableDisplayModes:Q.array(W).optional().describe("Display modes the host supports."),containerDimensions:Q.union([Q.object({height:Q.number().describe("Fixed container height in pixels.")}),Q.object({maxHeight:Q.union([Q.number(),Q.undefined()]).optional().describe("Maximum container height in pixels.")})]).and(Q.union([Q.object({width:Q.number().describe("Fixed container width in pixels.")}),Q.object({maxWidth:Q.union([Q.number(),Q.undefined()]).optional().describe("Maximum container width in pixels.")})])).optional().describe(`Container dimensions. Represents the dimensions of the iframe or other
container holding the app. Specify either width or maxWidth, and either height or maxHeight.`),locale:Q.string().optional().describe("User's language and region preference in BCP 47 format."),timeZone:Q.string().optional().describe("User's timezone in IANA format."),userAgent:Q.string().optional().describe("Host application identifier."),platform:Q.union([Q.literal("web"),Q.literal("desktop"),Q.literal("mobile")]).optional().describe("Platform type for responsive design decisions."),deviceCapabilities:Q.object({touch:Q.boolean().optional().describe("Whether the device supports touch input."),hover:Q.boolean().optional().describe("Whether the device supports hover interactions.")}).optional().describe("Device input capabilities."),safeAreaInsets:Q.object({top:Q.number().describe("Top safe area inset in pixels."),right:Q.number().describe("Right safe area inset in pixels."),bottom:Q.number().describe("Bottom safe area inset in pixels."),left:Q.number().describe("Left safe area inset in pixels.")}).optional().describe("Mobile safe area boundaries in pixels.")}).passthrough(),U=Q.object({method:Q.literal("ui/notifications/host-context-changed"),params:E.describe("Partial context update containing only changed fields.")}),GQ=Q.object({method:Q.literal("ui/update-model-context"),params:Q.object({content:Q.array(x).optional().describe("Context content blocks (text, image, etc.)."),structuredContent:Q.record(Q.string(),Q.unknown().describe("Structured content for machine-readable context data.")).optional().describe("Structured content for machine-readable context data.")})}),LQ=Q.object({method:Q.literal("ui/initialize"),params:Q.object({appInfo:g.describe("App identification (name and version)."),appCapabilities:v.describe("Features and capabilities this app provides."),protocolVersion:Q.string().describe("Protocol version this app supports.")})}),k=Q.object({protocolVersion:Q.string().describe('Negotiated protocol version string (e.g., "2025-11-21").'),hostInfo:g.describe("Host application identification and version."),hostCapabilities:y.describe("Features and capabilities provided by the host."),hostContext:E.describe("Rich context about the host environment.")}).passthrough();var M="ui/resourceUri",u="text/html;profile=mcp-app";class zQ extends j{_appInfo;_capabilities;options;_hostCapabilities;_hostInfo;_hostContext;eventSchemas={toolinput:A,toolinputpartial:P,toolresult:R,toolcancelled:H,hostcontextchanged:U};onEventDispatch(Z,$){if(Z==="hostcontextchanged")this._hostContext={...this._hostContext,...$}}constructor(Z,$={},J={autoResize:!0}){super(J);this._appInfo=Z;this._capabilities=$;this.options=J;this.setRequestHandler(jQ,(X)=>{return console.log("Received ping:",X.params),{}}),this.setEventHandler("hostcontextchanged",void 0)}getHostCapabilities(){return this._hostCapabilities}getHostVersion(){return this._hostInfo}getHostContext(){return this._hostContext}get ontoolinput(){return this.getEventHandler("toolinput")}set ontoolinput(Z){this.setEventHandler("toolinput",Z)}get ontoolinputpartial(){return this.getEventHandler("toolinputpartial")}set ontoolinputpartial(Z){this.setEventHandler("toolinputpartial",Z)}get ontoolresult(){return this.getEventHandler("toolresult")}set ontoolresult(Z){this.setEventHandler("toolresult",Z)}get ontoolcancelled(){return this.getEventHandler("toolcancelled")}set ontoolcancelled(Z){this.setEventHandler("toolcancelled",Z)}get onhostcontextchanged(){return this.getEventHandler("hostcontextchanged")}set onhostcontextchanged(Z){this.setEventHandler("hostcontextchanged",Z)}_onteardown;get onteardown(){return this._onteardown}set onteardown(Z){this.warnIfRequestHandlerReplaced("onteardown",this._onteardown,Z),this._onteardown=Z,this.replaceRequestHandler(_,($,J)=>{if(!this._onteardown)throw Error("No onteardown handler set");return this._onteardown($.params,J)})}_oncalltool;get oncalltool(){return this._oncalltool}set oncalltool(Z){this.warnIfRequestHandlerReplaced("oncalltool",this._oncalltool,Z),this._oncalltool=Z,this.replaceRequestHandler(WQ,($,J)=>{if(!this._oncalltool)throw Error("No oncalltool handler set");return this._oncalltool($.params,J)})}_onlisttools;get onlisttools(){return this._onlisttools}set onlisttools(Z){this.warnIfRequestHandlerReplaced("onlisttools",this._onlisttools,Z),this._onlisttools=Z,this.replaceRequestHandler(YQ,($,J)=>{if(!this._onlisttools)throw Error("No onlisttools handler set");return this._onlisttools($.params,J)})}assertCapabilityForMethod(Z){}assertRequestHandlerCapability(Z){switch(Z){case"tools/call":case"tools/list":if(!this._capabilities.tools)throw Error(`Client does not support tool capability (required for ${Z})`);return;case"ping":case"ui/resource-teardown":return;default:throw Error(`No handler for method ${Z} registered`)}}assertNotificationCapability(Z){}assertTaskCapability(Z){throw Error("Tasks are not supported in MCP Apps")}assertTaskHandlerCapability(Z){throw Error("Task handlers are not supported in MCP Apps")}async callServerTool(Z,$){if(typeof Z==="string")throw Error(`callServerTool() expects an object as its first argument, but received a string ("${Z}"). Did you mean: callServerTool({ name: "${Z}", arguments: { ... } })?`);return await this.request({method:"tools/call",params:Z},BQ,$)}async readServerResource(Z,$){return await this.request({method:"resources/read",params:Z},FQ,$)}async listServerResources(Z,$){return await this.request({method:"resources/list",params:Z},NQ,$)}sendMessage(Z,$){return this.request({method:"ui/message",params:Z},w,$)}sendLog(Z){return this.notification({method:"notifications/message",params:Z})}updateModelContext(Z,$){return this.request({method:"ui/update-model-context",params:Z},KQ,$)}openLink(Z,$){return this.request({method:"ui/open-link",params:Z},O,$)}sendOpenLink=this.openLink;downloadFile(Z,$){return this.request({method:"ui/download-file",params:Z},I,$)}requestTeardown(Z={}){return this.notification({method:"ui/notifications/request-teardown",params:Z})}requestDisplayMode(Z,$){return this.request({method:"ui/request-display-mode",params:Z},T,$)}sendSizeChanged(Z){return this.notification({method:"ui/notifications/size-changed",params:Z})}setupSizeChangedNotifications(){let Z=!1,$=0,J=0,X=()=>{if(Z)return;Z=!0,requestAnimationFrame(()=>{Z=!1;let D=document.documentElement,G=D.style.height;D.style.height="max-content";let L=Math.ceil(D.getBoundingClientRect().height);D.style.height=G;let Y=Math.ceil(window.innerWidth);if(Y!==$||L!==J)$=Y,J=L,this.sendSizeChanged({width:Y,height:L})})};X();let V=new ResizeObserver(X);return V.observe(document.documentElement),V.observe(document.body),()=>V.disconnect()}async connect(Z=new B(window.parent,window.parent),$){if(this.transport)throw Error("App is already connected. Call close() before connecting again.");await super.connect(Z);try{let J=await this.request({method:"ui/initialize",params:{appCapabilities:this._capabilities,appInfo:this._appInfo,protocolVersion:F}},k,$);if(J===void 0)throw Error(`Server sent invalid initialize result: ${J}`);if(this._hostCapabilities=J.hostCapabilities,this._hostInfo=J.hostInfo,this._hostContext=J.hostContext,await this.notification({method:"ui/notifications/initialized"}),this.options?.autoResize)this.setupSizeChangedNotifications()}catch(J){throw this.close(),J}}}function hZ(Z,$,J,X){let V=J._meta,D=V.ui,G=V[M],L=V;if(D?.resourceUri&&!G)L={...V,[M]:D.resourceUri};else if(G&&!D?.resourceUri)L={...V,ui:{...D,resourceUri:G}};return Z.registerTool($,{...J,_meta:L},X)}function mZ(Z,$,J,X,V){return Z.registerResource($,J,{mimeType:u,...X},V)}var qQ="io.modelcontextprotocol/ui";function pZ(Z){if(!Z)return;return Z.extensions?.[qQ]}export{hZ as registerAppTool,mZ as registerAppResource,pZ as getUiCapability,M as RESOURCE_URI_META_KEY,u as RESOURCE_MIME_TYPE,qQ as EXTENSION_ID};

@@ -8,3 +8,3 @@ {

"homepage": "https://github.com/modelcontextprotocol/ext-apps",
"version": "1.3.2",
"version": "1.4.0",
"license": "MIT",

@@ -80,3 +80,3 @@ "description": "MCP Apps SDK — Enable MCP servers to display interactive user interfaces in conversational clients.",

"@boneskull/typedoc-plugin-mermaid": "^0.2.0",
"@modelcontextprotocol/sdk": "1.25.2",
"@modelcontextprotocol/sdk": "^1.29.0",
"@playwright/test": "1.57.0",

@@ -112,3 +112,3 @@ "@types/bun": "^1.3.2",

"peerDependencies": {
"@modelcontextprotocol/sdk": "^1.24.0",
"@modelcontextprotocol/sdk": "^1.29.0",
"react": "^17.0.0 || ^18.0.0 || ^19.0.0",

@@ -115,0 +115,0 @@ "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.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