Skip to content

Commit 8614792

Browse files
committed
Replace viewport with maxheight
1 parent e316259 commit 8614792

File tree

7 files changed

+45
-118
lines changed

7 files changed

+45
-118
lines changed

specification/draft/apps.mdx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -414,13 +414,12 @@ interface HostContext {
414414
displayMode?: "inline" | "fullscreen" | "pip";
415415
/** Display modes the host supports */
416416
availableDisplayModes?: string[];
417-
/** Current and maximum dimensions available to the UI */
418-
viewport?: {
419-
width: number;
420-
height: number;
421-
maxHeight?: number;
422-
maxWidth?: number;
423-
};
417+
/**
418+
* Maximum height in pixels available to the UI.
419+
* When inline, this is undefined (unlimited).
420+
* When fullscreen or pip, this reflects the container constraints.
421+
*/
422+
maxHeight?: number;
424423
/** User's language/region preference (BCP 47, e.g., "en-US") */
425424
locale?: string;
426425
/** User's timezone (IANA, e.g., "America/New_York") */
@@ -465,13 +464,13 @@ Example:
465464
...
466465
}
467466
},
468-
"displayMode": "inline",
469-
"viewport": { "width": 400, "height": 300 }
467+
"displayMode": "inline"
470468
}
471469
}
472470
}
473471
```
474472

473+
<<<<<<< HEAD
475474
### Theming
476475

477476
Hosts can optionally pass CSS custom properties via `HostContext.styles.variables` for visual cohesion with the host environment.
@@ -600,6 +599,8 @@ Example usage of standardized CSS variables:
600599
}
601600
```
602601

602+
Note: When `displayMode` is `"inline"`, `maxHeight` is omitted (undefined) indicating unlimited height. For fullscreen or pip modes, hosts SHOULD provide a `maxHeight` value.
603+
603604
### MCP Apps Specific Messages
604605

605606
MCP Apps introduces additional JSON-RPC methods for UI-specific functionality:

src/app-bridge.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ describe("App <-> AppBridge integration", () => {
109109
const testHostContext = {
110110
theme: "dark" as const,
111111
locale: "en-US",
112-
viewport: { width: 800, height: 600 },
112+
maxHeight: 600,
113113
};
114114
const newBridge = new AppBridge(
115115
createMockClient() as Client,
@@ -333,7 +333,7 @@ describe("App <-> AppBridge integration", () => {
333333
const initialContext = {
334334
theme: "light" as const,
335335
locale: "en-US",
336-
viewport: { width: 800, height: 600 },
336+
maxHeight: 600,
337337
};
338338
const newBridge = new AppBridge(
339339
createMockClient() as Client,
@@ -350,20 +350,20 @@ describe("App <-> AppBridge integration", () => {
350350
newBridge.sendHostContextChange({ theme: "dark" });
351351
await flush();
352352

353-
// Send another partial update: only viewport changes
353+
// Send another partial update: only maxHeight changes
354354
newBridge.sendHostContextChange({
355-
viewport: { width: 1024, height: 768 },
355+
maxHeight: 768,
356356
});
357357
await flush();
358358

359359
// getHostContext should have accumulated all updates:
360360
// - locale from initial (unchanged)
361361
// - theme from first partial update
362-
// - viewport from second partial update
362+
// - maxHeight from second partial update
363363
const context = newApp.getHostContext();
364364
expect(context?.theme).toBe("dark");
365365
expect(context?.locale).toBe("en-US");
366-
expect(context?.viewport).toEqual({ width: 1024, height: 768 });
366+
expect(context?.maxHeight).toBe(768);
367367

368368
await newAppTransport.close();
369369
await newBridgeTransport.close();

src/app-bridge.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -907,7 +907,7 @@ export class AppBridge extends Protocol<
907907
* ```typescript
908908
* bridge.setHostContext({
909909
* theme: "dark",
910-
* viewport: { width: 800, height: 600 }
910+
* maxHeight: 600
911911
* });
912912
* ```
913913
*

src/app.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ type RequestHandlerExtra = Parameters<
150150
* - `ontoolinput` - Complete tool arguments from host
151151
* - `ontoolinputpartial` - Streaming partial tool arguments
152152
* - `ontoolresult` - Tool execution results
153-
* - `onhostcontextchanged` - Host context changes (theme, viewport, etc.)
153+
* - `onhostcontextchanged` - Host context changes (theme, maxHeight, etc.)
154154
*
155155
* These setters are convenience wrappers around `setNotificationHandler()`.
156156
* Both patterns work; use whichever fits your coding style better.
@@ -289,7 +289,7 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
289289
* Get the host context discovered during initialization.
290290
*
291291
* Returns the host context that was provided in the initialization response,
292-
* including tool info, theme, viewport, locale, and other environment details.
292+
* including tool info, theme, maxHeight, locale, and other environment details.
293293
* This context is automatically updated when the host sends
294294
* `ui/notifications/host-context-changed` notifications.
295295
*
@@ -474,7 +474,7 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
474474
}
475475

476476
/**
477-
* Convenience handler for host context changes (theme, viewport, locale, etc.).
477+
* Convenience handler for host context changes (theme, maxHeight, locale, etc.).
478478
*
479479
* Set this property to register a handler that will be called when the host's
480480
* context changes, such as theme switching (light/dark), viewport size changes,

src/generated/schema.json

Lines changed: 9 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -613,29 +613,9 @@
613613
"type": "string"
614614
}
615615
},
616-
"viewport": {
617-
"description": "Current and maximum dimensions available to the UI.",
618-
"type": "object",
619-
"properties": {
620-
"width": {
621-
"description": "Current viewport width in pixels.",
622-
"type": "number"
623-
},
624-
"height": {
625-
"description": "Current viewport height in pixels.",
626-
"type": "number"
627-
},
628-
"maxHeight": {
629-
"description": "Maximum available height in pixels (if constrained).",
630-
"type": "number"
631-
},
632-
"maxWidth": {
633-
"description": "Maximum available width in pixels (if constrained).",
634-
"type": "number"
635-
}
636-
},
637-
"required": ["width", "height"],
638-
"additionalProperties": false
616+
"maxHeight": {
617+
"description": "Maximum height in pixels available to the UI.\nWhen inline, this is undefined (unlimited). When fullscreen or pip,\nthis reflects the container constraints.",
618+
"type": "number"
639619
},
640620
"locale": {
641621
"description": "User's language and region preference in BCP 47 format.",
@@ -1224,29 +1204,9 @@
12241204
"type": "string"
12251205
}
12261206
},
1227-
"viewport": {
1228-
"description": "Current and maximum dimensions available to the UI.",
1229-
"type": "object",
1230-
"properties": {
1231-
"width": {
1232-
"description": "Current viewport width in pixels.",
1233-
"type": "number"
1234-
},
1235-
"height": {
1236-
"description": "Current viewport height in pixels.",
1237-
"type": "number"
1238-
},
1239-
"maxHeight": {
1240-
"description": "Maximum available height in pixels (if constrained).",
1241-
"type": "number"
1242-
},
1243-
"maxWidth": {
1244-
"description": "Maximum available width in pixels (if constrained).",
1245-
"type": "number"
1246-
}
1247-
},
1248-
"required": ["width", "height"],
1249-
"additionalProperties": false
1207+
"maxHeight": {
1208+
"description": "Maximum height in pixels available to the UI.\nWhen inline, this is undefined (unlimited). When fullscreen or pip,\nthis reflects the container constraints.",
1209+
"type": "number"
12501210
},
12511211
"locale": {
12521212
"description": "User's language and region preference in BCP 47 format.",
@@ -2342,29 +2302,9 @@
23422302
"type": "string"
23432303
}
23442304
},
2345-
"viewport": {
2346-
"description": "Current and maximum dimensions available to the UI.",
2347-
"type": "object",
2348-
"properties": {
2349-
"width": {
2350-
"description": "Current viewport width in pixels.",
2351-
"type": "number"
2352-
},
2353-
"height": {
2354-
"description": "Current viewport height in pixels.",
2355-
"type": "number"
2356-
},
2357-
"maxHeight": {
2358-
"description": "Maximum available height in pixels (if constrained).",
2359-
"type": "number"
2360-
},
2361-
"maxWidth": {
2362-
"description": "Maximum available width in pixels (if constrained).",
2363-
"type": "number"
2364-
}
2365-
},
2366-
"required": ["width", "height"],
2367-
"additionalProperties": false
2305+
"maxHeight": {
2306+
"description": "Maximum height in pixels available to the UI.\nWhen inline, this is undefined (unlimited). When fullscreen or pip,\nthis reflects the container constraints.",
2307+
"type": "number"
23682308
},
23692309
"locale": {
23702310
"description": "User's language and region preference in BCP 47 format.",

src/generated/schema.ts

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -484,26 +484,17 @@ export const McpUiHostContextSchema = z.looseObject({
484484
.array(z.string())
485485
.optional()
486486
.describe("Display modes the host supports."),
487-
/** @description Current and maximum dimensions available to the UI. */
488-
viewport: z
489-
.object({
490-
/** @description Current viewport width in pixels. */
491-
width: z.number().describe("Current viewport width in pixels."),
492-
/** @description Current viewport height in pixels. */
493-
height: z.number().describe("Current viewport height in pixels."),
494-
/** @description Maximum available height in pixels (if constrained). */
495-
maxHeight: z
496-
.number()
497-
.optional()
498-
.describe("Maximum available height in pixels (if constrained)."),
499-
/** @description Maximum available width in pixels (if constrained). */
500-
maxWidth: z
501-
.number()
502-
.optional()
503-
.describe("Maximum available width in pixels (if constrained)."),
504-
})
487+
/**
488+
* @description Maximum height in pixels available to the UI.
489+
* When inline, this is undefined (unlimited). When fullscreen or pip,
490+
* this reflects the container constraints.
491+
*/
492+
maxHeight: z
493+
.number()
505494
.optional()
506-
.describe("Current and maximum dimensions available to the UI."),
495+
.describe(
496+
"Maximum height in pixels available to the UI.\nWhen inline, this is undefined (unlimited). When fullscreen or pip,\nthis reflects the container constraints.",
497+
),
507498
/** @description User's language and region preference in BCP 47 format. */
508499
locale: z
509500
.string()

src/spec.types.ts

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -313,17 +313,12 @@ export interface McpUiHostContext {
313313
displayMode?: McpUiDisplayMode;
314314
/** @description Display modes the host supports. */
315315
availableDisplayModes?: string[];
316-
/** @description Current and maximum dimensions available to the UI. */
317-
viewport?: {
318-
/** @description Current viewport width in pixels. */
319-
width: number;
320-
/** @description Current viewport height in pixels. */
321-
height: number;
322-
/** @description Maximum available height in pixels (if constrained). */
323-
maxHeight?: number;
324-
/** @description Maximum available width in pixels (if constrained). */
325-
maxWidth?: number;
326-
};
316+
/**
317+
* @description Maximum height in pixels available to the UI.
318+
* When inline, this is undefined (unlimited). When fullscreen or pip,
319+
* this reflects the container constraints.
320+
*/
321+
maxHeight?: number;
327322
/** @description User's language and region preference in BCP 47 format. */
328323
locale?: string;
329324
/** @description User's timezone in IANA format. */

0 commit comments

Comments
 (0)