Update documentation and revert type change

This commit is contained in:
martinalong 2025-12-17 21:20:14 -08:00
commit 87f6f3f27e
No known key found for this signature in database
5 changed files with 108 additions and 200 deletions

View file

@ -461,18 +461,17 @@ interface HostContext {
displayMode?: "inline" | "fullscreen" | "pip"; displayMode?: "inline" | "fullscreen" | "pip";
/** Display modes the host supports */ /** Display modes the host supports */
availableDisplayModes?: string[]; availableDisplayModes?: string[];
/** /** Current and maximum dimensions available to the UI. */
* Viewport dimensions available to the UI. viewport?: {
* /** Current viewport width in pixels. */
* The viewport has two independent dimension pairs: width: number;
* - Height: Either `height` (fixed) or `maxHeight` (flexible), never both /** Current viewport height in pixels. */
* - Width: Either `width` (fixed) or `maxWidth` (flexible), never both height: number;
* /** Maximum available height in pixels (if constrained). */
* Fixed dimensions (height/width): The host controls the size. Set height: 100% (recommended) or use the pixel value directly. maxHeight?: number;
* Flexible dimensions (maxHeight/maxWidth or undefined): The app controls the size, up to the max if specified. /** Maximum available width in pixels (if constrained). */
*/ maxWidth?: number;
viewport?: ({ height: number } | { maxHeight?: number }) & };
({ width: number } | { maxWidth?: number });
/** User's language/region preference (BCP 47, e.g., "en-US") */ /** User's language/region preference (BCP 47, e.g., "en-US") */
locale?: string; locale?: string;
/** User's timezone (IANA, e.g., "America/New_York") */ /** User's timezone (IANA, e.g., "America/New_York") */

View file

@ -113,7 +113,7 @@ describe("App <-> AppBridge integration", () => {
const testHostContext = { const testHostContext = {
theme: "dark" as const, theme: "dark" as const,
locale: "en-US", locale: "en-US",
viewport: { width: 800, maxHeight: 600 }, viewport: { width: 800, height: 600, maxHeight: 600 },
}; };
const newBridge = new AppBridge( const newBridge = new AppBridge(
createMockClient() as Client, createMockClient() as Client,
@ -337,7 +337,7 @@ describe("App <-> AppBridge integration", () => {
const initialContext = { const initialContext = {
theme: "light" as const, theme: "light" as const,
locale: "en-US", locale: "en-US",
viewport: { width: 800, maxHeight: 600 }, viewport: { width: 800, height: 600, maxHeight: 600 },
}; };
const newBridge = new AppBridge( const newBridge = new AppBridge(
createMockClient() as Client, createMockClient() as Client,
@ -356,7 +356,7 @@ describe("App <-> AppBridge integration", () => {
// Send another partial update: only viewport changes // Send another partial update: only viewport changes
newBridge.sendHostContextChange({ newBridge.sendHostContextChange({
viewport: { width: 1024, maxHeight: 768 }, viewport: { width: 1024, height: 768, maxHeight: 768 },
}); });
await flush(); await flush();
@ -367,7 +367,11 @@ describe("App <-> AppBridge integration", () => {
const context = newApp.getHostContext(); const context = newApp.getHostContext();
expect(context?.theme).toBe("dark"); expect(context?.theme).toBe("dark");
expect(context?.locale).toBe("en-US"); expect(context?.locale).toBe("en-US");
expect(context?.viewport).toEqual({ width: 1024, maxHeight: 768 }); expect(context?.viewport).toEqual({
width: 1024,
height: 768,
maxHeight: 768,
});
await newAppTransport.close(); await newAppTransport.close();
await newBridgeTransport.close(); await newBridgeTransport.close();

View file

@ -629,55 +629,28 @@
} }
}, },
"viewport": { "viewport": {
"description": "Viewport dimensions available to the UI.\n\nThe viewport has two independent dimension pairs:\n- Height: Either `height` (fixed) or `maxHeight` (flexible), never both\n- Width: Either `width` (fixed) or `maxWidth` (flexible), never both\n\nFixed dimensions (height/width): The host controls the size. Set height: 100% (recommended) or use the pixel value directly.\nFlexible dimensions (maxHeight/maxWidth or undefined): The app controls the size, up to the max if specified. If undefined, there is no limit.", "description": "Current and maximum dimensions available to the UI.",
"allOf": [ "type": "object",
{ "properties": {
"anyOf": [ "width": {
{ "description": "Current viewport width in pixels.",
"type": "object", "type": "number"
"properties": {
"height": {
"type": "number"
}
},
"required": ["height"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"maxHeight": {
"type": "number"
}
},
"additionalProperties": false
}
]
}, },
{ "height": {
"anyOf": [ "description": "Current viewport height in pixels.",
{ "type": "number"
"type": "object", },
"properties": { "maxHeight": {
"width": { "description": "Maximum available height in pixels (if constrained).",
"type": "number" "type": "number"
} },
}, "maxWidth": {
"required": ["width"], "description": "Maximum available width in pixels (if constrained).",
"additionalProperties": false "type": "number"
},
{
"type": "object",
"properties": {
"maxWidth": {
"type": "number"
}
},
"additionalProperties": false
}
]
} }
] },
"required": ["width", "height"],
"additionalProperties": false
}, },
"locale": { "locale": {
"description": "User's language and region preference in BCP 47 format.", "description": "User's language and region preference in BCP 47 format.",
@ -1282,55 +1255,28 @@
} }
}, },
"viewport": { "viewport": {
"description": "Viewport dimensions available to the UI.\n\nThe viewport has two independent dimension pairs:\n- Height: Either `height` (fixed) or `maxHeight` (flexible), never both\n- Width: Either `width` (fixed) or `maxWidth` (flexible), never both\n\nFixed dimensions (height/width): The host controls the size. Set height: 100% (recommended) or use the pixel value directly.\nFlexible dimensions (maxHeight/maxWidth or undefined): The app controls the size, up to the max if specified. If undefined, there is no limit.", "description": "Current and maximum dimensions available to the UI.",
"allOf": [ "type": "object",
{ "properties": {
"anyOf": [ "width": {
{ "description": "Current viewport width in pixels.",
"type": "object", "type": "number"
"properties": {
"height": {
"type": "number"
}
},
"required": ["height"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"maxHeight": {
"type": "number"
}
},
"additionalProperties": false
}
]
}, },
{ "height": {
"anyOf": [ "description": "Current viewport height in pixels.",
{ "type": "number"
"type": "object", },
"properties": { "maxHeight": {
"width": { "description": "Maximum available height in pixels (if constrained).",
"type": "number" "type": "number"
} },
}, "maxWidth": {
"required": ["width"], "description": "Maximum available width in pixels (if constrained).",
"additionalProperties": false "type": "number"
},
{
"type": "object",
"properties": {
"maxWidth": {
"type": "number"
}
},
"additionalProperties": false
}
]
} }
] },
"required": ["width", "height"],
"additionalProperties": false
}, },
"locale": { "locale": {
"description": "User's language and region preference in BCP 47 format.", "description": "User's language and region preference in BCP 47 format.",
@ -2468,55 +2414,28 @@
} }
}, },
"viewport": { "viewport": {
"description": "Viewport dimensions available to the UI.\n\nThe viewport has two independent dimension pairs:\n- Height: Either `height` (fixed) or `maxHeight` (flexible), never both\n- Width: Either `width` (fixed) or `maxWidth` (flexible), never both\n\nFixed dimensions (height/width): The host controls the size. Set height: 100% (recommended) or use the pixel value directly.\nFlexible dimensions (maxHeight/maxWidth or undefined): The app controls the size, up to the max if specified. If undefined, there is no limit.", "description": "Current and maximum dimensions available to the UI.",
"allOf": [ "type": "object",
{ "properties": {
"anyOf": [ "width": {
{ "description": "Current viewport width in pixels.",
"type": "object", "type": "number"
"properties": {
"height": {
"type": "number"
}
},
"required": ["height"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"maxHeight": {
"type": "number"
}
},
"additionalProperties": false
}
]
}, },
{ "height": {
"anyOf": [ "description": "Current viewport height in pixels.",
{ "type": "number"
"type": "object", },
"properties": { "maxHeight": {
"width": { "description": "Maximum available height in pixels (if constrained).",
"type": "number" "type": "number"
} },
}, "maxWidth": {
"required": ["width"], "description": "Maximum available width in pixels (if constrained).",
"additionalProperties": false "type": "number"
},
{
"type": "object",
"properties": {
"maxWidth": {
"type": "number"
}
},
"additionalProperties": false
}
]
} }
] },
"required": ["width", "height"],
"additionalProperties": false
}, },
"locale": { "locale": {
"description": "User's language and region preference in BCP 47 format.", "description": "User's language and region preference in BCP 47 format.",

View file

@ -562,39 +562,26 @@ export const McpUiHostContextSchema = z.looseObject({
.array(z.string()) .array(z.string())
.optional() .optional()
.describe("Display modes the host supports."), .describe("Display modes the host supports."),
/** /** @description Current and maximum dimensions available to the UI. */
* @description Viewport dimensions available to the UI.
*
* The viewport has two independent dimension pairs:
* - Height: Either `height` (fixed) or `maxHeight` (flexible), never both
* - Width: Either `width` (fixed) or `maxWidth` (flexible), never both
*
* Fixed dimensions (height/width): The host controls the size. Set height: 100% (recommended) or use the pixel value directly.
* Flexible dimensions (maxHeight/maxWidth or undefined): The app controls the size, up to the max if specified. If undefined, there is no limit.
*/
viewport: z viewport: z
.union([ .object({
z.object({ /** @description Current viewport width in pixels. */
height: z.number(), width: z.number().describe("Current viewport width in pixels."),
}), /** @description Current viewport height in pixels. */
z.object({ height: z.number().describe("Current viewport height in pixels."),
maxHeight: z.number().optional(), /** @description Maximum available height in pixels (if constrained). */
}), maxHeight: z
]) .number()
.and( .optional()
z.union([ .describe("Maximum available height in pixels (if constrained)."),
z.object({ /** @description Maximum available width in pixels (if constrained). */
width: z.number(), maxWidth: z
}), .number()
z.object({ .optional()
maxWidth: z.number().optional(), .describe("Maximum available width in pixels (if constrained)."),
}), })
]),
)
.optional() .optional()
.describe( .describe("Current and maximum dimensions available to the UI."),
"Viewport dimensions available to the UI.\n\nThe viewport has two independent dimension pairs:\n- Height: Either `height` (fixed) or `maxHeight` (flexible), never both\n- Width: Either `width` (fixed) or `maxWidth` (flexible), never both\n\nFixed dimensions (height/width): The host controls the size. Set height: 100% (recommended) or use the pixel value directly.\nFlexible dimensions (maxHeight/maxWidth or undefined): The app controls the size, up to the max if specified. If undefined, there is no limit.",
),
/** @description User's language and region preference in BCP 47 format. */ /** @description User's language and region preference in BCP 47 format. */
locale: z locale: z
.string() .string()

View file

@ -324,18 +324,17 @@ export interface McpUiHostContext {
displayMode?: McpUiDisplayMode; displayMode?: McpUiDisplayMode;
/** @description Display modes the host supports. */ /** @description Display modes the host supports. */
availableDisplayModes?: string[]; availableDisplayModes?: string[];
/** /** @description Current and maximum dimensions available to the UI. */
* @description Viewport dimensions available to the UI. viewport?: {
* /** @description Current viewport width in pixels. */
* The viewport has two independent dimension pairs: width: number;
* - Height: Either `height` (fixed) or `maxHeight` (flexible), never both /** @description Current viewport height in pixels. */
* - Width: Either `width` (fixed) or `maxWidth` (flexible), never both height: number;
* /** @description Maximum available height in pixels (if constrained). */
* Fixed dimensions (height/width): The host controls the size. Set height: 100% (recommended) or use the pixel value directly. maxHeight?: number;
* Flexible dimensions (maxHeight/maxWidth or undefined): The app controls the size, up to the max if specified. If undefined, there is no limit. /** @description Maximum available width in pixels (if constrained). */
*/ maxWidth?: number;
viewport?: ({ height: number } | { maxHeight?: number }) & };
({ width: number } | { maxWidth?: number });
/** @description User's language and region preference in BCP 47 format. */ /** @description User's language and region preference in BCP 47 format. */
locale?: string; locale?: string;
/** @description User's timezone in IANA format. */ /** @description User's timezone in IANA format. */