docs: standardize UI terminology to use "view" consistently (#325)

* docs: standardize UI terminology to use "view" consistently

Replaces "widget" and "Guest UI" terminology with "view" across
the codebase as decided in the community survey.

This change updates:
- Specification document
- SDK source code and JSDoc comments
- Example servers and documentation
- Plugin documentation and skills

Closes #71

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Liad Yosef 2026-01-23 04:36:52 +02:00 • committed by GitHub
commit 4fc71656a3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 381 additions and 393 deletions

View file

@ -31,7 +31,7 @@ async function AppBridge_basicUsage(serverTransport: Transport) {
});
await client.connect(serverTransport);
// Create bridge for the Guest UI
// Create bridge for the View
const bridge = new AppBridge(
client,
{ name: "MyHost", version: "1.0.0" },
@ -46,7 +46,7 @@ async function AppBridge_basicUsage(serverTransport: Transport) {
);
bridge.oninitialized = () => {
console.log("Guest UI initialized");
console.log("View initialized");
// Now safe to send tool input
bridge.sendToolInput({ arguments: { location: "NYC" } });
};
@ -86,35 +86,35 @@ function AppBridge_constructor_withoutMcpClient() {
}
/**
* Example: Check Guest UI capabilities after initialization.
* Example: Check View capabilities after initialization.
*/
function AppBridge_getAppCapabilities_checkAfterInit(bridge: AppBridge) {
//#region AppBridge_getAppCapabilities_checkAfterInit
bridge.oninitialized = () => {
const caps = bridge.getAppCapabilities();
if (caps?.tools) {
console.log("Guest UI provides tools");
console.log("View provides tools");
}
};
//#endregion AppBridge_getAppCapabilities_checkAfterInit
}
/**
* Example: Log Guest UI information after initialization.
* Example: Log View information after initialization.
*/
function AppBridge_getAppVersion_logAfterInit(bridge: AppBridge) {
//#region AppBridge_getAppVersion_logAfterInit
bridge.oninitialized = () => {
const appInfo = bridge.getAppVersion();
if (appInfo) {
console.log(`Guest UI: ${appInfo.name} v${appInfo.version}`);
console.log(`View: ${appInfo.name} v${appInfo.version}`);
}
};
//#endregion AppBridge_getAppVersion_logAfterInit
}
/**
* Example: Handle Guest UI initialization and send tool input.
* Example: Handle View initialization and send tool input.
*/
function AppBridge_oninitialized_sendToolInput(
bridge: AppBridge,
@ -122,14 +122,14 @@ function AppBridge_oninitialized_sendToolInput(
) {
//#region AppBridge_oninitialized_sendToolInput
bridge.oninitialized = () => {
console.log("Guest UI ready");
console.log("View ready");
bridge.sendToolInput({ arguments: toolArgs });
};
//#endregion AppBridge_oninitialized_sendToolInput
}
/**
* Example: Handle message requests from the Guest UI.
* Example: Handle message requests from the View.
*/
function AppBridge_onmessage_logMessage(bridge: AppBridge) {
//#region AppBridge_onmessage_logMessage
@ -169,7 +169,7 @@ declare const modelContextManager: {
};
/**
* Example: Handle external link requests from the Guest UI.
* Example: Handle external link requests from the View.
*/
function AppBridge_onopenlink_handleRequest(bridge: AppBridge) {
//#region AppBridge_onopenlink_handleRequest
@ -195,7 +195,7 @@ function AppBridge_onopenlink_handleRequest(bridge: AppBridge) {
}
/**
* Example: Store model context updates from the Guest UI.
* Example: Store model context updates from the View.
*/
function AppBridge_onupdatemodelcontext_storeContext(bridge: AppBridge) {
//#region AppBridge_onupdatemodelcontext_storeContext
@ -283,18 +283,18 @@ function AppBridge_onlistprompts_returnPrompts(
}
/**
* Example: Handle ping requests from the Guest UI.
* Example: Handle ping requests from the View.
*/
function AppBridge_onping_handleRequest(bridge: AppBridge) {
//#region AppBridge_onping_handleRequest
bridge.onping = (params, extra) => {
console.log("Received ping from Guest UI");
console.log("Received ping from view");
};
//#endregion AppBridge_onping_handleRequest
}
/**
* Example: Handle size change notifications from the Guest UI.
* Example: Handle size change notifications from the View.
*/
function AppBridge_onsizechange_handleResize(
bridge: AppBridge,
@ -313,7 +313,7 @@ function AppBridge_onsizechange_handleResize(
}
/**
* Example: Handle display mode requests from the Guest UI.
* Example: Handle display mode requests from the View.
*/
function AppBridge_onrequestdisplaymode_handleRequest(
bridge: AppBridge,
@ -331,13 +331,13 @@ function AppBridge_onrequestdisplaymode_handleRequest(
}
/**
* Example: Handle logging messages from the Guest UI.
* Example: Handle logging messages from the View.
*/
function AppBridge_onloggingmessage_handleLog(bridge: AppBridge) {
//#region AppBridge_onloggingmessage_handleLog
bridge.onloggingmessage = ({ level, logger, data }) => {
console[level === "error" ? "error" : "log"](
`[${logger ?? "Guest UI"}] ${level.toUpperCase()}:`,
`[${logger ?? "View"}] ${level.toUpperCase()}:`,
data,
);
};
@ -345,7 +345,7 @@ function AppBridge_onloggingmessage_handleLog(bridge: AppBridge) {
}
/**
* Example: Gracefully tear down the Guest UI before unmounting.
* Example: Gracefully tear down the View before unmounting.
*/
async function AppBridge_teardownResource_gracefulShutdown(
bridge: AppBridge,
@ -354,7 +354,7 @@ async function AppBridge_teardownResource_gracefulShutdown(
//#region AppBridge_teardownResource_gracefulShutdown
try {
await bridge.teardownResource({});
// Guest UI is ready, safe to unmount iframe
// View is ready, safe to unmount iframe
iframe.remove();
} catch (error) {
console.error("Teardown failed:", error);
@ -471,7 +471,7 @@ async function AppBridge_connect_withMcpClient(
);
bridge.oninitialized = () => {
console.log("Guest UI ready");
console.log("View ready");
bridge.sendToolInput({ arguments: toolArgs });
};

View file

@ -159,7 +159,7 @@ export function buildAllowAttribute(
/**
* Options for configuring {@link AppBridge `AppBridge`} behavior.
*
* @property hostContext - Optional initial host context to provide to the Guest UI
* @property hostContext - Optional initial host context to provide to the view
*
* @see `ProtocolOptions` from @modelcontextprotocol/sdk for available options
* @see {@link McpUiHostContext `McpUiHostContext`} for the hostContext structure
@ -190,27 +190,27 @@ type RequestHandlerExtra = Parameters<
>[1];
/**
* Host-side bridge for communicating with a single Guest UI ({@link app!App `App`}).
* Host-side bridge for communicating with a single View ({@link app!App `App`}).
*
* `AppBridge` extends the MCP SDK's `Protocol` class and acts as a proxy between
* the host application and a Guest UI running in an iframe. When an MCP client
* the host application and a view running in an iframe. When an MCP client
* is provided to the constructor, it automatically forwards MCP server capabilities
* (tools, resources, prompts) to the Guest UI. It also handles the initialization
* (tools, resources, prompts) to the view. It also handles the initialization
* handshake.
*
* ## Architecture
*
* **Guest UI ↔ AppBridge ↔ Host ↔ MCP Server**
* **View ↔ AppBridge ↔ Host ↔ MCP Server**
*
* The bridge proxies requests from the Guest UI to the MCP server and forwards
* The bridge proxies requests from the view to the MCP server and forwards
* responses back. It also sends host-initiated notifications like tool input
* and results to the Guest UI.
* and results to the view.
*
* ## Lifecycle
*
* 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
* 3. **Wait for init**: View sends initialize request, bridge responds
* 4. **Send data**: Call {@link sendToolInput `sendToolInput`}, {@link sendToolResult `sendToolResult`}, etc.
* 5. **Teardown**: Call {@link teardownResource `teardownResource`} before unmounting iframe
*
@ -231,7 +231,7 @@ export class AppBridge extends Protocol<
*
* @param _client - MCP client connected to the server, or `null`. When provided,
* {@link connect `connect`} will automatically set up forwarding of MCP requests/notifications
* between the Guest UI and the server. When `null`, you must register handlers
* between the View and the server. When `null`, you must register handlers
* manually using the {@link oncalltool `oncalltool`}, {@link onlistresources `onlistresources`}, etc. setters.
* @param _hostInfo - Host application identification (name and version)
* @param _capabilities - Features and capabilities the host supports
@ -271,15 +271,15 @@ export class AppBridge extends Protocol<
}
/**
* Get the Guest UI's capabilities discovered during initialization.
* Get the view's capabilities discovered during initialization.
*
* Returns the capabilities that the Guest UI advertised during its
* Returns the capabilities that the view advertised during its
* initialization request. Returns `undefined` if called before
* initialization completes.
*
* @returns Guest UI capabilities, or `undefined` if not yet initialized
* @returns view capabilities, or `undefined` if not yet initialized
*
* @example Check Guest UI capabilities after initialization
* @example Check view capabilities after initialization
* {@includeCode ./app-bridge.examples.ts#AppBridge_getAppCapabilities_checkAfterInit}
*
* @see {@link McpUiAppCapabilities `McpUiAppCapabilities`} for the capabilities structure
@ -289,14 +289,14 @@ export class AppBridge extends Protocol<
}
/**
* Get the Guest UI's implementation info discovered during initialization.
* Get the view's implementation info discovered during initialization.
*
* Returns the Guest UI's name and version as provided in its initialization
* Returns the view's name and version as provided in its initialization
* request. Returns `undefined` if called before initialization completes.
*
* @returns Guest UI implementation info, or `undefined` if not yet initialized
* @returns view implementation info, or `undefined` if not yet initialized
*
* @example Log Guest UI information after initialization
* @example Log view information after initialization
* {@includeCode ./app-bridge.examples.ts#AppBridge_getAppVersion_logAfterInit}
*/
getAppVersion(): Implementation | undefined {
@ -304,9 +304,9 @@ export class AppBridge extends Protocol<
}
/**
* Optional handler for ping requests from the Guest UI.
* Optional handler for ping requests from the view.
*
* The Guest UI can send standard MCP `ping` requests to verify the connection
* The View can send standard MCP `ping` requests to verify the connection
* is alive. The {@link AppBridge `AppBridge`} automatically responds with an empty object, but this
* handler allows the host to observe or log ping activity.
*
@ -322,20 +322,20 @@ export class AppBridge extends Protocol<
onping?: (params: PingRequest["params"], extra: RequestHandlerExtra) => void;
/**
* Register a handler for size change notifications from the Guest UI.
* Register a handler for size change notifications from the view.
*
* The Guest UI sends `ui/notifications/size-changed` when its rendered content
* The view sends `ui/notifications/size-changed` when its rendered content
* size changes, typically via `ResizeObserver`. Set this callback to dynamically
* adjust the iframe container dimensions based on the Guest UI's content.
* adjust the iframe container dimensions based on the view's content.
*
* Note: This is for Guest UI → Host communication. To notify the Guest UI of
* Note: This is for View → Host communication. To notify the View of
* host container dimension changes, use {@link setHostContext `setHostContext`}.
*
* @example
* {@includeCode ./app-bridge.examples.ts#AppBridge_onsizechange_handleResize}
*
* @see {@link McpUiSizeChangedNotification `McpUiSizeChangedNotification`} for the notification type
* @see {@link app!App.sendSizeChanged `App.sendSizeChanged`} - the Guest UI method that sends these notifications
* @see {@link app!App.sendSizeChanged `App.sendSizeChanged`} - the View method that sends these notifications
*/
set onsizechange(
callback: (params: McpUiSizeChangedNotification["params"]) => void,
@ -384,16 +384,16 @@ export class AppBridge extends Protocol<
}
/**
* Called when the Guest UI completes initialization.
* Called when the view completes initialization.
*
* Set this callback to be notified when the Guest UI has finished its
* Set this callback to be notified when the view has finished its
* initialization handshake and is ready to receive tool input and other data.
*
* @example
* {@includeCode ./app-bridge.examples.ts#AppBridge_oninitialized_sendToolInput}
*
* @see {@link McpUiInitializedNotification `McpUiInitializedNotification`} for the notification type
* @see {@link sendToolInput `sendToolInput`} for sending tool arguments to the Guest UI
* @see {@link sendToolInput `sendToolInput`} for sending tool arguments to the View
*/
set oninitialized(
callback: (params: McpUiInitializedNotification["params"]) => void,
@ -404,9 +404,9 @@ export class AppBridge extends Protocol<
}
/**
* Register a handler for message requests from the Guest UI.
* Register a handler for message requests from the view.
*
* The Guest UI sends `ui/message` requests when it wants to add a message to
* The view sends `ui/message` requests when it wants to add a message to
* the host's chat interface. This enables interactive apps to communicate with
* the user through the conversation thread.
*
@ -442,9 +442,9 @@ export class AppBridge extends Protocol<
}
/**
* Register a handler for external link requests from the Guest UI.
* Register a handler for external link requests from the view.
*
* The Guest UI sends `ui/open-link` requests when it wants to open an external
* The view sends `ui/open-link` requests when it wants to open an external
* URL in the host's default browser. The handler should validate the URL and
* open it according to the host's security policy and user preferences.
*
@ -480,9 +480,9 @@ export class AppBridge extends Protocol<
}
/**
* Register a handler for display mode change requests from the Guest UI.
* Register a handler for display mode change requests from the view.
*
* The Guest UI sends `ui/request-display-mode` requests when it wants to change
* The view sends `ui/request-display-mode` requests when it wants to change
* its display mode (e.g., from "inline" to "fullscreen"). The handler should
* check if the requested mode is in `availableDisplayModes` from the host context,
* update the display mode if supported, and return the actual mode that was set.
@ -519,9 +519,9 @@ export class AppBridge extends Protocol<
}
/**
* Register a handler for logging messages from the Guest UI.
* Register a handler for logging messages from the view.
*
* The Guest UI sends standard MCP `notifications/message` (logging) notifications
* The view sends standard MCP `notifications/message` (logging) notifications
* to report debugging information, errors, warnings, and other telemetry to the
* host. The host can display these in a console, log them to a file, or send
* them to a monitoring service.
@ -549,10 +549,10 @@ export class AppBridge extends Protocol<
}
/**
* Register a handler for model context updates from the Guest UI.
* Register a handler for model context updates from the view.
*
* The Guest UI sends `ui/update-model-context` requests to update the Host's
* model context. Each request overwrites the previous context stored by the Guest UI.
* The view sends `ui/update-model-context` requests to update the Host's
* model context. Each request overwrites the previous context stored by the view.
* Unlike logging messages, context updates are intended to be available to
* the model in future turns. Unlike messages, context updates do not trigger follow-ups.
*
@ -580,9 +580,9 @@ export class AppBridge extends Protocol<
}
/**
* Register a handler for tool call requests from the Guest UI.
* Register a handler for tool call requests from the view.
*
* The Guest UI sends `tools/call` requests to execute MCP server tools. This
* The view sends `tools/call` requests to execute MCP server tools. This
* handler allows the host to intercept and process these requests, typically
* by forwarding them to the MCP server.
*
@ -609,10 +609,10 @@ export class AppBridge extends Protocol<
}
/**
* Notify the Guest UI that the MCP server's tool list has changed.
* Notify the view that the MCP server's tool list has changed.
*
* The host sends `notifications/tools/list_changed` to the Guest UI when it
* receives this notification from the MCP server. This allows the Guest UI
* The host sends `notifications/tools/list_changed` to the view when it
* receives this notification from the MCP server. This allows the view
* to refresh its tool cache or UI accordingly.
*
* @param params - Optional notification params (typically empty)
@ -635,9 +635,9 @@ export class AppBridge extends Protocol<
}
/**
* Register a handler for list resources requests from the Guest UI.
* Register a handler for list resources requests from the view.
*
* The Guest UI sends `resources/list` requests to enumerate available MCP
* The view sends `resources/list` requests to enumerate available MCP
* resources. This handler allows the host to intercept and process these
* requests, typically by forwarding them to the MCP server.
*
@ -667,9 +667,9 @@ export class AppBridge extends Protocol<
}
/**
* Register a handler for list resource templates requests from the Guest UI.
* Register a handler for list resource templates requests from the view.
*
* The Guest UI sends `resources/templates/list` requests to enumerate available
* The view sends `resources/templates/list` requests to enumerate available
* MCP resource templates. This handler allows the host to intercept and process
* these requests, typically by forwarding them to the MCP server.
*
@ -707,9 +707,9 @@ export class AppBridge extends Protocol<
}
/**
* Register a handler for read resource requests from the Guest UI.
* Register a handler for read resource requests from the view.
*
* The Guest UI sends `resources/read` requests to retrieve the contents of an
* The view sends `resources/read` requests to retrieve the contents of an
* MCP resource. This handler allows the host to intercept and process these
* requests, typically by forwarding them to the MCP server.
*
@ -739,10 +739,10 @@ export class AppBridge extends Protocol<
}
/**
* Notify the Guest UI that the MCP server's resource list has changed.
* Notify the view that the MCP server's resource list has changed.
*
* The host sends `notifications/resources/list_changed` to the Guest UI when it
* receives this notification from the MCP server. This allows the Guest UI
* The host sends `notifications/resources/list_changed` to the view when it
* receives this notification from the MCP server. This allows the view
* to refresh its resource cache or UI accordingly.
*
* @param params - Optional notification params (typically empty)
@ -767,9 +767,9 @@ export class AppBridge extends Protocol<
}
/**
* Register a handler for list prompts requests from the Guest UI.
* Register a handler for list prompts requests from the view.
*
* The Guest UI sends `prompts/list` requests to enumerate available MCP
* The view sends `prompts/list` requests to enumerate available MCP
* prompts. This handler allows the host to intercept and process these
* requests, typically by forwarding them to the MCP server.
*
@ -796,10 +796,10 @@ export class AppBridge extends Protocol<
}
/**
* Notify the Guest UI that the MCP server's prompt list has changed.
* Notify the view that the MCP server's prompt list has changed.
*
* The host sends `notifications/prompts/list_changed` to the Guest UI when it
* receives this notification from the MCP server. This allows the Guest UI
* The host sends `notifications/prompts/list_changed` to the view when it
* receives this notification from the MCP server. This allows the view
* to refresh its prompt cache or UI accordingly.
*
* @param params - Optional notification params (typically empty)
@ -899,14 +899,14 @@ export class AppBridge extends Protocol<
}
/**
* Update the host context and notify the Guest UI of changes.
* Update the host context and notify the view of changes.
*
* 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:
* Common use cases include notifying the view when:
* - Theme changes (light/dark mode toggle)
* - Viewport size changes (window resize)
* - Display mode changes (inline/fullscreen)
@ -944,7 +944,7 @@ export class AppBridge extends Protocol<
}
/**
* Low-level method to notify the Guest UI of host context changes.
* Low-level method to notify the view of host context changes.
*
* Most hosts should use {@link setHostContext `setHostContext`} instead, which automatically
* detects changes and calls this method with only the modified fields.
@ -962,9 +962,9 @@ export class AppBridge extends Protocol<
}
/**
* Send complete tool arguments to the Guest UI.
* Send complete tool arguments to the view.
*
* The host MUST send this notification after the Guest UI completes initialization
* The host MUST send this notification after the View completes initialization
* (after {@link oninitialized `oninitialized`} callback fires) and complete tool arguments become available.
* This notification is sent exactly once and is required before {@link sendToolResult `sendToolResult`}.
*
@ -985,14 +985,14 @@ export class AppBridge extends Protocol<
}
/**
* Send streaming partial tool arguments to the Guest UI.
* Send streaming partial tool arguments to the view.
*
* The host MAY send this notification zero or more times while tool arguments
* are being streamed, before {@link sendToolInput `sendToolInput`} is called with complete
* arguments. This enables progressive rendering of tool arguments in the
* Guest UI.
* view.
*
* The arguments represent best-effort recovery of incomplete JSON. Guest UIs
* The arguments represent best-effort recovery of incomplete JSON. views
* SHOULD handle missing or changing fields gracefully between notifications.
*
* @param params - Partial tool call arguments (may be incomplete)
@ -1011,10 +1011,10 @@ export class AppBridge extends Protocol<
}
/**
* Send tool execution result to the Guest UI.
* Send tool execution result to the view.
*
* The host MUST send this notification when tool execution completes successfully,
* provided the UI is still displayed. If the UI was closed before execution
* provided the view is still displayed. If the view was closed before execution
* completes, the host MAY skip this notification. This must be sent after
* {@link sendToolInput `sendToolInput`}.
*
@ -1034,11 +1034,11 @@ export class AppBridge extends Protocol<
}
/**
* Notify the Guest UI that tool execution was cancelled.
* Notify the view that tool execution was cancelled.
*
* The host MUST send this notification if tool execution was cancelled for any
* reason, including user action, sampling error, classifier intervention, or
* any other interruption. This allows the Guest UI to update its state and
* any other interruption. This allows the view to update its state and
* display appropriate feedback to the user.
*
* @param params - Cancellation details object
@ -1086,17 +1086,17 @@ export class AppBridge extends Protocol<
}
/**
* Request graceful shutdown of the Guest UI.
* Request graceful shutdown of the view.
*
* The host MUST send this request before tearing down the UI resource (before
* unmounting the iframe). This gives the Guest UI an opportunity to save state,
* unmounting the iframe). This gives the view an opportunity to save state,
* cancel pending operations, or show confirmation dialogs.
*
* The host SHOULD wait for the response before unmounting to prevent data loss.
*
* @param params - Empty params object
* @param options - Request options (timeout, etc.)
* @returns Promise resolving when Guest UI confirms readiness for teardown
* @returns Promise resolving when view confirms readiness for teardown
*
* @example
* {@includeCode ./app-bridge.examples.ts#AppBridge_teardownResource_gracefulShutdown}
@ -1119,11 +1119,11 @@ export class AppBridge extends Protocol<
sendResourceTeardown: AppBridge["teardownResource"] = this.teardownResource;
/**
* Connect to the Guest UI via transport and optionally set up message forwarding.
* Connect to the view via transport and optionally set up message forwarding.
*
* This method establishes the transport connection. If an MCP client was passed
* to the constructor, it also automatically sets up request/notification forwarding
* based on the MCP server's capabilities, proxying the following to the Guest UI:
* based on the MCP server's capabilities, proxying the following to the view:
* - Tools (tools/call, notifications/tools/list_changed)
* - Resources (resources/list, resources/read, resources/templates/list, notifications/resources/list_changed)
* - Prompts (prompts/list, notifications/prompts/list_changed)
@ -1133,7 +1133,7 @@ export class AppBridge extends Protocol<
* etc. setters.
*
* After calling connect, wait for the {@link oninitialized `oninitialized`} callback before sending
* tool input and other data to the Guest UI.
* tool input and other data to the View.
*
* @param transport - Transport layer (typically {@link PostMessageTransport `PostMessageTransport`})
* @returns Promise resolving when connection is established
@ -1152,7 +1152,7 @@ export class AppBridge extends Protocol<
async connect(transport: Transport) {
if (this._client) {
// When a client was passed to the constructor, automatically forward
// MCP requests/notifications between the Guest UI and the server
// MCP requests/notifications between the view and the server
const serverCapabilities = this._client.getServerCapabilities();
if (!serverCapabilities) {
throw new Error("Client server capabilities not available");

View file

@ -122,7 +122,7 @@ type RequestHandlerExtra = Parameters<
*
* ## Architecture
*
* Guest UIs (Apps) act as MCP clients connecting to the host via {@link PostMessageTransport `PostMessageTransport`}.
* Views (Apps) act as MCP clients connecting to the host via {@link PostMessageTransport `PostMessageTransport`}.
* The host proxies requests to the actual MCP server and forwards
* responses back to the App.
*

View file

@ -207,7 +207,7 @@
"additionalProperties": false
},
"message": {
"description": "Host supports receiving content messages (ui/message) from the Guest UI.",
"description": "Host supports receiving content messages (ui/message) from the view.",
"type": "object",
"properties": {
"text": {
@ -2504,7 +2504,7 @@
"additionalProperties": false
},
"message": {
"description": "Host supports receiving content messages (ui/message) from the Guest UI.",
"description": "Host supports receiving content messages (ui/message) from the view.",
"type": "object",
"properties": {
"text": {
@ -3877,7 +3877,7 @@
"additionalProperties": false
},
"domain": {
"description": "Dedicated origin for widget sandbox.",
"description": "Dedicated origin for view sandbox.",
"type": "string"
},
"prefersBorder": {

View file

@ -246,8 +246,8 @@ export const McpUiResourcePermissionsSchema = z.object({
});
/**
* @description Notification of UI size changes (Guest UI -> Host).
* @see {@link app!App.sendSizeChanged `App.sendSizeChanged`} for the method to send this from Guest UI
* @description Notification of UI size changes (View -> Host).
* @see {@link app!App.sendSizeChanged `App.sendSizeChanged`} for the method to send this from View
*/
export const McpUiSizeChangedNotificationSchema = z.object({
method: z.literal("ui/notifications/size-changed"),
@ -260,7 +260,7 @@ export const McpUiSizeChangedNotificationSchema = z.object({
});
/**
* @description Notification containing complete tool arguments (Host -> Guest UI).
* @description Notification containing complete tool arguments (Host -> View).
*/
export const McpUiToolInputNotificationSchema = z.object({
method: z.literal("ui/notifications/tool-input"),
@ -279,7 +279,7 @@ export const McpUiToolInputNotificationSchema = z.object({
});
/**
* @description Notification containing partial/streaming tool arguments (Host -> Guest UI).
* @description Notification containing partial/streaming tool arguments (Host -> View).
*/
export const McpUiToolInputPartialNotificationSchema = z.object({
method: z.literal("ui/notifications/tool-input-partial"),
@ -298,7 +298,7 @@ export const McpUiToolInputPartialNotificationSchema = z.object({
});
/**
* @description Notification that tool execution was cancelled (Host -> Guest UI).
* @description Notification that tool execution was cancelled (Host -> View).
* Host MUST send this if tool execution was cancelled for any reason (user action,
* sampling error, classifier intervention, etc.).
*/
@ -338,7 +338,7 @@ export const McpUiHostStylesSchema = z.object({
});
/**
* @description Request for graceful shutdown of the Guest UI (Host -> Guest UI).
* @description Request for graceful shutdown of the View (Host -> View).
* @see {@link app-bridge!AppBridge.teardownResource `AppBridge.teardownResource`} for the host method that sends this
*/
export const McpUiResourceTeardownRequestSchema = z.object({
@ -443,14 +443,14 @@ export const McpUiHostCapabilitiesSchema = z.object({
McpUiSupportedContentBlockModalitiesSchema.optional().describe(
"Host accepts context updates (ui/update-model-context) to be included in the model's context for future turns.",
),
/** @description Host supports receiving content messages (ui/message) from the Guest UI. */
/** @description Host supports receiving content messages (ui/message) from the view. */
message: McpUiSupportedContentBlockModalitiesSchema.optional().describe(
"Host supports receiving content messages (ui/message) from the Guest UI.",
"Host supports receiving content messages (ui/message) from the view.",
),
});
/**
* @description Capabilities provided by the Guest UI ({@link app!App `App`}).
* @description Capabilities provided by the View ({@link app!App `App`}).
* @see {@link McpUiInitializeRequest `McpUiInitializeRequest`} for the initialization request that includes these capabilities
*/
export const McpUiAppCapabilitiesSchema = z.object({
@ -473,7 +473,7 @@ export const McpUiAppCapabilitiesSchema = z.object({
});
/**
* @description Notification that Guest UI has completed initialization (Guest UI -> Host).
* @description Notification that View has completed initialization (View -> Host).
* @see {@link app!App.connect `App.connect`} for the method that sends this notification
*/
export const McpUiInitializedNotificationSchema = z.object({
@ -493,11 +493,8 @@ export const McpUiResourceMetaSchema = z.object({
permissions: McpUiResourcePermissionsSchema.optional().describe(
"Sandbox permissions requested by the UI.",
),
/** @description Dedicated origin for widget sandbox. */
domain: z
.string()
.optional()
.describe("Dedicated origin for widget sandbox."),
/** @description Dedicated origin for view sandbox. */
domain: z.string().optional().describe("Dedicated origin for view sandbox."),
/** @description Visual boundary preference - true if UI prefers a visible border. */
prefersBorder: z
.boolean()
@ -549,7 +546,7 @@ export const McpUiToolMetaSchema = z.object({
* URI of the UI resource to display for this tool, if any.
* This is converted to `_meta["ui/resourceUri"]`.
*
* @example "ui://weather/widget.html"
* @example "ui://weather/view.html"
*/
resourceUri: z.string().optional(),
/**
@ -610,7 +607,7 @@ export const McpUiSandboxResourceReadyNotificationSchema = z.object({
});
/**
* @description Notification containing tool execution result (Host -> Guest UI).
* @description Notification containing tool execution result (Host -> View).
*/
export const McpUiToolResultNotificationSchema = z.object({
method: z.literal("ui/notifications/tool-result"),
@ -619,7 +616,7 @@ export const McpUiToolResultNotificationSchema = z.object({
});
/**
* @description Rich context about the host environment provided to Guest UIs.
* @description Rich context about the host environment provided to views.
*/
export const McpUiHostContextSchema = z
.object({
@ -739,7 +736,7 @@ export const McpUiHostContextSchema = z
.passthrough();
/**
* @description Notification that host context has changed (Host -> Guest UI).
* @description Notification that host context has changed (Host -> View).
* @see {@link McpUiHostContext `McpUiHostContext`} for the full context structure
*/
export const McpUiHostContextChangedNotificationSchema = z.object({
@ -751,10 +748,10 @@ export const McpUiHostContextChangedNotificationSchema = z.object({
});
/**
* @description Request to update the agent's context without requiring a follow-up action (Guest UI -> Host).
* @description Request to update the agent's context without requiring a follow-up action (View -> Host).
*
* Unlike `notifications/message` which is for debugging/logging, this request is intended
* to update the Host's model context. Each request overwrites the previous context sent by the Guest UI.
* to update the Host's model context. Each request overwrites the previous context sent by the View.
* Unlike messages, context updates do not trigger follow-ups.
*
* The host will typically defer sending the context to the model until the next user message
@ -784,7 +781,7 @@ export const McpUiUpdateModelContextRequestSchema = z.object({
});
/**
* @description Initialization request sent from Guest UI to Host.
* @description Initialization request sent from View to Host.
* @see {@link app!App.connect `App.connect`} for the method that sends this request
*/
export const McpUiInitializeRequestSchema = z.object({
@ -804,7 +801,7 @@ export const McpUiInitializeRequestSchema = z.object({
});
/**
* @description Initialization result returned from Host to Guest UI.
* @description Initialization result returned from Host to View.
* @see {@link McpUiInitializeRequest `McpUiInitializeRequest`}
*/
export const McpUiInitializeResultSchema = z

View file

@ -12,13 +12,13 @@ import type { App } from "./app.js";
import type { AppBridge } from "./app-bridge.js";
/**
* Example: Guest UI connecting to parent window.
* Example: View connecting to parent window.
*/
async function PostMessageTransport_guestUI(app: App) {
//#region PostMessageTransport_guestUI
async function PostMessageTransport_view(app: App) {
//#region PostMessageTransport_view
const transport = new PostMessageTransport(window.parent, window.parent);
await app.connect(transport);
//#endregion PostMessageTransport_guestUI
//#endregion PostMessageTransport_view
}
/**
@ -36,12 +36,12 @@ async function PostMessageTransport_host(bridge: AppBridge) {
}
/**
* Example: Creating transport for guest UI (constructor only).
* Example: Creating transport for view (constructor only).
*/
function PostMessageTransport_constructor_guestUI() {
//#region PostMessageTransport_constructor_guestUI
function PostMessageTransport_constructor_view() {
//#region PostMessageTransport_constructor_view
const transport = new PostMessageTransport(window.parent, window.parent);
//#endregion PostMessageTransport_constructor_guestUI
//#endregion PostMessageTransport_constructor_view
}
/**

View file

@ -18,18 +18,18 @@ import {
* ## Security
*
* The `eventSource` parameter is required and validates the message source window
* by checking `event.source`. For guest UIs, pass `window.parent`.
* by checking `event.source`. For views, pass `window.parent`.
* For hosts, pass `iframe.contentWindow` to validate the iframe source.
*
* ## Usage
*
* **Guest UI**:
* {@includeCode ./message-transport.examples.ts#PostMessageTransport_guestUI}
* **View**:
* {@includeCode ./message-transport.examples.ts#PostMessageTransport_view}
*
* **Host**:
* {@includeCode ./message-transport.examples.ts#PostMessageTransport_host}
*
* @see {@link app!App.connect `App.connect`} for Guest UI usage
* @see {@link app!App.connect `App.connect`} for View usage
* @see {@link app-bridge!AppBridge.connect `AppBridge.connect`} for Host usage
*/
export class PostMessageTransport implements Transport {
@ -42,11 +42,11 @@ export class PostMessageTransport implements Transport {
* Create a new PostMessageTransport.
*
* @param eventTarget - Target window to send messages to (default: `window.parent`)
* @param eventSource - Source window for message validation. For guests, pass
* @param eventSource - Source window for message validation. For views, pass
* `window.parent`. For hosts, pass `iframe.contentWindow`.
*
* @example Guest UI connecting to parent
* {@includeCode ./message-transport.examples.ts#PostMessageTransport_constructor_guestUI}
* @example View connecting to parent
* {@includeCode ./message-transport.examples.ts#PostMessageTransport_constructor_view}
*
* @example Host connecting to iframe
* {@includeCode ./message-transport.examples.ts#PostMessageTransport_constructor_host}

View file

@ -39,13 +39,13 @@ function index_overview(
readCallback: ReadResourceCallback,
) {
//#region index_overview
// Register a tool that displays a widget
// Register a tool that displays a view
registerAppTool(
server,
"weather",
{
description: "Get weather forecast",
_meta: { ui: { resourceUri: "ui://weather/widget.html" } },
_meta: { ui: { resourceUri: "ui://weather/view.html" } },
},
toolCallback,
);
@ -53,8 +53,8 @@ function index_overview(
// Register the HTML resource the tool references
registerAppResource(
server,
"Weather Widget",
"ui://weather/widget.html",
"Weather View",
"ui://weather/view.html",
{},
readCallback,
);
@ -74,7 +74,7 @@ function registerAppTool_basicUsage(server: McpServer) {
description: "Get current weather for a location",
inputSchema: { location: z.string() },
_meta: {
ui: { resourceUri: "ui://weather/widget.html" },
ui: { resourceUri: "ui://weather/view.html" },
},
},
async (args) => {
@ -143,17 +143,17 @@ function registerAppResource_basicUsage(server: McpServer) {
//#region registerAppResource_basicUsage
registerAppResource(
server,
"Weather Widget",
"ui://weather/widget.html",
"Weather View",
"ui://weather/view.html",
{
description: "Interactive weather display",
},
async () => ({
contents: [
{
uri: "ui://weather/widget.html",
uri: "ui://weather/view.html",
mimeType: RESOURCE_MIME_TYPE,
text: await fs.readFile("dist/widget.html", "utf-8"),
text: await fs.readFile("dist/view.html", "utf-8"),
},
],
}),

View file

@ -35,7 +35,7 @@ describe("registerAppTool", () => {
title: "My Tool",
description: "A test tool",
_meta: {
[RESOURCE_URI_META_KEY]: "ui://test/widget.html",
[RESOURCE_URI_META_KEY]: "ui://test/view.html",
},
},
handler,
@ -49,7 +49,7 @@ describe("registerAppTool", () => {
(capturedConfig?._meta as Record<string, unknown>)?.[
RESOURCE_URI_META_KEY
],
).toBe("ui://test/widget.html");
).toBe("ui://test/view.html");
expect(capturedHandler).toBe(handler);
});
@ -74,7 +74,7 @@ describe("registerAppTool", () => {
"my-tool",
{
_meta: {
ui: { resourceUri: "ui://test/widget.html" },
ui: { resourceUri: "ui://test/view.html" },
},
},
async () => ({ content: [{ type: "text" as const, text: "ok" }] }),
@ -83,10 +83,10 @@ describe("registerAppTool", () => {
const meta = capturedConfig?._meta as Record<string, unknown>;
// New format should be preserved
expect((meta.ui as { resourceUri: string }).resourceUri).toBe(
"ui://test/widget.html",
"ui://test/view.html",
);
// Legacy key should also be set
expect(meta[RESOURCE_URI_META_KEY]).toBe("ui://test/widget.html");
expect(meta[RESOURCE_URI_META_KEY]).toBe("ui://test/view.html");
});
it("should set _meta.ui.resourceUri when legacy key is provided", () => {
@ -109,7 +109,7 @@ describe("registerAppTool", () => {
"my-tool",
{
_meta: {
[RESOURCE_URI_META_KEY]: "ui://test/widget.html",
[RESOURCE_URI_META_KEY]: "ui://test/view.html",
},
},
async () => ({ content: [{ type: "text" as const, text: "ok" }] }),
@ -117,10 +117,10 @@ describe("registerAppTool", () => {
const meta = capturedConfig?._meta as Record<string, unknown>;
// Legacy key should be preserved
expect(meta[RESOURCE_URI_META_KEY]).toBe("ui://test/widget.html");
expect(meta[RESOURCE_URI_META_KEY]).toBe("ui://test/view.html");
// New format should also be set
expect((meta.ui as { resourceUri: string }).resourceUri).toBe(
"ui://test/widget.html",
"ui://test/view.html",
);
});
@ -145,7 +145,7 @@ describe("registerAppTool", () => {
{
_meta: {
ui: { visibility: ["app"] },
[RESOURCE_URI_META_KEY]: "ui://test/widget.html",
[RESOURCE_URI_META_KEY]: "ui://test/view.html",
},
} as any,
async () => ({ content: [{ type: "text" as const, text: "ok" }] }),
@ -154,7 +154,7 @@ describe("registerAppTool", () => {
const meta = capturedConfig?._meta as Record<string, unknown>;
const ui = meta.ui as { resourceUri: string; visibility: string[] };
// Should have merged resourceUri into existing ui object
expect(ui.resourceUri).toBe("ui://test/widget.html");
expect(ui.resourceUri).toBe("ui://test/view.html");
expect(ui.visibility).toEqual(["app"]);
});
@ -178,8 +178,8 @@ describe("registerAppTool", () => {
"my-tool",
{
_meta: {
ui: { resourceUri: "ui://new/widget.html" },
[RESOURCE_URI_META_KEY]: "ui://old/widget.html",
ui: { resourceUri: "ui://new/view.html" },
[RESOURCE_URI_META_KEY]: "ui://old/view.html",
},
} as any,
async () => ({ content: [{ type: "text" as const, text: "ok" }] }),
@ -188,9 +188,9 @@ describe("registerAppTool", () => {
const meta = capturedConfig?._meta as Record<string, unknown>;
// Both should remain unchanged
expect((meta.ui as { resourceUri: string }).resourceUri).toBe(
"ui://new/widget.html",
"ui://new/view.html",
);
expect(meta[RESOURCE_URI_META_KEY]).toBe("ui://old/widget.html");
expect(meta[RESOURCE_URI_META_KEY]).toBe("ui://old/view.html");
});
});
});
@ -215,7 +215,7 @@ describe("registerAppResource", () => {
const callback = async () => ({
contents: [
{
uri: "ui://test/widget.html",
uri: "ui://test/view.html",
mimeType: RESOURCE_MIME_TYPE,
text: "<html/>",
},
@ -225,7 +225,7 @@ describe("registerAppResource", () => {
registerAppResource(
mockServer as unknown as Pick<McpServer, "registerResource">,
"My Resource",
"ui://test/widget.html",
"ui://test/view.html",
{
description: "A test resource",
_meta: { ui: {} },
@ -235,7 +235,7 @@ describe("registerAppResource", () => {
expect(mockServer.registerResource).toHaveBeenCalledTimes(1);
expect(capturedName).toBe("My Resource");
expect(capturedUri).toBe("ui://test/widget.html");
expect(capturedUri).toBe("ui://test/view.html");
expect(capturedConfig?.mimeType).toBe(RESOURCE_MIME_TYPE);
expect(capturedConfig?.description).toBe("A test resource");
});
@ -255,7 +255,7 @@ describe("registerAppResource", () => {
registerAppResource(
mockServer as unknown as Pick<McpServer, "registerResource">,
"My Resource",
"ui://test/widget.html",
"ui://test/view.html",
{
mimeType: "text/html",
_meta: { ui: {} },
@ -263,7 +263,7 @@ describe("registerAppResource", () => {
async () => ({
contents: [
{
uri: "ui://test/widget.html",
uri: "ui://test/view.html",
mimeType: "text/html",
text: "<html/>",
},
@ -295,7 +295,7 @@ describe("registerAppResource", () => {
const expectedResult = {
contents: [
{
uri: "ui://test/widget.html",
uri: "ui://test/view.html",
mimeType: RESOURCE_MIME_TYPE,
text: "<html>content</html>",
},
@ -306,7 +306,7 @@ describe("registerAppResource", () => {
registerAppResource(
mockServer as unknown as Pick<McpServer, "registerResource">,
"My Resource",
"ui://test/widget.html",
"ui://test/view.html",
{ _meta: { ui: {} } },
callback,
);

View file

@ -70,7 +70,7 @@ export interface McpUiAppToolConfig extends ToolConfig {
* URI of the UI resource to display for this tool.
* This is converted to `_meta["ui/resourceUri"]`.
*
* @example "ui://weather/widget.html"
* @example "ui://weather/view.html"
*
* @deprecated Use `_meta.ui.resourceUri` instead.
*/

View file

@ -226,8 +226,8 @@ export interface McpUiSandboxResourceReadyNotification {
}
/**
* @description Notification of UI size changes (Guest UI -> Host).
* @see {@link app!App.sendSizeChanged `App.sendSizeChanged`} for the method to send this from Guest UI
* @description Notification of UI size changes (View -> Host).
* @see {@link app!App.sendSizeChanged `App.sendSizeChanged`} for the method to send this from View
*/
export interface McpUiSizeChangedNotification {
method: "ui/notifications/size-changed";
@ -240,7 +240,7 @@ export interface McpUiSizeChangedNotification {
}
/**
* @description Notification containing complete tool arguments (Host -> Guest UI).
* @description Notification containing complete tool arguments (Host -> View).
*/
export interface McpUiToolInputNotification {
method: "ui/notifications/tool-input";
@ -251,7 +251,7 @@ export interface McpUiToolInputNotification {
}
/**
* @description Notification containing partial/streaming tool arguments (Host -> Guest UI).
* @description Notification containing partial/streaming tool arguments (Host -> View).
*/
export interface McpUiToolInputPartialNotification {
method: "ui/notifications/tool-input-partial";
@ -262,7 +262,7 @@ export interface McpUiToolInputPartialNotification {
}
/**
* @description Notification containing tool execution result (Host -> Guest UI).
* @description Notification containing tool execution result (Host -> View).
*/
export interface McpUiToolResultNotification {
method: "ui/notifications/tool-result";
@ -271,7 +271,7 @@ export interface McpUiToolResultNotification {
}
/**
* @description Notification that tool execution was cancelled (Host -> Guest UI).
* @description Notification that tool execution was cancelled (Host -> View).
* Host MUST send this if tool execution was cancelled for any reason (user action,
* sampling error, classifier intervention, etc.).
*/
@ -302,7 +302,7 @@ export interface McpUiHostStyles {
}
/**
* @description Rich context about the host environment provided to Guest UIs.
* @description Rich context about the host environment provided to views.
*/
export interface McpUiHostContext {
/** @description Allow additional properties for forward compatibility. */
@ -375,7 +375,7 @@ export interface McpUiHostContext {
}
/**
* @description Notification that host context has changed (Host -> Guest UI).
* @description Notification that host context has changed (Host -> View).
* @see {@link McpUiHostContext `McpUiHostContext`} for the full context structure
*/
export interface McpUiHostContextChangedNotification {
@ -385,10 +385,10 @@ export interface McpUiHostContextChangedNotification {
}
/**
* @description Request to update the agent's context without requiring a follow-up action (Guest UI -> Host).
* @description Request to update the agent's context without requiring a follow-up action (View -> Host).
*
* Unlike `notifications/message` which is for debugging/logging, this request is intended
* to update the Host's model context. Each request overwrites the previous context sent by the Guest UI.
* to update the Host's model context. Each request overwrites the previous context sent by the View.
* Unlike messages, context updates do not trigger follow-ups.
*
* The host will typically defer sending the context to the model until the next user message
@ -407,7 +407,7 @@ export interface McpUiUpdateModelContextRequest {
}
/**
* @description Request for graceful shutdown of the Guest UI (Host -> Guest UI).
* @description Request for graceful shutdown of the View (Host -> View).
* @see {@link app-bridge!AppBridge.teardownResource `AppBridge.teardownResource`} for the host method that sends this
*/
export interface McpUiResourceTeardownRequest {
@ -471,12 +471,12 @@ export interface McpUiHostCapabilities {
};
/** @description Host accepts context updates (ui/update-model-context) to be included in the model's context for future turns. */
updateModelContext?: McpUiSupportedContentBlockModalities;
/** @description Host supports receiving content messages (ui/message) from the Guest UI. */
/** @description Host supports receiving content messages (ui/message) from the view. */
message?: McpUiSupportedContentBlockModalities;
}
/**
* @description Capabilities provided by the Guest UI ({@link app!App `App`}).
* @description Capabilities provided by the View ({@link app!App `App`}).
* @see {@link McpUiInitializeRequest `McpUiInitializeRequest`} for the initialization request that includes these capabilities
*/
export interface McpUiAppCapabilities {
@ -490,7 +490,7 @@ export interface McpUiAppCapabilities {
}
/**
* @description Initialization request sent from Guest UI to Host.
* @description Initialization request sent from View to Host.
* @see {@link app!App.connect `App.connect`} for the method that sends this request
*/
export interface McpUiInitializeRequest {
@ -506,7 +506,7 @@ export interface McpUiInitializeRequest {
}
/**
* @description Initialization result returned from Host to Guest UI.
* @description Initialization result returned from Host to View.
* @see {@link McpUiInitializeRequest `McpUiInitializeRequest`}
*/
export interface McpUiInitializeResult {
@ -526,7 +526,7 @@ export interface McpUiInitializeResult {
}
/**
* @description Notification that Guest UI has completed initialization (Guest UI -> Host).
* @description Notification that View has completed initialization (View -> Host).
* @see {@link app!App.connect `App.connect`} for the method that sends this notification
*/
export interface McpUiInitializedNotification {
@ -572,7 +572,7 @@ export interface McpUiResourceMeta {
csp?: McpUiResourceCsp;
/** @description Sandbox permissions requested by the UI. */
permissions?: McpUiResourcePermissions;
/** @description Dedicated origin for widget sandbox. */
/** @description Dedicated origin for view sandbox. */
domain?: string;
/** @description Visual boundary preference - true if UI prefers a visible border. */
prefersBorder?: boolean;
@ -619,7 +619,7 @@ export interface McpUiToolMeta {
* URI of the UI resource to display for this tool, if any.
* This is converted to `_meta["ui/resourceUri"]`.
*
* @example "ui://weather/widget.html"
* @example "ui://weather/view.html"
*/
resourceUri?: string;
/**