feat(server): add getUiCapability helper for capability negotiation (#313)

* feat(server): add hasUiSupport/getUiCapability for experimental+extensions

Support double-tagging for MCP Apps capability negotiation:
- Check both experimental and extensions fields in client capabilities
- Add hasUiSupport() to easily check if client supports MCP Apps
- Add getUiCapability() to retrieve the capability settings
- Update spec to document both capability locations

This enables forward compatibility as MCP transitions from experimental
to the extensions field (SEP-1724).

Claude-Generated-By: Claude Code (cli/claude-opus-4-5=100%)
Claude-Steers: 0
Claude-Permission-Prompts: 0
Claude-Escapes: 0

* fix: update @types/node version in package-lock.json

Replace invalid 22.19.5/22.19.6/22.19.7 versions with valid 22.19.3

* docs(spec): clarify hosts SHOULD double-tag, servers SHOULD check both

- Hosts SHOULD advertise capabilities in both experimental and extensions
- Servers SHOULD check both locations, preferring extensions when present
- Updated example to show double-tagging pattern

* chore: remove double-tagging recommendation, keep hasUiSupport helper

Reverts the spec changes that recommended clients double-tag capabilities
in both experimental and extensions fields. The helper functions remain
as they're useful for checking capability in either location.

* refactor(server): simplify to only getUiCapability, remove hasUiSupport

- Remove hasUiSupport function (use getUiCapability directly)
- Remove double-tagging logic (only check extensions field)
- Add ClientCapabilitiesWithExtensions type using SDK's ClientCapabilities
- Update spec to use getUiCapability
- Simplify tests

* fix: update @see link to getUiCapability

* refactor(server): inline ClientCapabilitiesWithExtensions type in getUiCapability

* refactor: move McpUiClientCapabilities to spec.types.ts
This commit is contained in:
Olivier Chafik 2026-01-23 16:26:49 +00:00 • committed by GitHub
commit cfcbc9605f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 238 additions and 73 deletions

View file

@ -28,6 +28,20 @@
},
"additionalProperties": false
},
"McpUiClientCapabilities": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"mimeTypes": {
"description": "Array of supported MIME types for UI resources.\nMust include `\"text/html;profile=mcp-app\"` for MCP Apps support.",
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": false
},
"McpUiDisplayMode": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"anyOf": [

View file

@ -119,6 +119,10 @@ export type McpUiToolMetaSchemaInferredType = z.infer<
typeof generated.McpUiToolMetaSchema
>;
export type McpUiClientCapabilitiesSchemaInferredType = z.infer<
typeof generated.McpUiClientCapabilitiesSchema
>;
export type McpUiMessageRequestSchemaInferredType = z.infer<
typeof generated.McpUiMessageRequestSchema
>;
@ -277,6 +281,12 @@ expectType<McpUiToolVisibilitySchemaInferredType>(
);
expectType<spec.McpUiToolMeta>({} as McpUiToolMetaSchemaInferredType);
expectType<McpUiToolMetaSchemaInferredType>({} as spec.McpUiToolMeta);
expectType<spec.McpUiClientCapabilities>(
{} as McpUiClientCapabilitiesSchemaInferredType,
);
expectType<McpUiClientCapabilitiesSchemaInferredType>(
{} as spec.McpUiClientCapabilities,
);
expectType<spec.McpUiMessageRequest>(
{} as McpUiMessageRequestSchemaInferredType,
);

View file

@ -562,6 +562,26 @@ export const McpUiToolMetaSchema = z.object({
),
});
/**
* @description MCP Apps capability settings advertised by clients to servers.
*
* Clients advertise these capabilities via the `extensions` field in their
* capabilities during MCP initialization. Servers can check for MCP Apps
* support using {@link server-helpers!getUiCapability}.
*/
export const McpUiClientCapabilitiesSchema = z.object({
/**
* @description Array of supported MIME types for UI resources.
* Must include `"text/html;profile=mcp-app"` for MCP Apps support.
*/
mimeTypes: z
.array(z.string())
.optional()
.describe(
'Array of supported MIME types for UI resources.\nMust include `"text/html;profile=mcp-app"` for MCP Apps support.',
),
});
/**
* @description Request to send a message to the host's chat interface.
* @see {@link app!App.sendMessage `App.sendMessage`} for the method that sends this request