modelcontextprotocol / modelcontextprotocol/kotlin-sdk
[Proposal] SEP-2133: Extensions framework architecture & integration design (#804)
Nobody has claimed this yet.
- Dominant language
- Kotlin
- Stars
- 1.5k
- Forks
- 248
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 23
Description
Proposal: SEP-2133 Extensions Framework Architecture & Integration Design (#804)
Motivation & Context
Tracking implementation of SEP-2133 in kotlin-sdk for the 2026-07-28 MCP specification release (aligned with umbrella issue #842).
As the MCP ecosystem grows, standard features such as MCP Apps (SEP-1865), Tasks (SEP-2663), and Enterprise Managed Authorization (SEP-990) are developed as official and third-party extensions. Without a standardized extension framework:
- Capability Fragmentation: SDKs had ad-hoc, inconsistent locations for experimental features in
ClientCapabilitiesandServerCapabilities. - Identifier Clashes: Without a unified naming scheme, third-party and community capabilities risked naming collisions with core protocol methods.
- Ergonomics & Modularity: Core SDK modules risked bloat if every domain extension had to be baked directly into
kotlin-sdk-core.
SEP-2133 establishes:
- Standard reverse-domain extension identifiers (e.g.,
io.modelcontextprotocol/tasks,io.modelcontextprotocol/apps). - Standard capability negotiation via the
extensionsfield inClientCapabilitiesandServerCapabilities. - Extensible dispatch for extension-defined JSON-RPC methods and notifications.
This proposal outlines the Kotlin Multiplatform architecture to implement the SEP-2133 Extensions Framework in kotlin-sdk (kotlin-sdk-core, kotlin-sdk-server, and kotlin-sdk-client).
Proposed Architecture & Component Design
1. Capability Negotiation & Data Models (kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/)
In schema.kt:
- Capabilities Enhancement:
Addextensionsmapping to bothClientCapabilitiesandServerCapabilities:@Serializable public data class ClientCapabilities( // ... existing core capabilities (roots, sampling, elicitation) val extensions: Map<String, JsonElement>? = null, @SerialName("_meta") override val meta: JsonObject? = null, ) : WithMeta @Serializable public data class ServerCapabilities( // ... existing core capabilities (logging, prompts, resources, tools) val extensions: Map<String, JsonElement>? = null, @SerialName("_meta") override val meta: JsonObject? = null, ) : WithMeta - Extension Identifier Validation:
Provide validation utility ensuring reverse-domain conventions (e.g. regex^[a-zA-Z0-9.-]+/[a-zA-Z0-9._-]+$):public fun isValidExtensionId(id: String): Boolean
2. Extension Abstraction & Plugin SPI (kotlin-sdk-core)
Define a modular Kotlin Multiplatform extension contract:
public interface McpExtension {
/** Reverse domain identifier, e.g. "io.modelcontextprotocol/tasks" */
public val id: String
/** Semantic version of the extension supported */
public val version: String
/** Parameters or feature sub-capabilities advertised during handshake */
public fun createCapabilityDescriptor(): JsonElement? = buildJsonObject {
put("version", version)
}
}
3. Extension Management on Sessions (kotlin-sdk-server & kotlin-sdk-client)
-
Server-Side Extension Registration & Method Routing:
InServerSession:public class ServerSession(...) { private val registeredExtensions = mutableMapOf<String, McpExtension>() private val extensionMethodHandlers = mutableMapOf<Method, suspend (JsonRPCRequest) -> JsonRPCResponse>() public fun registerExtension(extension: McpExtension) { registeredExtensions[extension.id] = extension } public fun registerExtensionMethod( method: String, handler: suspend (JsonRPCRequest) -> JsonRPCResponse ) { extensionMethodHandlers[Method.Custom(method)] = handler } }- Incoming requests with unknown methods are checked against registered extension method handlers before falling back to
MethodNotFound(-32601). - During the
initializehandshake, advertisedServerCapabilities.extensionsare automatically synthesized fromregisteredExtensions.
- Incoming requests with unknown methods are checked against registered extension method handlers before falling back to
-
Client-Side Negotiation & Inspection:
InClientSession:public class ClientSession(...) { public fun isExtensionSupportedByServer(extensionId: String): Boolean = serverCapabilities?.extensions?.containsKey(extensionId) == true public fun getServerExtensionMetadata(extensionId: String): JsonElement? = serverCapabilities?.extensions?.get(extensionId) }
4. Idiomatic Builder DSL (kotlin-sdk-client / kotlin-sdk-server)
Provide an idiomatic, modular DSL for installing extensions:
// Server builder
val server = McpServer {
install(TasksExtension) {
ttl = 3600_000L
}
install(McpAppsExtension)
}
// Client builder
val client = McpClient {
install(TasksExtension)
}
5. Testing & Verification Plan
- Unit Tests:
- Serialization / deserialization of
ClientCapabilitiesandServerCapabilitiescontainingextensions. - Extension handshake negotiation between client and server (verifying matching capability advertisement).
- Dispatching custom extension methods and error isolation.
- Backward compatibility: ensure connecting to legacy servers lacking
extensionshandles gracefully withnullsafety.
- Serialization / deserialization of
- Conformance Suite:
- Verify capability negotiation conformance tests across supported SDK fixtures.
Next Steps
Upon review and consensus on the extension framework design:
- Add
extensionsfield toClientCapabilitiesandServerCapabilitiesinkotlin-sdk-core. - Implement
McpExtensioninterface and session registration plumbing. - Update server request dispatcher to support dynamically routed extension methods.
- Add unit test suite for capability negotiation.
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 kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/schema.kt and the existing ClientCapabilities and ServerCapabilities models. Then inspect ServerSession and ClientSession to understand handshake and request dispatch behavior. Done means the proposed extension negotiation, registration, routing, DSL, and unit or conformance tests are agreed and implemented across the named 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
- 30/100