Proposal: SEP-1865 MCP Apps (Interactive User Interfaces) Architecture & SDK Integration Design (#802)
Motivation & Context
Tracking implementation of SEP-1865 in kotlin-sdk for the 2026-07-28 MCP specification release (aligned with umbrella issue #842).
As conversational AI systems and agentic hosts evolve, plain-text and markdown responses are insufficient for workflows requiring interactive visual feedback, form rendering, interactive charts, and dashboard state visualization.
SEP-1865 standardizes MCP Apps as an official extension under the SEP-2133 Extensions Framework:
- Predeclared UI Resources: Declared through the
ui:// URI scheme with mime-type text/html;profile=mcp-app. Predeclaring templates allows hosts to prefetch, cache, and audit visual templates prior to runtime tool execution.
- Tool-to-UI Association: Tools bind to their visual interfaces through standardized metadata (
_meta["ui"]), linking execution output to interactive displays.
- Bi-directional Communication: The UI sandboxed iframe communicates with the host using standard JSON-RPC, reusing existing MCP protocol primitives for tool invocations, prompts, and updates.
- Security & Auditability: Mandatory iframe sandboxing, origin isolation, and user approval gates for UI-initiated actions.
This proposal outlines the Kotlin Multiplatform architecture to implement SEP-1865 across kotlin-sdk-core, kotlin-sdk-server, and kotlin-sdk-client.
Proposed Architecture & Component Design
1. Capability Negotiation & Constants (kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/)
- Extension Identifier & MIME Types:
public object McpAppsExtension {
public const val EXTENSION_ID: String = "io.modelcontextprotocol/apps"
public const val EXTENSION_VERSION: String = "1.0.0"
public const val UI_URI_SCHEME: String = "ui"
public const val MCP_APP_MIME_TYPE: String = "text/html;profile=mcp-app"
public const val UI_META_KEY: String = "ui"
}
- Apps Capability Descriptor:
@Serializable
public data class AppsCapabilities(
val formats: List<String> = listOf(McpAppsExtension.MCP_APP_MIME_TYPE),
val externalIframes: Boolean = false,
)
Advertised under ClientCapabilities.extensions[McpAppsExtension.EXTENSION_ID] and ServerCapabilities.extensions[McpAppsExtension.EXTENSION_ID].
2. Data Models & Metadata DSL (kotlin-sdk-core & kotlin-sdk-server)
- Tool UI Binding Metadata:
In types/tools.kt and types/resources.kt:
@Serializable
public data class ToolUiMetadata(
val resourceUri: String, // e.g. "ui://charts/stock-view"
val preferredDisplay: String? = null, // "inline" | "sidecar" | "modal"
val autoRender: Boolean = true,
)
- Ergonomic Server Tool Registration DSL:
// Registering a UI-bound tool
server.addTool(
name = "query_metrics",
description = "Retrieves and displays service metrics",
ui = ToolUiMetadata("ui://metrics/dashboard")
) { params ->
// Standard tool execution returning data
CallToolResult(
content = listOf(
TextContent("Metrics retrieved successfully"),
EmbeddedDataContent(jsonResult)
)
)
}
// Predeclaring the matching UI resource
server.addUiResource(
uri = "ui://metrics/dashboard",
name = "Service Metrics Dashboard",
htmlContent = loadResourceTemplate("dashboard.html")
)
3. UI Resource Registration & Serving (kotlin-sdk-server)
- In
ServerSession:
- Helper extension
addUiResource(uri, name, htmlContent, description) that registers an underlying Resource with mimeType = McpAppsExtension.MCP_APP_MIME_TYPE.
- Validates that the URI conforms strictly to the
ui:// scheme.
- Exposes
resources/read handlers that serve the HTML template directly to client hosts.
4. Client Host UI Integration Plumbing (kotlin-sdk-client)
- UI Resource Resolver:
Provide client utilities to resolve and inspect UI-enabled tools:
public suspend fun ClientSession.getToolUiResource(tool: Tool): ResourceContents? {
val uiUri = tool.meta?.get(McpAppsExtension.UI_META_KEY)
?.jsonObject?.get("resourceUri")?.jsonPrimitive?.contentOrNull ?: return null
val readResult = this.readResource(ReadResourceRequestParams(uri = uiUri))
return readResult.contents.firstOrNull()
}
- Sandboxed Message Bridge:
Provide an interface for hosts embedding WebView / iframe environments (e.g. desktop Compose Multiplatform, Android WebView, or browser JS) to pipe JSON-RPC messages between the sandboxed UI and ClientSession.
5. Testing & Verification Plan
- Unit Tests (
kotlin-sdk-core):
- Serialization and metadata extraction of
ToolUiMetadata in Tool definitions.
- Validation of
ui:// URI schemes and MIME type enforcement.
- Integration Tests (
kotlin-sdk-server & kotlin-sdk-client):
- Register a UI resource and an associated tool.
- Client retrieves tool catalog via
tools/list, detects UI binding, fetches the UI template via resources/read, and executes tools/call.
- Conformance Scenarios:
- Validate against the MCP Apps test scenarios in
modelcontextprotocol/conformance and ext-apps reference suite.
Next Steps
Upon review and consensus on the MCP Apps integration:
- Land
McpAppsExtension constants and ToolUiMetadata in kotlin-sdk-core.
- Add
addUiResource and UI-binding DSL helpers in kotlin-sdk-server.
- Provide client-side template resolution helpers in
kotlin-sdk-client.
- Add sample project demonstrating Compose Multiplatform / WebView hosting of MCP Apps.
AI assistance disclosure: AI was used to discover this opportunity and draft the change or text. The submission was checked against the prepared artifact and recorded verification evidence.
Proposal: SEP-1865 MCP Apps (Interactive User Interfaces) Architecture & SDK Integration Design (#802)
Motivation & Context
Tracking implementation of SEP-1865 in
kotlin-sdkfor the 2026-07-28 MCP specification release (aligned with umbrella issue #842).As conversational AI systems and agentic hosts evolve, plain-text and markdown responses are insufficient for workflows requiring interactive visual feedback, form rendering, interactive charts, and dashboard state visualization.
SEP-1865 standardizes MCP Apps as an official extension under the SEP-2133 Extensions Framework:
ui://URI scheme with mime-typetext/html;profile=mcp-app. Predeclaring templates allows hosts to prefetch, cache, and audit visual templates prior to runtime tool execution._meta["ui"]), linking execution output to interactive displays.This proposal outlines the Kotlin Multiplatform architecture to implement SEP-1865 across
kotlin-sdk-core,kotlin-sdk-server, andkotlin-sdk-client.Proposed Architecture & Component Design
1. Capability Negotiation & Constants (
kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/)ClientCapabilities.extensions[McpAppsExtension.EXTENSION_ID]andServerCapabilities.extensions[McpAppsExtension.EXTENSION_ID].2. Data Models & Metadata DSL (
kotlin-sdk-core&kotlin-sdk-server)In
types/tools.ktandtypes/resources.kt:3. UI Resource Registration & Serving (
kotlin-sdk-server)ServerSession:addUiResource(uri, name, htmlContent, description)that registers an underlyingResourcewithmimeType = McpAppsExtension.MCP_APP_MIME_TYPE.ui://scheme.resources/readhandlers that serve the HTML template directly to client hosts.4. Client Host UI Integration Plumbing (
kotlin-sdk-client)Provide client utilities to resolve and inspect UI-enabled tools:
Provide an interface for hosts embedding WebView / iframe environments (e.g. desktop Compose Multiplatform, Android WebView, or browser JS) to pipe JSON-RPC messages between the sandboxed UI and
ClientSession.5. Testing & Verification Plan
kotlin-sdk-core):ToolUiMetadatainTooldefinitions.ui://URI schemes and MIME type enforcement.kotlin-sdk-server&kotlin-sdk-client):tools/list, detects UI binding, fetches the UI template viaresources/read, and executestools/call.modelcontextprotocol/conformanceandext-appsreference suite.Next Steps
Upon review and consensus on the MCP Apps integration:
McpAppsExtensionconstants andToolUiMetadatainkotlin-sdk-core.addUiResourceand UI-binding DSL helpers inkotlin-sdk-server.kotlin-sdk-client.