Improve JSDoc comments with cross-references and clarifications (#254)

Key improvements:
- Add `{@link}` cross-references throughout the codebase to make API
  documentation navigable and help AI models understand relationships
- Use `{@link module!Export}` syntax for cross-module references
- Add backticks for inline code formatting (`ResizeObserver`, `App`, etc)
- Fix `PostMessageTransport` examples to show required two-argument form
- Clarify `onteardown` callback return type requirement
- Document React hooks cleanup behavior and Strict Mode considerations
- Add tool visibility example for `registerAppTool`
- Add CSP example for `registerAppResource`
- Fix notification direction documentation in `spec.types.ts`

TypeDoc config migrated from `typedoc.json` to `typedoc.config.mjs` to:
- Support custom `@description` block tag
- Add `intentionallyNotExported` for internal types
- Include `src/server/index.ts` entry point

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Jonathan Hefner 2026-01-13 18:41:17 -06:00 • committed by GitHub
commit d48e35d88a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 359 additions and 231 deletions

View file

@ -92,7 +92,7 @@ export { PostMessageTransport } from "./message-transport";
*
* @param tool - A tool object with optional `_meta` property
* @returns The UI resource URI if valid, undefined if not present
* @throws Error if resourceUri is present but invalid (not starting with "ui://")
* @throws Error if resourceUri is present but invalid (does not start with "ui://")
*
* @example
* ```typescript
@ -158,9 +158,12 @@ export function buildAllowAttribute(
}
/**
* Options for configuring AppBridge behavior.
* Options for configuring {@link AppBridge} behavior.
*
* @see ProtocolOptions from @modelcontextprotocol/sdk for available options
* @property hostContext - Optional initial host context to provide to the Guest UI
*
* @see `ProtocolOptions` from @modelcontextprotocol/sdk for available options
* @see {@link McpUiHostContext} for the hostContext structure
*/
export type HostOptions = ProtocolOptions & {
hostContext?: McpUiHostContext;
@ -177,7 +180,7 @@ export const SUPPORTED_PROTOCOL_VERSIONS = [LATEST_PROTOCOL_VERSION];
/**
* Extra metadata passed to request handlers.
*
* This type represents the additional context provided by the Protocol class
* This type represents the additional context provided by the `Protocol` class
* when handling requests, including abort signals and session information.
* It is extracted from the MCP SDK's request handler signature.
*
@ -188,12 +191,13 @@ type RequestHandlerExtra = Parameters<
>[1];
/**
* Host-side bridge for communicating with a single Guest UI (App).
* Host-side bridge for communicating with a single Guest UI ({@link app!App}).
*
* AppBridge extends the MCP SDK's Protocol class and acts as a proxy between
* the host application and a Guest UI running in an iframe. It automatically
* forwards MCP server capabilities (tools, resources, prompts) to the Guest UI
* and handles the initialization handshake.
* `AppBridge` extends the MCP SDK's `Protocol` class and acts as a proxy between
* the host application and a Guest UI running in an iframe. When an MCP client
* is provided to the constructor, it automatically forwards MCP server capabilities
* (tools, resources, prompts) to the Guest UI. It also handles the initialization
* handshake.
*
* ## Architecture
*
@ -205,11 +209,11 @@ type RequestHandlerExtra = Parameters<
*
* ## Lifecycle
*
* 1. **Create**: Instantiate AppBridge with MCP client and capabilities
* 1. **Create**: Instantiate `AppBridge` with MCP client and capabilities
* 2. **Connect**: Call `connect()` with transport to establish communication
* 3. **Wait for init**: Guest UI sends initialize request, bridge responds
* 4. **Send data**: Call `sendToolInput()`, `sendToolResult()`, etc.
* 5. **Teardown**: Call `teardownResource()` before unmounting iframe
* 4. **Send data**: Call {@link sendToolInput}, {@link sendToolResult}, etc.
* 5. **Teardown**: Call {@link teardownResource} before unmounting iframe
*
* @example Basic usage
* ```typescript
@ -261,7 +265,7 @@ export class AppBridge extends Protocol<
* @param _client - MCP client connected to the server, or `null`. When provided,
* {@link connect} will automatically set up forwarding of MCP requests/notifications
* between the Guest UI and the server. When `null`, you must register handlers
* manually using the `oncalltool`, `onlistresources`, etc. setters.
* manually using the {@link oncalltool}, {@link onlistresources}, etc. setters.
* @param _hostInfo - Host application identification (name and version)
* @param _capabilities - Features and capabilities the host supports
* @param options - Configuration options (inherited from Protocol)
@ -363,7 +367,7 @@ export class AppBridge extends Protocol<
* Optional handler for ping requests from the Guest UI.
*
* The Guest UI can send standard MCP `ping` requests to verify the connection
* is alive. The AppBridge automatically responds with an empty object, but this
* is alive. The {@link AppBridge} automatically responds with an empty object, but this
* handler allows the host to observe or log ping activity.
*
* Unlike the other handlers which use setters, this is a direct property
@ -385,7 +389,7 @@ export class AppBridge extends Protocol<
* Register a handler for size change notifications from the Guest UI.
*
* The Guest UI sends `ui/notifications/size-changed` when its rendered content
* size changes, typically via ResizeObserver. Set this callback to dynamically
* size changes, typically via `ResizeObserver`. Set this callback to dynamically
* adjust the iframe container dimensions based on the Guest UI's content.
*
* Note: This is for Guest UI → Host communication. To notify the Guest UI of
@ -404,7 +408,7 @@ export class AppBridge extends Protocol<
* ```
*
* @see {@link McpUiSizeChangedNotification} for the notification type
* @see {@link app.App.sendSizeChanged} for Host → Guest UI size notifications
* @see {@link app!App.sendSizeChanged} - the Guest UI method that sends these notifications
*/
set onsizechange(
callback: (params: McpUiSizeChangedNotification["params"]) => void,
@ -490,10 +494,10 @@ export class AppBridge extends Protocol<
* leakage.
*
* @param callback - Handler that receives message params and returns a result
* - params.role - Message role (currently only "user" is supported)
* - params.content - Message content blocks (text, image, etc.)
* - extra - Request metadata (abort signal, session info)
* - Returns: Promise<McpUiMessageResult> with optional isError flag
* - `params.role` - Message role (currently only "user" is supported)
* - `params.content` - Message content blocks (text, image, etc.)
* - `extra` - Request metadata (abort signal, session info)
* - Returns: `Promise<McpUiMessageResult>` with optional `isError` flag
*
* @example
* ```typescript
@ -539,9 +543,9 @@ export class AppBridge extends Protocol<
* - Reject the request entirely
*
* @param callback - Handler that receives URL params and returns a result
* - params.url - URL to open in the host's browser
* - extra - Request metadata (abort signal, session info)
* - Returns: Promise<McpUiOpenLinkResult> with optional isError flag
* - `params.url` - URL to open in the host's browser
* - `extra` - Request metadata (abort signal, session info)
* - Returns: `Promise<McpUiOpenLinkResult>` with optional `isError` flag
*
* @example
* ```typescript
@ -593,17 +597,22 @@ export class AppBridge extends Protocol<
* If the requested mode is not available, the handler should return the current
* display mode instead.
*
* By default, `AppBridge` returns the current `displayMode` from host context (or "inline").
* Setting this property replaces that default behavior.
*
* @param callback - Handler that receives the requested mode and returns the actual mode set
* - params.mode - The display mode being requested ("inline" | "fullscreen" | "pip")
* - extra - Request metadata (abort signal, session info)
* - Returns: Promise<McpUiRequestDisplayModeResult> with the actual mode set
* - `params.mode` - The display mode being requested ("inline" | "fullscreen" | "pip")
* - `extra` - Request metadata (abort signal, session info)
* - Returns: `Promise<McpUiRequestDisplayModeResult>` with the actual mode set
*
* @example
* ```typescript
* let currentDisplayMode: McpUiDisplayMode = "inline";
*
* bridge.onrequestdisplaymode = async ({ mode }, extra) => {
* const availableModes = hostContext.availableDisplayModes ?? ["inline"];
* if (availableModes.includes(mode)) {
* setDisplayMode(mode);
* currentDisplayMode = mode;
* return { mode };
* }
* // Return current mode if requested mode not available
@ -640,9 +649,9 @@ export class AppBridge extends Protocol<
* message type.
*
* @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
* - `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
*
* @example
* ```typescript
@ -716,9 +725,9 @@ export class AppBridge extends Protocol<
* by forwarding them to the MCP server.
*
* @param callback - Handler that receives tool call params and returns a
* {@link CallToolResult}
* @param callback.params - Tool call parameters (name and arguments)
* @param callback.extra - Request metadata (abort signal, session info)
* `CallToolResult`
* - `params` - Tool call parameters (name and arguments)
* - `extra` - Request metadata (abort signal, session info)
*
* @example
* ```typescript
@ -731,8 +740,8 @@ export class AppBridge extends Protocol<
* };
* ```
*
* @see {@link CallToolRequest} for the request type
* @see {@link CallToolResult} for the result type
* @see `CallToolRequest` from @modelcontextprotocol/sdk for the request type
* @see `CallToolResult` from @modelcontextprotocol/sdk for the result type
*/
set oncalltool(
callback: (
@ -762,7 +771,7 @@ export class AppBridge extends Protocol<
* });
* ```
*
* @see {@link ToolListChangedNotification} for the notification type
* @see `ToolListChangedNotification` from @modelcontextprotocol/sdk for the notification type
*/
sendToolListChanged(params: ToolListChangedNotification["params"] = {}) {
return this.notification({
@ -779,9 +788,9 @@ export class AppBridge extends Protocol<
* requests, typically by forwarding them to the MCP server.
*
* @param callback - Handler that receives list params and returns a
* {@link ListResourcesResult}
* @param callback.params - Request params (may include cursor for pagination)
* @param callback.extra - Request metadata (abort signal, session info)
* `ListResourcesResult`
* - `params` - Request params (may include cursor for pagination)
* - `extra` - Request metadata (abort signal, session info)
*
* @example
* ```typescript
@ -794,8 +803,8 @@ export class AppBridge extends Protocol<
* };
* ```
*
* @see {@link ListResourcesRequest} for the request type
* @see {@link ListResourcesResult} for the result type
* @see `ListResourcesRequest` from @modelcontextprotocol/sdk for the request type
* @see `ListResourcesResult` from @modelcontextprotocol/sdk for the result type
*/
set onlistresources(
callback: (
@ -819,9 +828,9 @@ export class AppBridge extends Protocol<
* these requests, typically by forwarding them to the MCP server.
*
* @param callback - Handler that receives list params and returns a
* {@link ListResourceTemplatesResult}
* @param callback.params - Request params (may include cursor for pagination)
* @param callback.extra - Request metadata (abort signal, session info)
* `ListResourceTemplatesResult`
* - `params` - Request params (may include cursor for pagination)
* - `extra` - Request metadata (abort signal, session info)
*
* @example
* ```typescript
@ -834,8 +843,8 @@ export class AppBridge extends Protocol<
* };
* ```
*
* @see {@link ListResourceTemplatesRequest} for the request type
* @see {@link ListResourceTemplatesResult} for the result type
* @see `ListResourceTemplatesRequest` from @modelcontextprotocol/sdk for the request type
* @see `ListResourceTemplatesResult` from @modelcontextprotocol/sdk for the result type
*/
set onlistresourcetemplates(
callback: (
@ -859,9 +868,9 @@ export class AppBridge extends Protocol<
* requests, typically by forwarding them to the MCP server.
*
* @param callback - Handler that receives read params and returns a
* {@link ReadResourceResult}
* @param callback.params - Read parameters including the resource URI
* @param callback.extra - Request metadata (abort signal, session info)
* `ReadResourceResult`
* - `params` - Read parameters including the resource URI
* - `extra` - Request metadata (abort signal, session info)
*
* @example
* ```typescript
@ -874,8 +883,8 @@ export class AppBridge extends Protocol<
* };
* ```
*
* @see {@link ReadResourceRequest} for the request type
* @see {@link ReadResourceResult} for the result type
* @see `ReadResourceRequest` from @modelcontextprotocol/sdk for the request type
* @see `ReadResourceResult` from @modelcontextprotocol/sdk for the result type
*/
set onreadresource(
callback: (
@ -908,7 +917,7 @@ export class AppBridge extends Protocol<
* });
* ```
*
* @see {@link ResourceListChangedNotification} for the notification type
* @see `ResourceListChangedNotification` from @modelcontextprotocol/sdk for the notification type
*/
sendResourceListChanged(
params: ResourceListChangedNotification["params"] = {},
@ -927,9 +936,9 @@ export class AppBridge extends Protocol<
* requests, typically by forwarding them to the MCP server.
*
* @param callback - Handler that receives list params and returns a
* {@link ListPromptsResult}
* @param callback.params - Request params (may include cursor for pagination)
* @param callback.extra - Request metadata (abort signal, session info)
* `ListPromptsResult`
* - `params` - Request params (may include cursor for pagination)
* - `extra` - Request metadata (abort signal, session info)
*
* @example
* ```typescript
@ -942,8 +951,8 @@ export class AppBridge extends Protocol<
* };
* ```
*
* @see {@link ListPromptsRequest} for the request type
* @see {@link ListPromptsResult} for the result type
* @see `ListPromptsRequest` from @modelcontextprotocol/sdk for the request type
* @see `ListPromptsResult` from @modelcontextprotocol/sdk for the result type
*/
set onlistprompts(
callback: (
@ -973,7 +982,7 @@ export class AppBridge extends Protocol<
* });
* ```
*
* @see {@link PromptListChangedNotification} for the notification type
* @see `PromptListChangedNotification` from @modelcontextprotocol/sdk for the notification type
*/
sendPromptListChanged(params: PromptListChangedNotification["params"] = {}) {
return this.notification({
@ -1062,9 +1071,10 @@ export class AppBridge extends Protocol<
/**
* Update the host context and notify the Guest UI of changes.
*
* Compares the new context with the current context and sends a
* `ui/notifications/host-context-changed` notification containing only the
* fields that have changed. If no fields have changed, no notification is sent.
* Compares fields present in the new context with the current context and sends a
* `ui/notifications/host-context-changed` notification containing only fields
* that have been added or modified. If no fields have changed, no notification is sent.
* The new context fully replaces the internal state.
*
* Common use cases include notifying the Guest UI when:
* - Theme changes (light/dark mode toggle)
@ -1111,8 +1121,13 @@ export class AppBridge extends Protocol<
}
/**
* Send a host context change notification to the app.
* Only sends the fields that have changed (partial update).
* Low-level method to notify the Guest UI of host context changes.
*
* Most hosts should use {@link setHostContext} instead, which automatically
* detects changes and calls this method with only the modified fields.
* Use this directly only when you need fine-grained control over change detection.
*
* @param params - The context fields that have changed (partial update)
*/
sendHostContextChange(
params: McpUiHostContextChangedNotification["params"],
@ -1225,7 +1240,7 @@ export class AppBridge extends Protocol<
* any other interruption. This allows the Guest UI to update its state and
* display appropriate feedback to the user.
*
* @param params - Optional cancellation details:
* @param params - Cancellation details object
* - `reason`: Human-readable explanation for why the tool was cancelled
*
* @example User-initiated cancellation
@ -1330,13 +1345,13 @@ export class AppBridge extends Protocol<
* - Prompts (prompts/list, notifications/prompts/list_changed)
*
* If no client was passed to the constructor, no automatic forwarding is set up
* and you must register handlers manually using the `oncalltool`, `onlistresources`,
* and you must register handlers manually using the {@link oncalltool}, {@link onlistresources},
* etc. setters.
*
* After calling connect, wait for the `oninitialized` callback before sending
* After calling connect, wait for the {@link oninitialized} callback before sending
* tool input and other data to the Guest UI.
*
* @param transport - Transport layer (typically PostMessageTransport)
* @param transport - Transport layer (typically {@link PostMessageTransport})
* @returns Promise resolving when connection is established
*
* @throws {Error} If a client was passed but server capabilities are not available.

View file

@ -64,7 +64,7 @@ export {
*
* MCP servers include this key in tool call result metadata to indicate which
* UI resource should be displayed for the tool. When hosts receive a tool result
* containing this metadata, they resolve and render the corresponding App.
* containing this metadata, they resolve and render the corresponding {@link App}.
*
* **Note**: This constant is provided for reference. MCP servers set this metadata
* in their tool handlers; App developers typically don't need to use it directly.
@ -93,21 +93,25 @@ export const RESOURCE_URI_META_KEY = "ui/resourceUri";
/**
* MIME type for MCP UI resources.
*
* Identifies HTML content as an MCP App UI resource.
*
* Used by {@link server-helpers!registerAppResource} as the default MIME type for app resources.
*/
export const RESOURCE_MIME_TYPE = "text/html;profile=mcp-app";
/**
* Options for configuring App behavior.
* Options for configuring {@link App} behavior.
*
* Extends ProtocolOptions from the MCP SDK with App-specific configuration.
* Extends `ProtocolOptions` from the MCP SDK with `App`-specific configuration.
*
* @see ProtocolOptions from @modelcontextprotocol/sdk for inherited options
* @see `ProtocolOptions` from @modelcontextprotocol/sdk for inherited options
*/
type AppOptions = ProtocolOptions & {
/**
* Automatically report size changes to the host using ResizeObserver.
* Automatically report size changes to the host using `ResizeObserver`.
*
* When enabled, the App monitors `document.body` and `document.documentElement`
* When enabled, the {@link App} monitors `document.body` and `document.documentElement`
* for size changes and automatically sends `ui/notifications/size-changed`
* notifications to the host.
*
@ -123,8 +127,8 @@ type RequestHandlerExtra = Parameters<
/**
* Main class for MCP Apps to communicate with their host.
*
* The App class provides a framework-agnostic way to build interactive MCP Apps
* that run inside host applications. It extends the MCP SDK's Protocol class and
* The `App` class provides a framework-agnostic way to build interactive MCP Apps
* that run inside host applications. It extends the MCP SDK's `Protocol` class and
* handles the connection lifecycle, initialization handshake, and bidirectional
* communication with the host.
*
@ -143,19 +147,20 @@ type RequestHandlerExtra = Parameters<
*
* ## Inherited Methods
*
* As a subclass of Protocol, App inherits key methods for handling communication:
* As a subclass of `Protocol`, `App` inherits key methods for handling communication:
* - `setRequestHandler()` - Register handlers for requests from host
* - `setNotificationHandler()` - Register handlers for notifications from host
*
* @see Protocol from @modelcontextprotocol/sdk for all inherited methods
* @see `Protocol` from @modelcontextprotocol/sdk for all inherited methods
*
* ## Notification Setters
*
* For common notifications, the App class provides convenient setter properties
* For common notifications, the `App` class provides convenient setter properties
* that simplify handler registration:
* - `ontoolinput` - Complete tool arguments from host
* - `ontoolinputpartial` - Streaming partial tool arguments
* - `ontoolresult` - Tool execution results
* - `ontoolcancelled` - Tool execution was cancelled by user or host
* - `onhostcontextchanged` - Host context changes (theme, locale, etc.)
*
* These setters are convenience wrappers around `setNotificationHandler()`.
@ -187,7 +192,7 @@ type RequestHandlerExtra = Parameters<
* }
* );
*
* await app.connect(new PostMessageTransport(window.parent));
* await app.connect(new PostMessageTransport(window.parent, window.parent));
* ```
*
* @example Sending a message to the host's chat
@ -208,7 +213,7 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
*
* @param _appInfo - App identification (name and version)
* @param _capabilities - Features and capabilities this app provides
* @param options - Configuration options including autoResize behavior
* @param options - Configuration options including `autoResize` behavior
*
* @example
* ```typescript
@ -339,7 +344,7 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
*
* Register handlers before calling {@link connect} to avoid missing notifications.
*
* @param callback - Function called with the tool input params
* @param callback - Function called with the tool input params ({@link McpUiToolInputNotification.params})
*
* @example Using the setter (simpler)
* ```typescript
@ -384,7 +389,7 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
*
* Register handlers before calling {@link connect} to avoid missing notifications.
*
* @param callback - Function called with each partial tool input update
* @param callback - Function called with each partial tool input update ({@link McpUiToolInputPartialNotification.params})
*
* @example Progressive rendering of tool arguments
* ```typescript
@ -418,7 +423,7 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
*
* Register handlers before calling {@link connect} to avoid missing notifications.
*
* @param callback - Function called with the tool result
* @param callback - Function called with the tool result ({@link McpUiToolResultNotification.params})
*
* @example Display tool execution results
* ```typescript
@ -457,7 +462,7 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
*
* Register handlers before calling {@link connect} to avoid missing notifications.
*
* @param callback - Function called when tool execution is cancelled
* @param callback - Function called when tool execution is cancelled. Receives optional cancellation reason — see {@link McpUiToolCancelledNotification.params}.
*
* @example Handle tool cancellation
* ```typescript
@ -490,6 +495,10 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
* This setter is a convenience wrapper around `setNotificationHandler()` that
* automatically handles the notification schema and extracts the params for you.
*
* Notification params are automatically merged into the internal host context
* before the callback is invoked. This means {@link getHostContext} will
* return the updated values even before your callback runs.
*
* Register handlers before calling {@link connect} to avoid missing notifications.
*
* @param callback - Function called with the updated host context
@ -538,7 +547,7 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
* Register handlers before calling {@link connect} to avoid missing requests.
*
* @param callback - Function called when teardown is requested.
* Can return void or a Promise that resolves when cleanup is complete.
* Must return `McpUiResourceTeardownResult` (can be an empty object `{}`) or a Promise resolving to it.
*
* @example Perform cleanup before teardown
* ```typescript
@ -546,6 +555,7 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
* await saveState();
* closeConnections();
* console.log("App ready for teardown");
* return {};
* };
* ```
*
@ -620,9 +630,9 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
*
* Register handlers before calling {@link connect} to avoid missing requests.
*
* @param callback - Async function that returns the list of available tools.
* The callback will only be invoked if the app declared tool capabilities
* in the constructor.
* @param callback - Async function that returns tool names as strings (simplified
* from full `ListToolsResult` with `Tool` objects). Registration is always
* allowed; capability validation occurs when handlers are invoked.
*
* @example Return available tools
* ```typescript
@ -1050,7 +1060,7 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
* If initialization fails, the connection is automatically closed and an error
* is thrown.
*
* @param transport - Transport layer (typically PostMessageTransport)
* @param transport - Transport layer (typically {@link PostMessageTransport})
* @param options - Request options for the initialize request
*
* @throws {Error} If initialization fails or connection is lost
@ -1063,7 +1073,7 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
* );
*
* try {
* await app.connect(new PostMessageTransport(window.parent));
* await app.connect(new PostMessageTransport(window.parent, window.parent));
* console.log("Connected successfully!");
* } catch (error) {
* console.error("Failed to connect:", error);

View file

@ -839,7 +839,6 @@
"type": "object",
"properties": {
"fonts": {
"description": "CSS for font loading (@font-face rules or",
"type": "string"
}
},
@ -1593,7 +1592,6 @@
"type": "object",
"properties": {
"fonts": {
"description": "CSS for font loading (@font-face rules or",
"type": "string"
}
},
@ -1767,7 +1765,6 @@
"type": "object",
"properties": {
"fonts": {
"description": "CSS for font loading (@font-face rules or",
"type": "string"
}
},
@ -2186,7 +2183,6 @@
"type": "object",
"properties": {
"fonts": {
"description": "CSS for font loading (@font-face rules or",
"type": "string"
}
},
@ -3133,7 +3129,6 @@
"type": "object",
"properties": {
"fonts": {
"description": "CSS for font loading (@font-face rules or",
"type": "string"
}
},

View file

@ -135,7 +135,7 @@ export const McpUiStylesSchema = z
/**
* @description Request to open an external URL in the host's default browser.
* @see {@link app.App.sendOpenLink} for the method that sends this request
* @see {@link app!App.openLink} for the method that sends this request
*/
export const McpUiOpenLinkRequestSchema = z.object({
method: z.literal("ui/open-link"),
@ -246,8 +246,8 @@ export const McpUiResourcePermissionsSchema = z.object({
});
/**
* @description Notification of UI size changes (bidirectional: Guest <-> Host).
* @see {@link app.App.sendSizeChanged} for the method to send this from Guest UI
* @description Notification of UI size changes (Guest UI -> Host).
* @see {@link app!App.sendSizeChanged} for the method to send this from Guest UI
*/
export const McpUiSizeChangedNotificationSchema = z.object({
method: z.literal("ui/notifications/size-changed"),
@ -319,11 +319,8 @@ export const McpUiToolCancelledNotificationSchema = z.object({
* @description CSS blocks that can be injected by apps.
*/
export const McpUiHostCssSchema = z.object({
/** @description CSS for font loading (@font-face rules or @import statements). Apps must apply using applyHostFonts(). */
fonts: z
.string()
.optional()
.describe("CSS for font loading (@font-face rules or"),
/** @description CSS for font loading (`@font-face` rules or `@import` statements). Apps must apply using {@link applyHostFonts}. */
fonts: z.string().optional(),
});
/**
@ -342,7 +339,7 @@ export const McpUiHostStylesSchema = z.object({
/**
* @description Request for graceful shutdown of the Guest UI (Host -> Guest UI).
* @see {@link app-bridge.AppBridge.teardownResource} for the host method that sends this
* @see {@link app-bridge!AppBridge.teardownResource} for the host method that sends this
*/
export const McpUiResourceTeardownRequestSchema = z.object({
method: z.literal("ui/resource-teardown"),
@ -453,7 +450,7 @@ export const McpUiHostCapabilitiesSchema = z.object({
});
/**
* @description Capabilities provided by the Guest UI (App).
* @description Capabilities provided by the Guest UI ({@link app!App}).
* @see {@link McpUiInitializeRequest} for the initialization request that includes these capabilities
*/
export const McpUiAppCapabilitiesSchema = z.object({
@ -477,7 +474,7 @@ export const McpUiAppCapabilitiesSchema = z.object({
/**
* @description Notification that Guest UI has completed initialization (Guest UI -> Host).
* @see {@link app.App.connect} for the method that sends this notification
* @see {@link app!App.connect} for the method that sends this notification
*/
export const McpUiInitializedNotificationSchema = z.object({
method: z.literal("ui/notifications/initialized"),
@ -514,7 +511,7 @@ export const McpUiResourceMetaSchema = z.object({
* @description Request to change the display mode of the UI.
* The host will respond with the actual display mode that was set,
* which may differ from the requested mode if not supported.
* @see {@link app.App.requestDisplayMode} for the method that sends this request
* @see {@link app!App.requestDisplayMode} for the method that sends this request
*/
export const McpUiRequestDisplayModeRequestSchema = z.object({
method: z.literal("ui/request-display-mode"),
@ -570,7 +567,7 @@ export const McpUiToolMetaSchema = z.object({
/**
* @description Request to send a message to the host's chat interface.
* @see {@link app.App.sendMessage} for the method that sends this request
* @see {@link app!App.sendMessage} for the method that sends this request
*/
export const McpUiMessageRequestSchema = z.object({
method: z.literal("ui/message"),
@ -788,7 +785,7 @@ export const McpUiUpdateModelContextRequestSchema = z.object({
/**
* @description Initialization request sent from Guest UI to Host.
* @see {@link app.App.connect} for the method that sends this request
* @see {@link app!App.connect} for the method that sends this request
*/
export const McpUiInitializeRequestSchema = z.object({
method: z.literal("ui/initialize"),

View file

@ -9,39 +9,38 @@ import {
} from "@modelcontextprotocol/sdk/shared/transport.js";
/**
* JSON-RPC transport using window.postMessage for iframe↔parent communication.
* JSON-RPC transport using `window.postMessage` for iframe↔parent communication.
*
* This transport enables bidirectional communication between MCP Apps running in
* iframes and their host applications using the browser's postMessage API. It
* implements the MCP SDK's Transport interface.
* iframes and their host applications using the browser's `postMessage` API. It
* implements the MCP SDK's `Transport` interface.
*
* ## Security
*
* The `eventSource` parameter provides origin validation by filtering messages
* from specific sources. Guest UIs typically don't need to specify this (they only
* communicate with their parent), but hosts should validate the iframe source for
* security.
* The `eventSource` parameter is required and validates the message source window
* by checking `event.source`. For guest UIs, pass `window.parent`.
* For hosts, pass `iframe.contentWindow` to validate the iframe source.
*
* ## Usage
*
* **Guest UI (default)**:
* **Guest UI**:
* ```typescript
* const transport = new PostMessageTransport(window.parent);
* const transport = new PostMessageTransport(window.parent, window.parent);
* await app.connect(transport);
* ```
*
* **Host (with source validation)**:
* **Host**:
* ```typescript
* const iframe = document.getElementById('app-iframe') as HTMLIFrameElement;
* const transport = new PostMessageTransport(
* iframe.contentWindow!,
* iframe.contentWindow // Validate messages from this iframe only
* iframe.contentWindow!
* );
* await bridge.connect(transport);
* ```
*
* @see {@link app.App.connect} for Guest UI usage
* @see {@link app-bridge.AppBridge.connect} for Host usage
* @see {@link app!App.connect} for Guest UI usage
* @see {@link app-bridge!AppBridge.connect} for Host usage
*/
export class PostMessageTransport implements Transport {
private messageListener: (
@ -52,22 +51,21 @@ export class PostMessageTransport implements Transport {
/**
* Create a new PostMessageTransport.
*
* @param eventTarget - Target window to send messages to (default: window.parent)
* @param eventSource - Optional source validation. If specified, only messages from
* this source will be accepted. Guest UIs typically don't need this (they only
* receive from parent), but hosts should validate the iframe source.
* @param eventTarget - Target window to send messages to (default: `window.parent`)
* @param eventSource - Source window for message validation. For guests, pass
* `window.parent`. For hosts, pass `iframe.contentWindow`.
*
* @example Guest UI connecting to parent
* ```typescript
* const transport = new PostMessageTransport(window.parent);
* const transport = new PostMessageTransport(window.parent, window.parent);
* ```
*
* @example Host connecting to iframe with validation
* @example Host connecting to iframe
* ```typescript
* const iframe = document.getElementById('app') as HTMLIFrameElement;
* const transport = new PostMessageTransport(
* iframe.contentWindow!,
* iframe.contentWindow // Only accept messages from this iframe
* iframe.contentWindow!
* );
* ```
*/
@ -108,7 +106,7 @@ export class PostMessageTransport implements Transport {
/**
* Send a JSON-RPC message to the target window.
*
* Messages are sent using postMessage with "*" origin, meaning they are visible
* Messages are sent using `postMessage` with `"*"` origin, meaning they are visible
* to all frames. The receiver should validate the message source for security.
*
* @param message - JSON-RPC message to send
@ -161,7 +159,7 @@ export class PostMessageTransport implements Transport {
* Optional session identifier for this transport connection.
*
* Set by the MCP SDK to track the connection session. Not required for
* PostMessageTransport functionality.
* `PostMessageTransport` functionality.
*/
sessionId?: string;

View file

@ -5,27 +5,29 @@ import { App, McpUiAppCapabilities, PostMessageTransport } from "../app";
export * from "../app";
/**
* Options for configuring the useApp hook.
* Options for configuring the {@link useApp} hook.
*
* Note: This interface does NOT expose App options like `autoResize`.
* The hook creates the App with default options (autoResize: true). If you need
* custom App options, create the App manually instead of using this hook.
* Note: This interface does NOT expose {@link App} options like `autoResize`.
* The hook creates the `App` with default options (`autoResize: true`). If you
* need custom `App` options, create the `App` manually instead of using this hook.
*
* @see {@link useApp} for the hook that uses these options
* @see {@link useAutoResize} for manual auto-resize control with custom App options
* @see {@link useAutoResize} for manual auto-resize control with custom `App` options
*/
export interface UseAppOptions {
/** App identification (name and version) */
appInfo: Implementation;
/** Features and capabilities this app provides */
/**
* Declares what features this app supports.
*/
capabilities: McpUiAppCapabilities;
/**
* Called after App is created but before connection.
* Called after {@link App} is created but before connection.
*
* Use this to register request/notification handlers that need to be in place
* before the initialization handshake completes.
*
* @param app - The newly created App instance
* @param app - The newly created `App` instance
*
* @example Register a notification handler
* ```typescript
@ -45,10 +47,10 @@ export interface UseAppOptions {
}
/**
* State returned by the useApp hook.
* State returned by the {@link useApp} hook.
*/
export interface AppState {
/** The connected App instance, null during initialization */
/** The connected {@link App} instance, null during initialization */
app: App | null;
/** Whether initialization completed successfully */
isConnected: boolean;
@ -59,16 +61,19 @@ export interface AppState {
/**
* React hook to create and connect an MCP App.
*
* This hook manages the complete lifecycle of an {@link App}: creation, connection,
* and cleanup. It automatically creates a {@link PostMessageTransport} to window.parent
* and handles initialization.
* This hook manages {@link App} creation and connection. It automatically
* creates a {@link PostMessageTransport} to window.parent and handles
* initialization.
*
* This hook is part of the optional React integration. The core SDK (`App`,
* `PostMessageTransport`) is framework-agnostic and can be used with any UI
* framework or vanilla JavaScript.
*
* **Important**: The hook intentionally does NOT re-run when options change
* to avoid reconnection loops. Options are only used during the initial mount.
*
* **Note**: This is part of the optional React integration. The core SDK
* (App, PostMessageTransport) is framework-agnostic and can be
* used with any UI framework or vanilla JavaScript.
* Furthermore, the `App` instance is NOT closed on unmount. This avoids cleanup
* issues during React Strict Mode's double-mount cycle. If you need to
* explicitly close the `App`, call {@link App.close} manually.
*
* @param options - Configuration for the app
* @returns Current connection state and app instance. If connection fails during

View file

@ -4,15 +4,17 @@ import { App } from "../app";
/**
* React hook that automatically reports UI size changes to the host.
*
* Uses ResizeObserver to watch `document.body` and `document.documentElement` for
* Uses `ResizeObserver` to watch `document.body` and `document.documentElement` for
* size changes and sends `ui/notifications/size-changed` notifications.
*
* The hook automatically cleans up the `ResizeObserver` when the component unmounts.
*
* **Note**: This hook is rarely needed since the {@link useApp} hook automatically enables
* auto-resize by default. This hook is provided for advanced cases where you
* create the {@link App} manually with `autoResize: false` and want to add auto-resize
* behavior later.
*
* @param app - The connected App instance, or null during initialization
* @param app - The connected {@link App} instance, or null during initialization
* @param elementRef - Currently unused. The hook always observes `document.body`
* and `document.documentElement` regardless of this value. Passing a ref will
* cause unnecessary effect re-runs; omit this parameter.
@ -31,7 +33,7 @@ import { App } from "../app";
* { autoResize: false } // Disable default auto-resize
* );
*
* const transport = new PostMessageTransport(window.parent);
* const transport = new PostMessageTransport(window.parent, window.parent);
* myApp.connect(transport)
* .then(() => setApp(myApp))
* .catch((err) => setError(err));

View file

@ -5,11 +5,13 @@ import { McpUiTheme } from "../types";
/**
* React hook that provides the current document theme reactively.
*
* Uses a MutationObserver to watch for changes to the `data-theme` attribute
* Uses a `MutationObserver` to watch for changes to the `data-theme` attribute
* or `class` on `document.documentElement`. When the theme changes (e.g., from
* host context updates), the hook automatically re-renders your component with
* the new theme value.
*
* The `MutationObserver` is automatically disconnected when the component unmounts.
*
* @returns The current theme ("light" or "dark")
*
* @example Conditionally render based on theme

View file

@ -21,14 +21,13 @@ import { McpUiHostContext } from "../types";
* this hook ensures they work correctly by setting the `color-scheme` property
* based on the host's theme preference.
*
* @param app - The connected App instance, or null during initialization
* @param app - The connected {@link App} instance, or null during initialization
* @param initialContext - Initial host context from the connection (optional).
* If provided, styles and theme will be applied immediately on mount.
*
* @example Basic usage with useApp
* @example
* ```tsx
* import { useApp } from '@modelcontextprotocol/ext-apps/react';
* import { useHostStyleVariables } from '@modelcontextprotocol/ext-apps/react';
* import { useApp, useHostStyleVariables } from '@modelcontextprotocol/ext-apps/react';
*
* function MyApp() {
* const { app, isConnected } = useApp({
@ -36,8 +35,8 @@ import { McpUiHostContext } from "../types";
* capabilities: {},
* });
*
* // Automatically apply host style variables and theme
* useHostStyleVariables(app);
* // Apply host styles - pass initial context to apply styles from connect() immediately
* useHostStyleVariables(app, app?.getHostContext());
*
* return (
* <div style={{ background: 'var(--color-background-primary)' }}>
@ -47,15 +46,6 @@ import { McpUiHostContext } from "../types";
* }
* ```
*
* @example With initial context
* ```tsx
* const [hostContext, setHostContext] = useState<McpUiHostContext | null>(null);
*
* // ... get initial context from app.connect() result
*
* useHostStyleVariables(app, hostContext);
* ```
*
* @see {@link applyHostStyleVariables} for the underlying styles function
* @see {@link applyDocumentTheme} for the underlying theme function
* @see {@link useHostFonts} for applying host fonts
@ -112,7 +102,7 @@ export function useHostStyleVariables(
* The hook also applies fonts from the initial host context when
* the app first connects.
*
* @param app - The connected App instance, or null during initialization
* @param app - The connected {@link App} instance, or null during initialization
* @param initialContext - Initial host context from the connection (optional).
* If provided, fonts will be applied immediately on mount.
*
@ -182,13 +172,24 @@ export function useHostFonts(
}
/**
* React hook that applies host styles, fonts, and theme.
* Applies all host styling (CSS variables, theme, and fonts) to match the host application.
*
* This is a convenience hook that combines {@link useHostStyleVariables} and
* {@link useHostFonts}. Use the individual hooks if you need more control.
*
* @param app - The connected App instance, or null during initialization
* @param app - The connected {@link App} instance, or null during initialization
* @param initialContext - Initial host context from the connection (optional).
* Pass `app?.getHostContext()` to apply styles immediately on mount.
*
* @example
* ```tsx
* function MyApp() {
* const { app } = useApp({ appInfo, capabilities: {} });
* useHostStyles(app, app?.getHostContext());
*
* return <div style={{ background: 'var(--color-background-primary)' }}>...</div>;
* }
* ```
*
* @see {@link useHostStyleVariables} for style variables and theme only
* @see {@link useHostFonts} for fonts only

View file

@ -1,7 +1,25 @@
/**
* Server Helpers for MCP Apps.
* Utilities for MCP servers to register tools and resources that display interactive UIs.
*
* Use these helpers instead of the base SDK's `registerTool` and `registerResource` when
* your tool should render an {@link app!App} in the client. They handle UI metadata normalization
* and provide sensible defaults for the MCP Apps MIME type ({@link RESOURCE_MIME_TYPE}).
*
* @module server-helpers
*
* @example
* ```typescript
* import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE } from '@modelcontextprotocol/ext-apps/server';
*
* // Register a tool that displays a widget
* registerAppTool(server, "weather", {
* description: "Get weather forecast",
* _meta: { ui: { resourceUri: "ui://weather/widget.html" } },
* }, handler);
*
* // Register the HTML resource the tool references
* registerAppResource(server, "Weather Widget", "ui://weather/widget.html", {}, readCallback);
* ```
*/
import {
@ -29,7 +47,8 @@ export { RESOURCE_URI_META_KEY, RESOURCE_MIME_TYPE };
export type { ResourceMetadata, ToolCallback, ReadResourceCallback };
/**
* Tool configuration (same as McpServer.registerTool).
* Base tool configuration matching the standard MCP server tool options.
* Extended by {@link McpUiAppToolConfig} to add UI metadata requirements.
*/
export interface ToolConfig {
title?: string;
@ -41,7 +60,14 @@ export interface ToolConfig {
}
/**
* MCP App Tool configuration for `registerAppTool`.
* Configuration for tools that render an interactive UI.
*
* Extends {@link ToolConfig} with a required `_meta` field that specifies UI metadata.
* The UI resource can be specified in two ways:
* - `_meta.ui.resourceUri` (preferred)
* - `_meta["ui/resourceUri"]` (deprecated, for backward compatibility)
*
* @see {@link registerAppTool} for the recommended way to register app tools
*/
export interface McpUiAppToolConfig extends ToolConfig {
_meta: {
@ -65,11 +91,24 @@ export interface McpUiAppToolConfig extends ToolConfig {
}
/**
* MCP App Resource configuration for `registerAppResource`.
* MCP App Resource configuration for {@link registerAppResource}.
*
* Extends the base MCP SDK `ResourceMetadata` with optional UI metadata
* for configuring security policies and rendering preferences.
*
* @see {@link registerAppResource} for usage
*/
export interface McpUiAppResourceConfig extends ResourceMetadata {
/**
* Optional UI metadata for the resource.
* Used to configure security policies (CSP) and rendering preferences.
*/
_meta?: {
/**
* UI-specific metadata including CSP configuration and rendering preferences.
*/
ui?: McpUiResourceMeta;
// Allow additional metadata properties for extensibility.
[key: string]: unknown;
};
}
@ -77,14 +116,16 @@ export interface McpUiAppResourceConfig extends ResourceMetadata {
/**
* Register an app tool with the MCP server.
*
* This is a convenience wrapper around `server.registerTool` that will allow more backwards-compatibility.
* This is a convenience wrapper around `server.registerTool` that normalizes
* UI metadata: if `_meta.ui.resourceUri` is set, the legacy `_meta["ui/resourceUri"]`
* key is also populated (and vice versa) for compatibility with older hosts.
*
* @param server - The MCP server instance
* @param name - Tool name/identifier
* @param config - Tool configuration with required `ui` field
* @param handler - Tool handler function
* @param config - Tool configuration with `_meta` field containing UI metadata
* @param cb - Tool handler function
*
* @example
* @example Basic usage
* ```typescript
* import { registerAppTool } from '@modelcontextprotocol/ext-apps/server';
* import { z } from 'zod';
@ -94,13 +135,50 @@ export interface McpUiAppResourceConfig extends ResourceMetadata {
* description: "Get current weather for a location",
* inputSchema: { location: z.string() },
* _meta: {
* [RESOURCE_URI_META_KEY]: "ui://weather/widget.html",
* ui: { resourceUri: "ui://weather/widget.html" },
* },
* }, async (args) => {
* const weather = await fetchWeather(args.location);
* return { content: [{ type: "text", text: JSON.stringify(weather) }] };
* });
* ```
*
* @example Tool visibility - create app-only tools for UI actions
* ```typescript
* import { registerAppTool } from '@modelcontextprotocol/ext-apps/server';
* import { z } from 'zod';
*
* // Main tool - visible to both model and app (default)
* registerAppTool(server, "show-cart", {
* description: "Display the user's shopping cart",
* _meta: {
* ui: {
* resourceUri: "ui://shop/cart.html",
* visibility: ["model", "app"],
* },
* },
* }, async () => {
* const cart = await getCart();
* return { content: [{ type: "text", text: JSON.stringify(cart) }] };
* });
*
* // App-only tool - hidden from the model, only callable by the UI
* registerAppTool(server, "update-quantity", {
* description: "Update item quantity in cart",
* inputSchema: { itemId: z.string(), quantity: z.number() },
* _meta: {
* ui: {
* resourceUri: "ui://shop/cart.html",
* visibility: ["app"],
* },
* },
* }, async ({ itemId, quantity }) => {
* const cart = await updateCartItem(itemId, quantity);
* return { content: [{ type: "text", text: JSON.stringify(cart) }] };
* });
* ```
*
* @see {@link registerAppResource} to register the HTML resource referenced by the tool
*/
export function registerAppTool<
OutputArgs extends ZodRawShapeCompat | AnySchema,
@ -137,22 +215,21 @@ export function registerAppTool<
* Register an app resource with the MCP server.
*
* This is a convenience wrapper around `server.registerResource` that:
* - Defaults the MIME type to "text/html;profile=mcp-app"
* - Defaults the MIME type to {@link RESOURCE_MIME_TYPE} (`"text/html;profile=mcp-app"`)
* - Provides a cleaner API matching the SDK's callback signature
*
* @param server - The MCP server instance
* @param name - Human-readable resource name
* @param uri - Resource URI (should match the `ui` field in tool config)
* @param uri - Resource URI (should match the `_meta.ui` field in tool config)
* @param config - Resource configuration
* @param readCallback - Callback that returns the resource contents
*
* @example
* @example Basic usage
* ```typescript
* import { registerAppResource } from '@modelcontextprotocol/ext-apps/server';
*
* registerAppResource(server, "Weather Widget", "ui://weather/widget.html", {
* description: "Interactive weather display",
* mimeType: RESOURCE_MIME_TYPE,
* }, async () => ({
* contents: [{
* uri: "ui://weather/widget.html",
@ -161,6 +238,23 @@ export function registerAppTool<
* }],
* }));
* ```
*
* @example With CSP configuration for external domains
* ```typescript
* registerAppResource(server, "Music Player", "ui://music/player.html", {
* description: "Audio player with external soundfonts",
* _meta: {
* ui: {
* csp: {
* connectDomains: ["https://api.example.com"], // For fetch/WebSocket
* resourceDomains: ["https://cdn.example.com"], // For scripts/styles/images
* },
* },
* },
* }, readCallback);
* ```
*
* @see {@link registerAppTool} to register tools that reference this resource
*/
export function registerAppResource(
server: Pick<McpServer, "registerResource">,

View file

@ -2,7 +2,7 @@
* MCP Apps Protocol Types (spec.types.ts)
*
* This file contains pure TypeScript interface definitions for the MCP Apps protocol.
* These types are the source of truth and are used to generate Zod schemas via ts-to-zod.
* These types are the source of truth and are used to generate Zod schemas via `ts-to-zod`.
*
* - Use `@description` JSDoc tags to generate `.describe()` calls on schemas
* - Run `npm run generate:schemas` to regenerate schemas from these types
@ -144,7 +144,7 @@ export type McpUiStyles = Record<McpUiStyleVariableKey, string | undefined>;
/**
* @description Request to open an external URL in the host's default browser.
* @see {@link app.App.sendOpenLink} for the method that sends this request
* @see {@link app!App.openLink} for the method that sends this request
*/
export interface McpUiOpenLinkRequest {
method: "ui/open-link";
@ -163,14 +163,14 @@ export interface McpUiOpenLinkResult {
isError?: boolean;
/**
* Index signature required for MCP SDK `Protocol` class compatibility.
* Note: The schema intentionally omits this to enforce strict validation.
* Note: The generated schema uses passthrough() to allow additional properties.
*/
[key: string]: unknown;
}
/**
* @description Request to send a message to the host's chat interface.
* @see {@link app.App.sendMessage} for the method that sends this request
* @see {@link app!App.sendMessage} for the method that sends this request
*/
export interface McpUiMessageRequest {
method: "ui/message";
@ -191,7 +191,7 @@ export interface McpUiMessageResult {
isError?: boolean;
/**
* Index signature required for MCP SDK `Protocol` class compatibility.
* Note: The schema intentionally omits this to enforce strict validation.
* Note: The generated schema uses passthrough() to allow additional properties.
*/
[key: string]: unknown;
}
@ -226,8 +226,8 @@ export interface McpUiSandboxResourceReadyNotification {
}
/**
* @description Notification of UI size changes (bidirectional: Guest <-> Host).
* @see {@link app.App.sendSizeChanged} for the method to send this from Guest UI
* @description Notification of UI size changes (Guest UI -> Host).
* @see {@link app!App.sendSizeChanged} for the method to send this from Guest UI
*/
export interface McpUiSizeChangedNotification {
method: "ui/notifications/size-changed";
@ -287,7 +287,7 @@ export interface McpUiToolCancelledNotification {
* @description CSS blocks that can be injected by apps.
*/
export interface McpUiHostCss {
/** @description CSS for font loading (@font-face rules or @import statements). Apps must apply using applyHostFonts(). */
/** @description CSS for font loading (`@font-face` rules or `@import` statements). Apps must apply using {@link applyHostFonts}. */
fonts?: string;
}
@ -408,7 +408,7 @@ export interface McpUiUpdateModelContextRequest {
/**
* @description Request for graceful shutdown of the Guest UI (Host -> Guest UI).
* @see {@link app-bridge.AppBridge.teardownResource} for the host method that sends this
* @see {@link app-bridge!AppBridge.teardownResource} for the host method that sends this
*/
export interface McpUiResourceTeardownRequest {
method: "ui/resource-teardown";
@ -476,7 +476,7 @@ export interface McpUiHostCapabilities {
}
/**
* @description Capabilities provided by the Guest UI (App).
* @description Capabilities provided by the Guest UI ({@link app!App}).
* @see {@link McpUiInitializeRequest} for the initialization request that includes these capabilities
*/
export interface McpUiAppCapabilities {
@ -491,7 +491,7 @@ export interface McpUiAppCapabilities {
/**
* @description Initialization request sent from Guest UI to Host.
* @see {@link app.App.connect} for the method that sends this request
* @see {@link app!App.connect} for the method that sends this request
*/
export interface McpUiInitializeRequest {
method: "ui/initialize";
@ -520,14 +520,14 @@ export interface McpUiInitializeResult {
hostContext: McpUiHostContext;
/**
* Index signature required for MCP SDK `Protocol` class compatibility.
* Note: The schema intentionally omits this to enforce strict validation.
* Note: The generated schema uses passthrough() to allow additional properties.
*/
[key: string]: unknown;
}
/**
* @description Notification that Guest UI has completed initialization (Guest UI -> Host).
* @see {@link app.App.connect} for the method that sends this notification
* @see {@link app!App.connect} for the method that sends this notification
*/
export interface McpUiInitializedNotification {
method: "ui/notifications/initialized";
@ -582,7 +582,7 @@ export interface McpUiResourceMeta {
* @description Request to change the display mode of the UI.
* The host will respond with the actual display mode that was set,
* which may differ from the requested mode if not supported.
* @see {@link app.App.requestDisplayMode} for the method that sends this request
* @see {@link app!App.requestDisplayMode} for the method that sends this request
*/
export interface McpUiRequestDisplayModeRequest {
method: "ui/request-display-mode";
@ -601,7 +601,7 @@ export interface McpUiRequestDisplayModeResult {
mode: McpUiDisplayMode;
/**
* Index signature required for MCP SDK `Protocol` class compatibility.
* Note: The schema intentionally omits this to enforce strict validation.
* Note: The generated schema uses passthrough() to allow additional properties.
*/
[key: string]: unknown;
}

View file

@ -76,12 +76,12 @@ export function applyDocumentTheme(theme: McpUiTheme): void {
/**
* Apply host style variables as CSS custom properties on an element.
*
* This function takes the `variables` object from `McpUiHostContext.styles` and sets
* This function takes the `variables` object from {@link McpUiHostContext.styles} and sets
* each CSS variable on the specified root element (defaults to `document.documentElement`).
* This allows apps to use the host's theming values via CSS variables like
* `var(--color-background-primary)`.
*
* @param styles - The styles object from `McpUiHostContext.styles.variables`
* @param styles - The style variables object from `McpUiHostContext.styles.variables`
* @param root - The element to apply styles to (defaults to `document.documentElement`)
*
* @example Apply style variables from host context
@ -123,10 +123,10 @@ export function applyHostStyleVariables(
* self-hosted fonts, `@import` statements for Google Fonts or other font services,
* or a combination of both.
*
* The styles are only injected once. Subsequent calls will not create duplicate
* style tags.
* The styles are only injected once. Subsequent calls are no-ops and will not
* create duplicate style tags.
*
* @param fontCss - CSS string containing @font-face rules and/or @import statements
* @param fontCss - CSS string containing `@font-face` rules and/or `@import` statements
*
* @example Apply fonts from host context
* ```typescript

View file

@ -1,12 +1,12 @@
/**
* MCP Apps Protocol Types and Schemas
*
* This file re-exports types from spec.types.ts and schemas from generated/schema.ts.
* Compile-time verification is handled by generated/schema.test.ts.
* This file re-exports types from `spec.types.ts` and schemas from `generated/schema.ts`.
* Compile-time verification is handled by `generated/schema.test.ts`.
*
* @see spec.types.ts for the source of truth TypeScript interfaces
* @see generated/schema.ts for auto-generated Zod schemas
* @see generated/schema.test.ts for compile-time verification
* @see `spec.types.ts` for the source of truth TypeScript interfaces
* @see `generated/schema.ts` for auto-generated Zod schemas
* @see `generated/schema.test.ts` for compile-time verification
*/
// Re-export all types from spec.types.ts
@ -151,7 +151,8 @@ import {
*
* Includes:
* - MCP UI requests (initialize, open-link, message, resource-teardown, request-display-mode)
* - MCP server requests forwarded from the app (tools/call, resources/*, prompts/list)
* - MCP server requests forwarded from the app (tools/call, tools/list, resources/list,
* resources/templates/list, resources/read, prompts/list)
* - Protocol requests (ping)
*/
export type AppRequest =

30
typedoc.config.mjs Normal file
View file

@ -0,0 +1,30 @@
import { OptionDefaults } from "typedoc";
/** @type {Partial<import('typedoc').TypeDocOptions>} */
const config = {
blockTags: [...OptionDefaults.blockTags, "@description"],
intentionallyNotExported: ["AppOptions"],
projectDocuments: ["docs/quickstart.md"],
entryPoints: [
"src/server/index.ts",
"src/app.ts",
"src/react/index.tsx",
"src/app-bridge.ts",
"src/message-transport.ts",
"src/types.ts",
],
out: "docs/api",
gitRevision: "main",
excludePrivate: true,
excludeInternal: false,
categorizeByGroup: true,
navigationLinks: {
GitHub: "https://github.com/modelcontextprotocol/ext-apps",
Specification:
"https://github.com/modelcontextprotocol/ext-apps/blob/main/specification/draft/apps.mdx",
},
readme: "README.md",
includeVersion: true,
};
export default config;

View file

@ -1,22 +0,0 @@
{
"$schema": "https://typedoc.org/schema.json",
"projectDocuments": ["docs/quickstart.md"],
"entryPoints": [
"src/app.ts",
"src/app-bridge.ts",
"src/types.ts",
"src/message-transport.ts",
"src/react/index.tsx"
],
"out": "docs/api",
"gitRevision": "main",
"excludePrivate": true,
"excludeInternal": false,
"categorizeByGroup": true,
"navigationLinks": {
"GitHub": "https://github.com/modelcontextprotocol/ext-apps",
"Specification": "https://github.com/modelcontextprotocol/ext-apps/blob/main/specification/draft/apps.mdx"
},
"readme": "README.md",
"includeVersion": true
}