fix: preserve experimental capability settings (#721)

This commit is contained in:
victor-openai 2026-07-22 09:28:57 -07:00 • committed by GitHub
commit c55a3a231f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 81 additions and 27 deletions

View file

@ -548,8 +548,8 @@ When the View sends an `ui/initialize` request to the Host, it MUST include its
```typescript ```typescript
interface McpUiAppCapabilities { interface McpUiAppCapabilities {
/** Experimental features (structure TBD). */ /** Experimental features keyed by identifier. */
experimental?: {}; experimental?: Record<string, object>;
/** App exposes MCP-style tools that the host can call. */ /** App exposes MCP-style tools that the host can call. */
tools?: { tools?: {
/** App supports tools/list_changed notifications. */ /** App supports tools/list_changed notifications. */
@ -677,8 +677,8 @@ interface SupportedContentBlockModalities {
} }
interface HostCapabilities { interface HostCapabilities {
/** Experimental features (structure TBD). */ /** Experimental features keyed by identifier. */
experimental?: {}; experimental?: Record<string, object>;
/** Host supports opening external URLs. */ /** Host supports opening external URLs. */
openLinks?: {}; openLinks?: {};
/** Host supports file downloads via ui/download-file. */ /** Host supports file downloads via ui/download-file. */

View file

@ -45,6 +45,9 @@ function createMockClient(
const testHostInfo = { name: "TestHost", version: "1.0.0" }; const testHostInfo = { name: "TestHost", version: "1.0.0" };
const testAppInfo = { name: "TestApp", version: "1.0.0" }; const testAppInfo = { name: "TestApp", version: "1.0.0" };
const testHostCapabilities: McpUiHostCapabilities = { const testHostCapabilities: McpUiHostCapabilities = {
experimental: {
"com.example/host-extension": { version: 1 },
},
openLinks: {}, openLinks: {},
serverTools: {}, serverTools: {},
logging: {}, logging: {},
@ -97,7 +100,12 @@ describe("App <-> AppBridge integration", () => {
}); });
it("Bridge receives app info and capabilities after initialization", async () => { it("Bridge receives app info and capabilities after initialization", async () => {
const appCapabilities = { tools: { listChanged: true } }; const appCapabilities = {
experimental: {
"com.example/app-extension": { version: 1 },
},
tools: { listChanged: true },
};
app = new App(testAppInfo, appCapabilities, { autoResize: false }); app = new App(testAppInfo, appCapabilities, { autoResize: false });
await bridge.connect(bridgeTransport); await bridge.connect(bridgeTransport);

View file

@ -9,10 +9,19 @@
"type": "object", "type": "object",
"properties": { "properties": {
"experimental": { "experimental": {
"description": "Experimental features (structure TBD).", "description": "Experimental features keyed by identifier.",
"type": "object", "type": "object",
"properties": {}, "propertyNames": {
"additionalProperties": false "type": "string"
},
"additionalProperties": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {},
"description": "Experimental features keyed by identifier."
}
}, },
"tools": { "tools": {
"description": "App exposes MCP-style tools that the host can call.", "description": "App exposes MCP-style tools that the host can call.",
@ -298,10 +307,19 @@
"type": "object", "type": "object",
"properties": { "properties": {
"experimental": { "experimental": {
"description": "Experimental features (structure TBD).", "description": "Experimental features keyed by identifier.",
"type": "object", "type": "object",
"properties": {}, "propertyNames": {
"additionalProperties": false "type": "string"
},
"additionalProperties": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {},
"description": "Experimental features keyed by identifier."
}
}, },
"openLinks": { "openLinks": {
"description": "Host supports opening external URLs.", "description": "Host supports opening external URLs.",
@ -2537,10 +2555,19 @@
"type": "object", "type": "object",
"properties": { "properties": {
"experimental": { "experimental": {
"description": "Experimental features (structure TBD).", "description": "Experimental features keyed by identifier.",
"type": "object", "type": "object",
"properties": {}, "propertyNames": {
"additionalProperties": false "type": "string"
},
"additionalProperties": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {},
"description": "Experimental features keyed by identifier."
}
}, },
"tools": { "tools": {
"description": "App exposes MCP-style tools that the host can call.", "description": "App exposes MCP-style tools that the host can call.",
@ -2651,10 +2678,19 @@
"type": "object", "type": "object",
"properties": { "properties": {
"experimental": { "experimental": {
"description": "Experimental features (structure TBD).", "description": "Experimental features keyed by identifier.",
"type": "object", "type": "object",
"properties": {}, "propertyNames": {
"additionalProperties": false "type": "string"
},
"additionalProperties": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {},
"description": "Experimental features keyed by identifier."
}
}, },
"openLinks": { "openLinks": {
"description": "Host supports opening external URLs.", "description": "Host supports opening external URLs.",

View file

@ -496,11 +496,16 @@ export const McpUiRequestTeardownNotificationSchema = z.object({
* @see {@link McpUiInitializeResult `McpUiInitializeResult`} for the initialization result that includes these capabilities * @see {@link McpUiInitializeResult `McpUiInitializeResult`} for the initialization result that includes these capabilities
*/ */
export const McpUiHostCapabilitiesSchema = z.object({ export const McpUiHostCapabilitiesSchema = z.object({
/** @description Experimental features (structure TBD). */ /** @description Experimental features keyed by identifier. */
experimental: z experimental: z
.object({}) .record(
z.string(),
z
.record(z.string(), z.any())
.describe("Experimental features keyed by identifier."),
)
.optional() .optional()
.describe("Experimental features (structure TBD)."), .describe("Experimental features keyed by identifier."),
/** @description Host supports opening external URLs. */ /** @description Host supports opening external URLs. */
openLinks: z openLinks: z
.object({}) .object({})
@ -583,11 +588,16 @@ export const McpUiHostCapabilitiesSchema = z.object({
* @see {@link McpUiInitializeRequest `McpUiInitializeRequest`} for the initialization request that includes these capabilities * @see {@link McpUiInitializeRequest `McpUiInitializeRequest`} for the initialization request that includes these capabilities
*/ */
export const McpUiAppCapabilitiesSchema = z.object({ export const McpUiAppCapabilitiesSchema = z.object({
/** @description Experimental features (structure TBD). */ /** @description Experimental features keyed by identifier. */
experimental: z experimental: z
.object({}) .record(
z.string(),
z
.record(z.string(), z.any())
.describe("Experimental features keyed by identifier."),
)
.optional() .optional()
.describe("Experimental features (structure TBD)."), .describe("Experimental features keyed by identifier."),
/** @description App exposes MCP-style tools that the host can call. */ /** @description App exposes MCP-style tools that the host can call. */
tools: z tools: z
.object({ .object({

View file

@ -492,8 +492,8 @@ export interface McpUiRequestTeardownNotification {
* @see {@link McpUiInitializeResult `McpUiInitializeResult`} for the initialization result that includes these capabilities * @see {@link McpUiInitializeResult `McpUiInitializeResult`} for the initialization result that includes these capabilities
*/ */
export interface McpUiHostCapabilities { export interface McpUiHostCapabilities {
/** @description Experimental features (structure TBD). */ /** @description Experimental features keyed by identifier. */
experimental?: {}; experimental?: Record<string, object>;
/** @description Host supports opening external URLs. */ /** @description Host supports opening external URLs. */
openLinks?: {}; openLinks?: {};
/** @description Host supports file downloads via ui/download-file. */ /** @description Host supports file downloads via ui/download-file. */
@ -536,8 +536,8 @@ export interface McpUiHostCapabilities {
* @see {@link McpUiInitializeRequest `McpUiInitializeRequest`} for the initialization request that includes these capabilities * @see {@link McpUiInitializeRequest `McpUiInitializeRequest`} for the initialization request that includes these capabilities
*/ */
export interface McpUiAppCapabilities { export interface McpUiAppCapabilities {
/** @description Experimental features (structure TBD). */ /** @description Experimental features keyed by identifier. */
experimental?: {}; experimental?: Record<string, object>;
/** @description App exposes MCP-style tools that the host can call. */ /** @description App exposes MCP-style tools that the host can call. */
tools?: { tools?: {
/** @description App supports tools/list_changed notifications. */ /** @description App supports tools/list_changed notifications. */