modelcontextprotocol / modelcontextprotocol/kotlin-sdk
[Proposal] SEP-1865: MCP Apps (Interactive User Interfaces) architecture & SDK integration design (#802)
Nobody has claimed this yet.
- Dominant language
- Kotlin
- Stars
- 1.5k
- Forks
- 248
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 23
Description
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-typetext/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:
Advertised under@Serializable public data class AppsCapabilities( val formats: List<String> = listOf(McpAppsExtension.MCP_APP_MIME_TYPE), val externalIframes: Boolean = false, )ClientCapabilities.extensions[McpAppsExtension.EXTENSION_ID]andServerCapabilities.extensions[McpAppsExtension.EXTENSION_ID].
2. Data Models & Metadata DSL (kotlin-sdk-core & kotlin-sdk-server)
- Tool UI Binding Metadata:
Intypes/tools.ktandtypes/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 underlyingResourcewithmimeType = McpAppsExtension.MCP_APP_MIME_TYPE. - Validates that the URI conforms strictly to the
ui://scheme. - Exposes
resources/readhandlers that serve the HTML template directly to client hosts.
- Helper extension
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 andClientSession.
5. Testing & Verification Plan
- Unit Tests (
kotlin-sdk-core):- Serialization and metadata extraction of
ToolUiMetadatainTooldefinitions. - Validation of
ui://URI schemes and MIME type enforcement.
- Serialization and metadata extraction of
- 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 viaresources/read, and executestools/call.
- Conformance Scenarios:
- Validate against the MCP Apps test scenarios in
modelcontextprotocol/conformanceandext-appsreference suite.
- Validate against the MCP Apps test scenarios in
Next Steps
Upon review and consensus on the MCP Apps integration:
- Land
McpAppsExtensionconstants andToolUiMetadatainkotlin-sdk-core. - Add
addUiResourceand UI-binding DSL helpers inkotlin-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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the existing types in kotlin-sdk-core, especially the tools.kt and resources.kt areas, along with the server and client session entry points named in the proposal. Then examine the planned core unit tests and server/client integration tests. Done means the architecture is agreed and the capability, resource, tool-binding, client-resolution, and verification work is implemented across the listed modules.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- kotlin
- Domain
- api, backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100