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:
parent
9e42ee05a3
commit
4fc71656a3
11 changed files with 381 additions and 393 deletions
|
|
@ -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 });
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
6
src/generated/schema.json
generated
6
src/generated/schema.json
generated
|
|
@ -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": {
|
||||
|
|
|
|||
43
src/generated/schema.ts
generated
43
src/generated/schema.ts
generated
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
},
|
||||
],
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue