Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions specification/draft/apps.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -632,12 +632,12 @@ Host MUST send this notification if the tool execution was cancelled, for any re
Host MUST send this notification before tearing down the UI resource, for any reason, including user action, resource re-allocation, etc. The Host MAY specify the reason.
Host SHOULD wait for a response before tearing down the resource (to prevent data loss).

`ui/notifications/size-change` - UI’s size changed
`ui/notifications/size-changed` - UI’s size changed

```typescript
{
jsonrpc: "2.0",
method: "ui/notifications/size-change",
method: "ui/notifications/size-changed",
params: {
width: number, // Viewport width in pixels
height: number // Viewport height in pixels
Expand Down Expand Up @@ -774,7 +774,7 @@ sequenceDiagram
H --> UI: resources/read response
end
opt UI notifications
UI ->> H: notifications (e.g., ui/notifications/size-change)
UI ->> H: notifications (e.g., ui/notifications/size-changed)
end
opt Host notifications
H ->> UI: notifications (e.g., ui/notifications/host-context-change)
Expand Down
4 changes: 2 additions & 2 deletions src/app-bridge.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,14 +180,14 @@ describe("App <-> AppBridge integration", () => {
await bridge.connect(bridgeTransport);
});

it("app.sendSizeChange triggers bridge.onsizechange", async () => {
it("app.sendSizeChanged triggers bridge.onsizechange", async () => {
const receivedSizes: unknown[] = [];
bridge.onsizechange = (params) => {
receivedSizes.push(params);
};

await app.connect(appTransport);
await app.sendSizeChange({ width: 400, height: 600 });
await app.sendSizeChanged({ width: 400, height: 600 });

expect(receivedSizes).toEqual([{ width: 400, height: 600 }]);
});
Expand Down
16 changes: 8 additions & 8 deletions src/app-bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import {

import {
type McpUiSandboxResourceReadyNotification,
type McpUiSizeChangeNotification,
type McpUiSizeChangedNotification,
type McpUiToolInputNotification,
type McpUiToolInputPartialNotification,
type McpUiToolResultNotification,
Expand All @@ -57,7 +57,7 @@ import {
McpUiResourceTeardownResultSchema,
McpUiSandboxProxyReadyNotification,
McpUiSandboxProxyReadyNotificationSchema,
McpUiSizeChangeNotificationSchema,
McpUiSizeChangedNotificationSchema,
} from "./types";
export * from "./types";
export { PostMessageTransport } from "./message-transport";
Expand Down Expand Up @@ -265,12 +265,12 @@ export class AppBridge extends Protocol<Request, Notification, Result> {
/**
* Register a handler for size change notifications from the Guest UI.
*
* The Guest UI sends `ui/notifications/size-change` when its rendered content
* The Guest UI 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.
*
* Note: This is for Guest UI → Host communication. To notify the Guest UI of
* host viewport changes, use {@link app.App.sendSizeChange}.
* host viewport changes, use {@link app.App.sendSizeChanged}.
*
* @example
* ```typescript
Expand All @@ -284,13 +284,13 @@ export class AppBridge extends Protocol<Request, Notification, Result> {
* };
* ```
*
* @see {@link McpUiSizeChangeNotification} for the notification type
* @see {@link app.App.sendSizeChange} for Host → Guest UI size notifications
* @see {@link McpUiSizeChangedNotification} for the notification type
* @see {@link app.App.sendSizeChanged} for Host → Guest UI size notifications
*/
set onsizechange(
callback: (params: McpUiSizeChangeNotification["params"]) => void,
callback: (params: McpUiSizeChangedNotification["params"]) => void,
) {
this.setNotificationHandler(McpUiSizeChangeNotificationSchema, (n) =>
this.setNotificationHandler(McpUiSizeChangedNotificationSchema, (n) =>
callback(n.params),
);
}
Expand Down
32 changes: 16 additions & 16 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {
McpUiMessageResultSchema,
McpUiOpenLinkRequest,
McpUiOpenLinkResultSchema,
McpUiSizeChangeNotification,
McpUiSizeChangedNotification,
McpUiToolInputNotification,
McpUiToolInputNotificationSchema,
McpUiToolInputPartialNotification,
Expand Down Expand Up @@ -88,7 +88,7 @@ type AppOptions = ProtocolOptions & {
* Automatically report size changes to the host using ResizeObserver.
*
* When enabled, the App monitors `document.body` and `document.documentElement`
* for size changes and automatically sends `ui/notifications/size-change`
* for size changes and automatically sends `ui/notifications/size-changed`
* notifications to the host.
*
* @default true
Expand Down Expand Up @@ -707,19 +707,19 @@ export class App extends Protocol<Request, Notification, Result> {
*
* @example Manually notify host of size change
* ```typescript
* app.sendSizeChange({
* app.sendSizeChanged({
* width: 400,
* height: 600
* });
* ```
*
* @returns Promise that resolves when the notification is sent
*
* @see {@link McpUiSizeChangeNotification} for notification structure
* @see {@link McpUiSizeChangedNotification} for notification structure
*/
sendSizeChange(params: McpUiSizeChangeNotification["params"]) {
return this.notification(<McpUiSizeChangeNotification>{
method: "ui/notifications/size-change",
sendSizeChanged(params: McpUiSizeChangedNotification["params"]) {
return this.notification(<McpUiSizeChangedNotification>{
method: "ui/notifications/size-changed",
params,
});
}
Expand All @@ -728,7 +728,7 @@ export class App extends Protocol<Request, Notification, Result> {
* Set up automatic size change notifications using ResizeObserver.
*
* Observes both `document.documentElement` and `document.body` for size changes
* and automatically sends `ui/notifications/size-change` notifications to the host.
* and automatically sends `ui/notifications/size-changed` notifications to the host.
* The notifications are debounced using requestAnimationFrame to avoid duplicates.
*
* Note: This method is automatically called by `connect()` if the `autoResize`
Expand All @@ -743,18 +743,18 @@ export class App extends Protocol<Request, Notification, Result> {
* await app.connect(transport);
*
* // Later, enable auto-resize manually
* const cleanup = app.setupSizeChangeNotifications();
* const cleanup = app.setupSizeChangedNotifications();
*
* // Clean up when done
* cleanup();
* ```
*/
setupSizeChangeNotifications() {
setupSizeChangedNotifications() {
let scheduled = false;
let lastWidth = 0;
let lastHeight = 0;

const sendBodySizeChange = () => {
const sendBodySizeChanged = () => {
if (scheduled) {
return;
}
Expand Down Expand Up @@ -785,14 +785,14 @@ export class App extends Protocol<Request, Notification, Result> {
if (width !== lastWidth || height !== lastHeight) {
lastWidth = width;
lastHeight = height;
this.sendSizeChange({ width, height });
this.sendSizeChanged({ width, height });
}
});
};

sendBodySizeChange();
sendBodySizeChanged();

const resizeObserver = new ResizeObserver(sendBodySizeChange);
const resizeObserver = new ResizeObserver(sendBodySizeChanged);
// Observe both html and body to catch all size changes
resizeObserver.observe(document.documentElement);
resizeObserver.observe(document.body);
Expand All @@ -808,7 +808,7 @@ export class App extends Protocol<Request, Notification, Result> {
* 2. Sends `ui/initialize` request with app info and capabilities
* 3. Receives host capabilities and context in response
* 4. Sends `ui/notifications/initialized` notification
* 5. Sets up auto-resize using {@link setupSizeChangeNotifications} if enabled (default)
* 5. Sets up auto-resize using {@link setupSizeChangedNotifications} if enabled (default)
*
* If initialization fails, the connection is automatically closed and an error
* is thrown.
Expand Down Expand Up @@ -869,7 +869,7 @@ export class App extends Protocol<Request, Notification, Result> {
});

if (this.options?.autoResize) {
this.setupSizeChangeNotifications();
this.setupSizeChangedNotifications();
}
} catch (error) {
// Disconnect if initialization fails.
Expand Down
6 changes: 3 additions & 3 deletions src/react/useAutoResize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { App } from "../app";
* React hook that automatically reports UI size changes to the host.
*
* Uses ResizeObserver to watch `document.body` and `document.documentElement` for
* size changes and sends `ui/notifications/size-change` notifications.
* size changes and sends `ui/notifications/size-changed` notifications.
*
* **Note**: This hook is rarely needed since the {@link useApp} hook automatically enables
* auto-resize by default. This hook is provided for advanced cases where you
Expand Down Expand Up @@ -45,7 +45,7 @@ import { App } from "../app";
* }
* ```
*
* @see {@link App.setupSizeChangeNotifications} for the underlying implementation
* @see {@link App.setupSizeChangedNotifications} for the underlying implementation
* @see {@link useApp} which enables auto-resize by default
* @see {@link App} constructor for configuring `autoResize` option
*/
Expand All @@ -58,6 +58,6 @@ export function useAutoResize(
return;
}

return app.setupSizeChangeNotifications();
return app.setupSizeChangedNotifications();
}, [app, elementRef]);
}
18 changes: 9 additions & 9 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,11 +258,11 @@ type _VerifySandboxResourceReadyNotification = VerifySchemaMatches<
* **Host → Guest UI**: Sent by the Host when the viewport size changes (e.g.,
* window resize, orientation change). This allows the Guest UI to adjust its layout.
*
* @see {@link app.App.sendSizeChange} for the method to send this from Guest UI
* @see {@link app.App.setupSizeChangeNotifications} for automatic size reporting
* @see {@link app.App.sendSizeChanged} for the method to send this from Guest UI
* @see {@link app.App.setupSizeChangedNotifications} for automatic size reporting
*/
export interface McpUiSizeChangeNotification {
method: "ui/notifications/size-change";
export interface McpUiSizeChangedNotification {
method: "ui/notifications/size-changed";
params: {
/** New width in pixels */
width?: number;
Expand All @@ -272,11 +272,11 @@ export interface McpUiSizeChangeNotification {
}

/**
* Runtime validation schema for {@link McpUiSizeChangeNotification}.
* Runtime validation schema for {@link McpUiSizeChangedNotification}.
* @internal
*/
export const McpUiSizeChangeNotificationSchema = z.object({
method: z.literal("ui/notifications/size-change"),
export const McpUiSizeChangedNotificationSchema = z.object({
method: z.literal("ui/notifications/size-changed"),
params: z.object({
width: z.number().optional(),
height: z.number().optional(),
Expand All @@ -285,8 +285,8 @@ export const McpUiSizeChangeNotificationSchema = z.object({

/** @internal - Compile-time verification that schema matches interface */
type _VerifySizeChangeNotification = VerifySchemaMatches<
typeof McpUiSizeChangeNotificationSchema,
McpUiSizeChangeNotification
typeof McpUiSizeChangedNotificationSchema,
McpUiSizeChangedNotification
>;

/**
Expand Down