Merge pull request #153 from modelcontextprotocol/martinalong/mcp-apps/max-height-only
[MCP Apps] Update `viewport` type
This commit is contained in:
commit
38126f7c7f
8 changed files with 366 additions and 117 deletions
|
|
@ -25,7 +25,7 @@ export interface WidgetProps<TToolInput = Record<string, unknown>> {
|
|||
toolInputsPartial: TToolInput | null;
|
||||
/** Tool execution result from the server */
|
||||
toolResult: CallToolResult | null;
|
||||
/** Host context (theme, viewport, locale, etc.) */
|
||||
/** Host context (theme, dimensions, locale, etc.) */
|
||||
hostContext: McpUiHostContext | null;
|
||||
/** Call a tool on the MCP server */
|
||||
callServerTool: App["callServerTool"];
|
||||
|
|
@ -65,7 +65,7 @@ function McpAppWrapper() {
|
|||
app.ontoolresult = (params) => {
|
||||
setToolResult(params as CallToolResult);
|
||||
};
|
||||
// Host context changes (theme, viewport, etc.)
|
||||
// Host context changes (theme, dimensions, etc.)
|
||||
app.onhostcontextchanged = (params) => {
|
||||
setHostContext(params);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -461,13 +461,14 @@ interface HostContext {
|
|||
displayMode?: "inline" | "fullscreen" | "pip";
|
||||
/** Display modes the host supports */
|
||||
availableDisplayModes?: string[];
|
||||
/** Current and maximum dimensions available to the UI */
|
||||
viewport?: {
|
||||
width: number;
|
||||
height: number;
|
||||
maxHeight?: number;
|
||||
maxWidth?: number;
|
||||
};
|
||||
/** Container dimensions for the iframe. Specify either width or maxWidth, and either height or maxHeight. */
|
||||
containerDimensions?: (
|
||||
| { height: number } // If specified, container is fixed at this height
|
||||
| { maxHeight?: number } // Otherwise, container height is determined by the UI height, up to this maximum height (if defined)
|
||||
) & (
|
||||
| { width: number } // If specified, container is fixed at this width
|
||||
| { maxWidth?: number } // Otherwise, container width is determined by the UI width, up to this maximum width (if defined)
|
||||
);
|
||||
/** User's language/region preference (BCP 47, e.g., "en-US") */
|
||||
locale?: string;
|
||||
/** User's timezone (IANA, e.g., "America/New_York") */
|
||||
|
|
@ -516,12 +517,78 @@ Example:
|
|||
}
|
||||
},
|
||||
"displayMode": "inline",
|
||||
"viewport": { "width": 400, "height": 300 }
|
||||
"containerDimensions": { "width": 400, "maxHeight": 600 }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Container Dimensions
|
||||
|
||||
The `HostContext` provides sizing information via `containerDimensions`:
|
||||
|
||||
- **`containerDimensions`**: The dimensions of the container that holds the app. This controls the actual space the app occupies within the host. Each dimension (height and width) operates independently and can be either **fixed** or **flexible**.
|
||||
|
||||
#### Dimension Modes
|
||||
|
||||
| Mode | Dimensions Field | Meaning |
|
||||
|------|-----------------|---------|
|
||||
| Fixed | `height` or `width` | Host controls the size. App should fill the available space. |
|
||||
| Flexible | `maxHeight` or `maxWidth` | App controls the size, up to the specified maximum. |
|
||||
| Unbounded | Field omitted | App controls the size with no limit. |
|
||||
|
||||
These modes can be combined independently. For example, a host might specify a fixed width but flexible height, allowing the app to grow vertically based on content.
|
||||
|
||||
#### App Behavior
|
||||
|
||||
Apps should check the containerDimensions configuration and apply appropriate CSS:
|
||||
|
||||
```typescript
|
||||
// In the app's initialization
|
||||
const containerDimensions = hostContext.containerDimensions;
|
||||
|
||||
if (containerDimensions) {
|
||||
// Handle height
|
||||
if ("height" in containerDimensions) {
|
||||
// Fixed height: fill the container
|
||||
document.documentElement.style.height = "100vh";
|
||||
} else if ("maxHeight" in containerDimensions && containerDimensions.maxHeight) {
|
||||
// Flexible with max: let content determine size, up to max
|
||||
document.documentElement.style.maxHeight = `${containerDimensions.maxHeight}px`;
|
||||
}
|
||||
// If neither, height is unbounded
|
||||
|
||||
// Handle width
|
||||
if ("width" in containerDimensions) {
|
||||
// Fixed width: fill the container
|
||||
document.documentElement.style.width = "100vw";
|
||||
} else if ("maxWidth" in containerDimensions && containerDimensions.maxWidth) {
|
||||
// Flexible with max: let content determine size, up to max
|
||||
document.documentElement.style.maxWidth = `${containerDimensions.maxWidth}px`;
|
||||
}
|
||||
// If neither, width is unbounded
|
||||
}
|
||||
```
|
||||
|
||||
#### Host Behavior
|
||||
|
||||
When using flexible dimensions (no fixed `height` or `width`), hosts MUST listen for `ui/notifications/size-changed` notifications from the app and update the iframe dimensions accordingly:
|
||||
|
||||
```typescript
|
||||
// Host listens for size changes from the app
|
||||
bridge.onsizechange = ({ width, height }) => {
|
||||
// Update iframe to match app's content size
|
||||
if (width != null) {
|
||||
iframe.style.width = `${width}px`;
|
||||
}
|
||||
if (height != null) {
|
||||
iframe.style.height = `${height}px`;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
Apps using the SDK automatically send size-changed notifications via ResizeObserver when `autoResize` is enabled (the default). The notifications are debounced and only sent when dimensions actually change.
|
||||
|
||||
### Theming
|
||||
|
||||
Hosts can optionally pass CSS custom properties via `HostContext.styles.variables` for visual cohesion with the host environment.
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ describe("App <-> AppBridge integration", () => {
|
|||
const testHostContext = {
|
||||
theme: "dark" as const,
|
||||
locale: "en-US",
|
||||
viewport: { width: 800, height: 600 },
|
||||
containerDimensions: { width: 800, maxHeight: 600 },
|
||||
};
|
||||
const newBridge = new AppBridge(
|
||||
createMockClient() as Client,
|
||||
|
|
@ -337,7 +337,7 @@ describe("App <-> AppBridge integration", () => {
|
|||
const initialContext = {
|
||||
theme: "light" as const,
|
||||
locale: "en-US",
|
||||
viewport: { width: 800, height: 600 },
|
||||
containerDimensions: { width: 800, maxHeight: 600 },
|
||||
};
|
||||
const newBridge = new AppBridge(
|
||||
createMockClient() as Client,
|
||||
|
|
@ -354,20 +354,23 @@ describe("App <-> AppBridge integration", () => {
|
|||
newBridge.sendHostContextChange({ theme: "dark" });
|
||||
await flush();
|
||||
|
||||
// Send another partial update: only viewport changes
|
||||
// Send another partial update: only containerDimensions change
|
||||
newBridge.sendHostContextChange({
|
||||
viewport: { width: 1024, height: 768 },
|
||||
containerDimensions: { width: 1024, maxHeight: 768 },
|
||||
});
|
||||
await flush();
|
||||
|
||||
// getHostContext should have accumulated all updates:
|
||||
// - locale from initial (unchanged)
|
||||
// - theme from first partial update
|
||||
// - viewport from second partial update
|
||||
// - containerDimensions from second partial update
|
||||
const context = newApp.getHostContext();
|
||||
expect(context?.theme).toBe("dark");
|
||||
expect(context?.locale).toBe("en-US");
|
||||
expect(context?.viewport).toEqual({ width: 1024, height: 768 });
|
||||
expect(context?.containerDimensions).toEqual({
|
||||
width: 1024,
|
||||
maxHeight: 768,
|
||||
});
|
||||
|
||||
await newAppTransport.close();
|
||||
await newBridgeTransport.close();
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ export class AppBridge extends Protocol<
|
|||
* 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.sendSizeChanged}.
|
||||
* host container dimension changes, use {@link setHostContext}.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
|
|
@ -1008,7 +1008,7 @@ export class AppBridge extends Protocol<
|
|||
* ```typescript
|
||||
* bridge.setHostContext({
|
||||
* theme: "dark",
|
||||
* viewport: { width: 800, height: 600 }
|
||||
* containerDimensions: { maxHeight: 600, width: 800 }
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
|
|
|
|||
12
src/app.ts
12
src/app.ts
|
|
@ -154,7 +154,7 @@ type RequestHandlerExtra = Parameters<
|
|||
* - `ontoolinput` - Complete tool arguments from host
|
||||
* - `ontoolinputpartial` - Streaming partial tool arguments
|
||||
* - `ontoolresult` - Tool execution results
|
||||
* - `onhostcontextchanged` - Host context changes (theme, viewport, etc.)
|
||||
* - `onhostcontextchanged` - Host context changes (theme, locale, etc.)
|
||||
*
|
||||
* These setters are convenience wrappers around `setNotificationHandler()`.
|
||||
* Both patterns work; use whichever fits your coding style better.
|
||||
|
|
@ -293,7 +293,7 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
|
|||
* Get the host context discovered during initialization.
|
||||
*
|
||||
* Returns the host context that was provided in the initialization response,
|
||||
* including tool info, theme, viewport, locale, and other environment details.
|
||||
* including tool info, theme, locale, and other environment details.
|
||||
* This context is automatically updated when the host sends
|
||||
* `ui/notifications/host-context-changed` notifications.
|
||||
*
|
||||
|
|
@ -478,12 +478,12 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Convenience handler for host context changes (theme, viewport, locale, etc.).
|
||||
* Convenience handler for host context changes (theme, locale, etc.).
|
||||
*
|
||||
* Set this property to register a handler that will be called when the host's
|
||||
* context changes, such as theme switching (light/dark), viewport size changes,
|
||||
* locale changes, or other environmental updates. Apps should respond by
|
||||
* updating their UI accordingly.
|
||||
* context changes, such as theme switching (light/dark), locale changes, or
|
||||
* other environmental updates. Apps should respond by updating their UI
|
||||
* accordingly.
|
||||
*
|
||||
* This setter is a convenience wrapper around `setNotificationHandler()` that
|
||||
* automatically handles the notification schema and extracts the params for you.
|
||||
|
|
|
|||
273
src/generated/schema.json
generated
273
src/generated/schema.json
generated
|
|
@ -330,6 +330,10 @@
|
|||
"type": "string",
|
||||
"const": "--color-text-inverse"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"const": "--color-text-ghost"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"const": "--color-text-info"
|
||||
|
|
@ -628,29 +632,70 @@
|
|||
"type": "string"
|
||||
}
|
||||
},
|
||||
"viewport": {
|
||||
"description": "Current and maximum dimensions available to the UI.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"width": {
|
||||
"description": "Current viewport width in pixels.",
|
||||
"type": "number"
|
||||
"containerDimensions": {
|
||||
"description": "Container dimensions. Represents the dimensions of the iframe or other\ncontainer holding the app. Specify either width or maxWidth, and either height or maxHeight.",
|
||||
"allOf": [
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"height": {
|
||||
"description": "Fixed container height in pixels.",
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["height"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"maxHeight": {
|
||||
"description": "Maximum container height in pixels.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"height": {
|
||||
"description": "Current viewport height in pixels.",
|
||||
"type": "number"
|
||||
},
|
||||
"maxHeight": {
|
||||
"description": "Maximum available height in pixels (if constrained).",
|
||||
"type": "number"
|
||||
},
|
||||
"maxWidth": {
|
||||
"description": "Maximum available width in pixels (if constrained).",
|
||||
"type": "number"
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"width": {
|
||||
"description": "Fixed container width in pixels.",
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["width"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"maxWidth": {
|
||||
"description": "Maximum container width in pixels.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["width", "height"],
|
||||
"additionalProperties": false
|
||||
]
|
||||
},
|
||||
"locale": {
|
||||
"description": "User's language and region preference in BCP 47 format.",
|
||||
|
|
@ -956,6 +1001,10 @@
|
|||
"type": "string",
|
||||
"const": "--color-text-inverse"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"const": "--color-text-ghost"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"const": "--color-text-info"
|
||||
|
|
@ -1254,29 +1303,70 @@
|
|||
"type": "string"
|
||||
}
|
||||
},
|
||||
"viewport": {
|
||||
"description": "Current and maximum dimensions available to the UI.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"width": {
|
||||
"description": "Current viewport width in pixels.",
|
||||
"type": "number"
|
||||
"containerDimensions": {
|
||||
"description": "Container dimensions. Represents the dimensions of the iframe or other\ncontainer holding the app. Specify either width or maxWidth, and either height or maxHeight.",
|
||||
"allOf": [
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"height": {
|
||||
"description": "Fixed container height in pixels.",
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["height"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"maxHeight": {
|
||||
"description": "Maximum container height in pixels.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"height": {
|
||||
"description": "Current viewport height in pixels.",
|
||||
"type": "number"
|
||||
},
|
||||
"maxHeight": {
|
||||
"description": "Maximum available height in pixels (if constrained).",
|
||||
"type": "number"
|
||||
},
|
||||
"maxWidth": {
|
||||
"description": "Maximum available width in pixels (if constrained).",
|
||||
"type": "number"
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"width": {
|
||||
"description": "Fixed container width in pixels.",
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["width"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"maxWidth": {
|
||||
"description": "Maximum container width in pixels.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["width", "height"],
|
||||
"additionalProperties": false
|
||||
]
|
||||
},
|
||||
"locale": {
|
||||
"description": "User's language and region preference in BCP 47 format.",
|
||||
|
|
@ -1426,6 +1516,10 @@
|
|||
"type": "string",
|
||||
"const": "--color-text-inverse"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"const": "--color-text-ghost"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"const": "--color-text-info"
|
||||
|
|
@ -2115,6 +2209,10 @@
|
|||
"type": "string",
|
||||
"const": "--color-text-inverse"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"const": "--color-text-ghost"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"const": "--color-text-info"
|
||||
|
|
@ -2413,29 +2511,70 @@
|
|||
"type": "string"
|
||||
}
|
||||
},
|
||||
"viewport": {
|
||||
"description": "Current and maximum dimensions available to the UI.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"width": {
|
||||
"description": "Current viewport width in pixels.",
|
||||
"type": "number"
|
||||
"containerDimensions": {
|
||||
"description": "Container dimensions. Represents the dimensions of the iframe or other\ncontainer holding the app. Specify either width or maxWidth, and either height or maxHeight.",
|
||||
"allOf": [
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"height": {
|
||||
"description": "Fixed container height in pixels.",
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["height"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"maxHeight": {
|
||||
"description": "Maximum container height in pixels.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"height": {
|
||||
"description": "Current viewport height in pixels.",
|
||||
"type": "number"
|
||||
},
|
||||
"maxHeight": {
|
||||
"description": "Maximum available height in pixels (if constrained).",
|
||||
"type": "number"
|
||||
},
|
||||
"maxWidth": {
|
||||
"description": "Maximum available width in pixels (if constrained).",
|
||||
"type": "number"
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"width": {
|
||||
"description": "Fixed container width in pixels.",
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["width"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"maxWidth": {
|
||||
"description": "Maximum container width in pixels.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["width", "height"],
|
||||
"additionalProperties": false
|
||||
]
|
||||
},
|
||||
"locale": {
|
||||
"description": "User's language and region preference in BCP 47 format.",
|
||||
|
|
@ -3210,6 +3349,10 @@
|
|||
"type": "string",
|
||||
"const": "--color-text-inverse"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"const": "--color-text-ghost"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"const": "--color-text-info"
|
||||
|
|
@ -3523,6 +3666,10 @@
|
|||
"type": "string",
|
||||
"const": "--color-text-inverse"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"const": "--color-text-ghost"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"const": "--color-text-info"
|
||||
|
|
|
|||
56
src/generated/schema.ts
generated
56
src/generated/schema.ts
generated
|
|
@ -43,6 +43,7 @@ export const McpUiStyleVariableKeySchema = z
|
|||
z.literal("--color-text-secondary"),
|
||||
z.literal("--color-text-tertiary"),
|
||||
z.literal("--color-text-inverse"),
|
||||
z.literal("--color-text-ghost"),
|
||||
z.literal("--color-text-info"),
|
||||
z.literal("--color-text-danger"),
|
||||
z.literal("--color-text-success"),
|
||||
|
|
@ -563,26 +564,43 @@ export const McpUiHostContextSchema = z
|
|||
.array(z.string())
|
||||
.optional()
|
||||
.describe("Display modes the host supports."),
|
||||
/** @description Current and maximum dimensions available to the UI. */
|
||||
viewport: z
|
||||
.object({
|
||||
/** @description Current viewport width in pixels. */
|
||||
width: z.number().describe("Current viewport width in pixels."),
|
||||
/** @description Current viewport height in pixels. */
|
||||
height: z.number().describe("Current viewport height in pixels."),
|
||||
/** @description Maximum available height in pixels (if constrained). */
|
||||
maxHeight: z
|
||||
.number()
|
||||
.optional()
|
||||
.describe("Maximum available height in pixels (if constrained)."),
|
||||
/** @description Maximum available width in pixels (if constrained). */
|
||||
maxWidth: z
|
||||
.number()
|
||||
.optional()
|
||||
.describe("Maximum available width in pixels (if constrained)."),
|
||||
})
|
||||
/**
|
||||
* @description Container dimensions. Represents the dimensions of the iframe or other
|
||||
* container holding the app. Specify either width or maxWidth, and either height or maxHeight.
|
||||
*/
|
||||
containerDimensions: z
|
||||
.union([
|
||||
z.object({
|
||||
/** @description Fixed container height in pixels. */
|
||||
height: z.number().describe("Fixed container height in pixels."),
|
||||
}),
|
||||
z.object({
|
||||
/** @description Maximum container height in pixels. */
|
||||
maxHeight: z
|
||||
.union([z.number(), z.undefined()])
|
||||
.optional()
|
||||
.describe("Maximum container height in pixels."),
|
||||
}),
|
||||
])
|
||||
.and(
|
||||
z.union([
|
||||
z.object({
|
||||
/** @description Fixed container width in pixels. */
|
||||
width: z.number().describe("Fixed container width in pixels."),
|
||||
}),
|
||||
z.object({
|
||||
/** @description Maximum container width in pixels. */
|
||||
maxWidth: z
|
||||
.union([z.number(), z.undefined()])
|
||||
.optional()
|
||||
.describe("Maximum container width in pixels."),
|
||||
}),
|
||||
]),
|
||||
)
|
||||
.optional()
|
||||
.describe("Current and maximum dimensions available to the UI."),
|
||||
.describe(
|
||||
"Container dimensions. Represents the dimensions of the iframe or other\ncontainer holding the app. Specify either width or maxWidth, and either height or maxHeight.",
|
||||
),
|
||||
/** @description User's language and region preference in BCP 47 format. */
|
||||
locale: z
|
||||
.string()
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ export type McpUiStyleVariableKey =
|
|||
| "--color-text-secondary"
|
||||
| "--color-text-tertiary"
|
||||
| "--color-text-inverse"
|
||||
| "--color-text-ghost"
|
||||
| "--color-text-info"
|
||||
| "--color-text-danger"
|
||||
| "--color-text-success"
|
||||
|
|
@ -324,17 +325,30 @@ export interface McpUiHostContext {
|
|||
displayMode?: McpUiDisplayMode;
|
||||
/** @description Display modes the host supports. */
|
||||
availableDisplayModes?: string[];
|
||||
/** @description Current and maximum dimensions available to the UI. */
|
||||
viewport?: {
|
||||
/** @description Current viewport width in pixels. */
|
||||
width: number;
|
||||
/** @description Current viewport height in pixels. */
|
||||
height: number;
|
||||
/** @description Maximum available height in pixels (if constrained). */
|
||||
maxHeight?: number;
|
||||
/** @description Maximum available width in pixels (if constrained). */
|
||||
maxWidth?: number;
|
||||
};
|
||||
/**
|
||||
* @description Container dimensions. Represents the dimensions of the iframe or other
|
||||
* container holding the app. Specify either width or maxWidth, and either height or maxHeight.
|
||||
*/
|
||||
containerDimensions?: (
|
||||
| {
|
||||
/** @description Fixed container height in pixels. */
|
||||
height: number;
|
||||
}
|
||||
| {
|
||||
/** @description Maximum container height in pixels. */
|
||||
maxHeight?: number | undefined;
|
||||
}
|
||||
) &
|
||||
(
|
||||
| {
|
||||
/** @description Fixed container width in pixels. */
|
||||
width: number;
|
||||
}
|
||||
| {
|
||||
/** @description Maximum container width in pixels. */
|
||||
maxWidth?: number | undefined;
|
||||
}
|
||||
);
|
||||
/** @description User's language and region preference in BCP 47 format. */
|
||||
locale?: string;
|
||||
/** @description User's timezone in IANA format. */
|
||||
|
|
|
|||
Loading…
Reference in a new issue