Skip to content

Commit ced5954

Browse files
committed
Replace viewport with maxheight
1 parent 372c241 commit ced5954

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
@@ -408,13 +408,12 @@ interface HostContext {
408408
displayMode?: "inline" | "fullscreen" | "pip";
409409
/** Display modes the host supports */
410410
availableDisplayModes?: string[];
411-
/** Current and maximum dimensions available to the UI */
412-
viewport?: {
413-
width: number;
414-
height: number;
415-
maxHeight?: number;
416-
maxWidth?: number;
417-
};
411+
/**
412+
* Maximum height in pixels available to the UI.
413+
* When inline, this is undefined (unlimited).
414+
* When fullscreen or pip, this reflects the container constraints.
415+
*/
416+
maxHeight?: number;
418417
/** User's language/region preference (BCP 47, e.g., "en-US") */
419418
locale?: string;
420419
/** User's timezone (IANA, e.g., "America/New_York") */
@@ -453,13 +452,15 @@ Example:
453452
"hostInfo": { "name": "claude-desktop", "version": "1.0.0" },
454453
"hostContext": {
455454
"theme": "dark",
456-
"displayMode": "inline",
457-
"viewport": { "width": 400, "height": 300 }
455+
"displayMode": "inline"
458456
}
459457
}
460458
}
461459
```
462460

461+
Note: When `displayMode` is `"inline"`, `maxHeight` is omitted (undefined) indicating unlimited height. For fullscreen or pip modes, hosts SHOULD provide a `maxHeight` value.
462+
463+
463464
### MCP Apps Specific Messages
464465

465466
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
@@ -145,7 +145,7 @@ type RequestHandlerExtra = Parameters<
145145
* - `ontoolinput` - Complete tool arguments from host
146146
* - `ontoolinputpartial` - Streaming partial tool arguments
147147
* - `ontoolresult` - Tool execution results
148-
* - `onhostcontextchanged` - Host context changes (theme, viewport, etc.)
148+
* - `onhostcontextchanged` - Host context changes (theme, maxHeight, etc.)
149149
*
150150
* These setters are convenience wrappers around `setNotificationHandler()`.
151151
* Both patterns work; use whichever fits your coding style better.
@@ -284,7 +284,7 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
284284
* Get the host context discovered during initialization.
285285
*
286286
* Returns the host context that was provided in the initialization response,
287-
* including tool info, theme, viewport, locale, and other environment details.
287+
* including tool info, theme, maxHeight, locale, and other environment details.
288288
* This context is automatically updated when the host sends
289289
* `ui/notifications/host-context-changed` notifications.
290290
*
@@ -469,7 +469,7 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
469469
}
470470

471471
/**
472-
* Convenience handler for host context changes (theme, viewport, locale, etc.).
472+
* Convenience handler for host context changes (theme, maxHeight, locale, etc.).
473473
*
474474
* Set this property to register a handler that will be called when the host's
475475
* 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
@@ -288,29 +288,9 @@
288288
"type": "string"
289289
}
290290
},
291-
"viewport": {
292-
"description": "Current and maximum dimensions available to the UI.",
293-
"type": "object",
294-
"properties": {
295-
"width": {
296-
"description": "Current viewport width in pixels.",
297-
"type": "number"
298-
},
299-
"height": {
300-
"description": "Current viewport height in pixels.",
301-
"type": "number"
302-
},
303-
"maxHeight": {
304-
"description": "Maximum available height in pixels (if constrained).",
305-
"type": "number"
306-
},
307-
"maxWidth": {
308-
"description": "Maximum available width in pixels (if constrained).",
309-
"type": "number"
310-
}
311-
},
312-
"required": ["width", "height"],
313-
"additionalProperties": false
291+
"maxHeight": {
292+
"description": "Maximum height in pixels available to the UI.\nWhen inline, this is undefined (unlimited). When fullscreen or pip,\nthis reflects the container constraints.",
293+
"type": "number"
314294
},
315295
"locale": {
316296
"description": "User's language and region preference in BCP 47 format.",
@@ -574,29 +554,9 @@
574554
"type": "string"
575555
}
576556
},
577-
"viewport": {
578-
"description": "Current and maximum dimensions available to the UI.",
579-
"type": "object",
580-
"properties": {
581-
"width": {
582-
"description": "Current viewport width in pixels.",
583-
"type": "number"
584-
},
585-
"height": {
586-
"description": "Current viewport height in pixels.",
587-
"type": "number"
588-
},
589-
"maxHeight": {
590-
"description": "Maximum available height in pixels (if constrained).",
591-
"type": "number"
592-
},
593-
"maxWidth": {
594-
"description": "Maximum available width in pixels (if constrained).",
595-
"type": "number"
596-
}
597-
},
598-
"required": ["width", "height"],
599-
"additionalProperties": false
557+
"maxHeight": {
558+
"description": "Maximum height in pixels available to the UI.\nWhen inline, this is undefined (unlimited). When fullscreen or pip,\nthis reflects the container constraints.",
559+
"type": "number"
600560
},
601561
"locale": {
602562
"description": "User's language and region preference in BCP 47 format.",
@@ -1042,29 +1002,9 @@
10421002
"type": "string"
10431003
}
10441004
},
1045-
"viewport": {
1046-
"description": "Current and maximum dimensions available to the UI.",
1047-
"type": "object",
1048-
"properties": {
1049-
"width": {
1050-
"description": "Current viewport width in pixels.",
1051-
"type": "number"
1052-
},
1053-
"height": {
1054-
"description": "Current viewport height in pixels.",
1055-
"type": "number"
1056-
},
1057-
"maxHeight": {
1058-
"description": "Maximum available height in pixels (if constrained).",
1059-
"type": "number"
1060-
},
1061-
"maxWidth": {
1062-
"description": "Maximum available width in pixels (if constrained).",
1063-
"type": "number"
1064-
}
1065-
},
1066-
"required": ["width", "height"],
1067-
"additionalProperties": false
1005+
"maxHeight": {
1006+
"description": "Maximum height in pixels available to the UI.\nWhen inline, this is undefined (unlimited). When fullscreen or pip,\nthis reflects the container constraints.",
1007+
"type": "number"
10681008
},
10691009
"locale": {
10701010
"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
@@ -363,26 +363,17 @@ export const McpUiHostContextSchema = z.looseObject({
363363
.array(z.string())
364364
.optional()
365365
.describe("Display modes the host supports."),
366-
/** @description Current and maximum dimensions available to the UI. */
367-
viewport: z
368-
.object({
369-
/** @description Current viewport width in pixels. */
370-
width: z.number().describe("Current viewport width in pixels."),
371-
/** @description Current viewport height in pixels. */
372-
height: z.number().describe("Current viewport height in pixels."),
373-
/** @description Maximum available height in pixels (if constrained). */
374-
maxHeight: z
375-
.number()
376-
.optional()
377-
.describe("Maximum available height in pixels (if constrained)."),
378-
/** @description Maximum available width in pixels (if constrained). */
379-
maxWidth: z
380-
.number()
381-
.optional()
382-
.describe("Maximum available width in pixels (if constrained)."),
383-
})
366+
/**
367+
* @description Maximum height in pixels available to the UI.
368+
* When inline, this is undefined (unlimited). When fullscreen or pip,
369+
* this reflects the container constraints.
370+
*/
371+
maxHeight: z
372+
.number()
384373
.optional()
385-
.describe("Current and maximum dimensions available to the UI."),
374+
.describe(
375+
"Maximum height in pixels available to the UI.\nWhen inline, this is undefined (unlimited). When fullscreen or pip,\nthis reflects the container constraints.",
376+
),
386377
/** @description User's language and region preference in BCP 47 format. */
387378
locale: z
388379
.string()

src/spec.types.ts

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -199,17 +199,12 @@ export interface McpUiHostContext {
199199
displayMode?: McpUiDisplayMode;
200200
/** @description Display modes the host supports. */
201201
availableDisplayModes?: string[];
202-
/** @description Current and maximum dimensions available to the UI. */
203-
viewport?: {
204-
/** @description Current viewport width in pixels. */
205-
width: number;
206-
/** @description Current viewport height in pixels. */
207-
height: number;
208-
/** @description Maximum available height in pixels (if constrained). */
209-
maxHeight?: number;
210-
/** @description Maximum available width in pixels (if constrained). */
211-
maxWidth?: number;
212-
};
202+
/**
203+
* @description Maximum height in pixels available to the UI.
204+
* When inline, this is undefined (unlimited). When fullscreen or pip,
205+
* this reflects the container constraints.
206+
*/
207+
maxHeight?: number;
213208
/** @description User's language and region preference in BCP 47 format. */
214209
locale?: string;
215210
/** @description User's timezone in IANA format. */

0 commit comments

Comments
 (0)