diff --git a/kotlin-sdk-core/api/kotlin-sdk-core.api b/kotlin-sdk-core/api/kotlin-sdk-core.api index 679b68d2..b6fe9422 100644 --- a/kotlin-sdk-core/api/kotlin-sdk-core.api +++ b/kotlin-sdk-core/api/kotlin-sdk-core.api @@ -606,17 +606,19 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/CancelledNotificatio public final class io/modelcontextprotocol/kotlin/sdk/types/ClientCapabilities { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/ClientCapabilities$Companion; public fun ()V - public fun (Lkotlinx/serialization/json/JsonObject;Lio/modelcontextprotocol/kotlin/sdk/types/ClientCapabilities$Roots;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;)V - public synthetic fun (Lkotlinx/serialization/json/JsonObject;Lio/modelcontextprotocol/kotlin/sdk/types/ClientCapabilities$Roots;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lkotlinx/serialization/json/JsonObject;Lio/modelcontextprotocol/kotlin/sdk/types/ClientCapabilities$Roots;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;Ljava/util/Map;)V + public synthetic fun (Lkotlinx/serialization/json/JsonObject;Lio/modelcontextprotocol/kotlin/sdk/types/ClientCapabilities$Roots;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;Ljava/util/Map;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Lkotlinx/serialization/json/JsonObject; public final fun component2 ()Lio/modelcontextprotocol/kotlin/sdk/types/ClientCapabilities$Roots; public final fun component3 ()Lkotlinx/serialization/json/JsonObject; public final fun component4 ()Lkotlinx/serialization/json/JsonObject; - public final fun copy (Lkotlinx/serialization/json/JsonObject;Lio/modelcontextprotocol/kotlin/sdk/types/ClientCapabilities$Roots;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;)Lio/modelcontextprotocol/kotlin/sdk/types/ClientCapabilities; - public static synthetic fun copy$default (Lio/modelcontextprotocol/kotlin/sdk/types/ClientCapabilities;Lkotlinx/serialization/json/JsonObject;Lio/modelcontextprotocol/kotlin/sdk/types/ClientCapabilities$Roots;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;ILjava/lang/Object;)Lio/modelcontextprotocol/kotlin/sdk/types/ClientCapabilities; + public final fun component5 ()Ljava/util/Map; + public final fun copy (Lkotlinx/serialization/json/JsonObject;Lio/modelcontextprotocol/kotlin/sdk/types/ClientCapabilities$Roots;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;Ljava/util/Map;)Lio/modelcontextprotocol/kotlin/sdk/types/ClientCapabilities; + public static synthetic fun copy$default (Lio/modelcontextprotocol/kotlin/sdk/types/ClientCapabilities;Lkotlinx/serialization/json/JsonObject;Lio/modelcontextprotocol/kotlin/sdk/types/ClientCapabilities$Roots;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;Ljava/util/Map;ILjava/lang/Object;)Lio/modelcontextprotocol/kotlin/sdk/types/ClientCapabilities; public fun equals (Ljava/lang/Object;)Z public final fun getElicitation ()Lkotlinx/serialization/json/JsonObject; public final fun getExperimental ()Lkotlinx/serialization/json/JsonObject; + public final fun getExtensions ()Ljava/util/Map; public final fun getRoots ()Lio/modelcontextprotocol/kotlin/sdk/types/ClientCapabilities$Roots; public final fun getSampling ()Lkotlinx/serialization/json/JsonObject; public fun hashCode ()I @@ -676,6 +678,7 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/ClientCapabilitiesBu public final fun elicitation (Lkotlinx/serialization/json/JsonObject;)V public final fun experimental (Lkotlin/jvm/functions/Function1;)V public final fun experimental (Lkotlinx/serialization/json/JsonObject;)V + public final fun extensions (Ljava/util/Map;)V public final fun roots (Ljava/lang/Boolean;)V public static synthetic fun roots$default (Lio/modelcontextprotocol/kotlin/sdk/types/ClientCapabilitiesBuilder;Ljava/lang/Boolean;ILjava/lang/Object;)V public final fun sampling (Lkotlin/jvm/functions/Function1;)V @@ -4245,19 +4248,21 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/Sampling_dslKt { public final class io/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Companion; public fun ()V - public fun (Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Tools;Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Resources;Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Prompts;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;)V - public synthetic fun (Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Tools;Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Resources;Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Prompts;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Tools;Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Resources;Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Prompts;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;Ljava/util/Map;)V + public synthetic fun (Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Tools;Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Resources;Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Prompts;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;Ljava/util/Map;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Tools; public final fun component2 ()Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Resources; public final fun component3 ()Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Prompts; public final fun component4 ()Lkotlinx/serialization/json/JsonObject; public final fun component5 ()Lkotlinx/serialization/json/JsonObject; public final fun component6 ()Lkotlinx/serialization/json/JsonObject; - public final fun copy (Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Tools;Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Resources;Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Prompts;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;)Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities; - public static synthetic fun copy$default (Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities;Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Tools;Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Resources;Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Prompts;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;ILjava/lang/Object;)Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities; + public final fun component7 ()Ljava/util/Map; + public final fun copy (Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Tools;Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Resources;Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Prompts;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;Ljava/util/Map;)Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities; + public static synthetic fun copy$default (Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities;Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Tools;Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Resources;Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Prompts;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;Ljava/util/Map;ILjava/lang/Object;)Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities; public fun equals (Ljava/lang/Object;)Z public final fun getCompletions ()Lkotlinx/serialization/json/JsonObject; public final fun getExperimental ()Lkotlinx/serialization/json/JsonObject; + public final fun getExtensions ()Ljava/util/Map; public final fun getLogging ()Lkotlinx/serialization/json/JsonObject; public final fun getPrompts ()Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Prompts; public final fun getResources ()Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Resources; diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/capabilities.dsl.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/capabilities.dsl.kt index 146eabfb..d936381d 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/capabilities.dsl.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/capabilities.dsl.kt @@ -39,6 +39,7 @@ public class ClientCapabilitiesBuilder @PublishedApi internal constructor() { private var sampling: JsonObject? = null private var roots: ClientCapabilities.Roots? = null private var elicitation: JsonObject? = null + private var extensions: Map? = null private var experimental: JsonObject? = null /** @@ -132,6 +133,30 @@ public class ClientCapabilitiesBuilder @PublishedApi internal constructor() { */ public fun elicitation(block: JsonObjectBuilder.() -> Unit): Unit = elicitation(buildJsonObject(block)) + /** + * Defines extensions that the client supports. + * + * Extension identifiers use the format `{vendor-prefix}/{extension-name}`, + * e.g., `"io.modelcontextprotocol/ui"`. Each value is an extension-specific + * settings object; an empty [JsonObject] indicates no settings. + * + * Example: + * ```kotlin + * capabilities { + * extensions(mapOf( + * "io.modelcontextprotocol/ui" to buildJsonObject { + * put("mimeTypes", JsonArray(listOf(JsonPrimitive("text/html")))) + * } + * )) + * } + * ``` + * + * @param value The map of extension identifiers to their settings + */ + public fun extensions(value: Map) { + this.extensions = value + } + /** * Defines experimental, non-standard capabilities that the client supports. * @@ -177,6 +202,7 @@ public class ClientCapabilitiesBuilder @PublishedApi internal constructor() { sampling = sampling, roots = roots, elicitation = elicitation, + extensions = extensions, experimental = experimental, ) } diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/capabilities.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/capabilities.kt index fae24c31..14248fae 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/capabilities.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/capabilities.kt @@ -45,6 +45,9 @@ public data class Implementation( * @property elicitation Present if the client supports elicitation from the server. * @property experimental Experimental, non-standard capabilities that the client supports. * Keys are capability names, values are capability-specific configuration objects. + * @property extensions Optional extensions that the client supports. + * Keys are extension identifiers (e.g., `"io.modelcontextprotocol/ui"`), + * values are extension-specific settings objects. */ @Serializable public data class ClientCapabilities( @@ -52,6 +55,7 @@ public data class ClientCapabilities( public val roots: Roots? = null, public val elicitation: JsonObject? = null, public val experimental: JsonObject? = null, + public val extensions: Map? = null, ) { /** @@ -93,6 +97,9 @@ public data class ClientCapabilities( * @property completions Present if the server supports argument autocompletion suggestions. * Keys are capability names, values are capability-specific configuration objects. * @property experimental Experimental, non-standard capabilities that the server supports. + * @property extensions Optional extensions that the server supports. + * Keys are extension identifiers (e.g., `"io.modelcontextprotocol/ui"`), + * values are extension-specific settings objects. */ @Serializable public data class ServerCapabilities( @@ -102,6 +109,7 @@ public data class ServerCapabilities( val logging: JsonObject? = null, val completions: JsonObject? = null, val experimental: JsonObject? = null, + val extensions: Map? = null, ) { /** diff --git a/kotlin-sdk-core/src/commonTest/kotlin/io/modelcontextprotocol/kotlin/sdk/types/CapabilitiesTest.kt b/kotlin-sdk-core/src/commonTest/kotlin/io/modelcontextprotocol/kotlin/sdk/types/CapabilitiesTest.kt index 33d56537..171c249d 100644 --- a/kotlin-sdk-core/src/commonTest/kotlin/io/modelcontextprotocol/kotlin/sdk/types/CapabilitiesTest.kt +++ b/kotlin-sdk-core/src/commonTest/kotlin/io/modelcontextprotocol/kotlin/sdk/types/CapabilitiesTest.kt @@ -182,6 +182,53 @@ class CapabilitiesTest { ) } + @Test + fun `should serialize ClientCapabilities with extensions`() { + val extensions = mapOf( + "io.modelcontextprotocol/ui" to buildJsonObject { + put("mimeTypes", buildJsonObject { put("text/html", true) }) + }, + ) + val capabilities = ClientCapabilities( + extensions = extensions, + ) + verifySerialization( + capabilities, + McpJson, + """ + { + "extensions": { + "io.modelcontextprotocol/ui": { + "mimeTypes": { + "text/html": true + } + } + } + } + """.trimIndent(), + ) + } + + @Test + fun `should serialize ClientCapabilities with empty extensions settings`() { + val capabilities = ClientCapabilities( + extensions = mapOf( + "io.modelcontextprotocol/ui" to EmptyJsonObject, + ), + ) + verifySerialization( + capabilities, + McpJson, + """ + { + "extensions": { + "io.modelcontextprotocol/ui": {} + } + } + """.trimIndent(), + ) + } + @Test fun `should serialize ClientCapabilities with experimental`() { val experimental = buildJsonObject { @@ -215,11 +262,15 @@ class CapabilitiesTest { val experimental = buildJsonObject { put("feature1", buildJsonObject { put("enabled", true) }) } + val extensions = mapOf( + "io.modelcontextprotocol/ui" to EmptyJsonObject, + ) val capabilities = ClientCapabilities( sampling = ClientCapabilities.sampling, roots = ClientCapabilities.Roots(listChanged = true), elicitation = ClientCapabilities.elicitation, experimental = experimental, + extensions = extensions, ) verifySerialization( capabilities, @@ -235,6 +286,9 @@ class CapabilitiesTest { "feature1": { "enabled": true } + }, + "extensions": { + "io.modelcontextprotocol/ui": {} } } """.trimIndent(), @@ -270,6 +324,7 @@ class CapabilitiesTest { assertNull(capabilities.roots) assertNull(capabilities.elicitation) assertNull(capabilities.experimental) + assertNull(capabilities.extensions) } @Test @@ -278,6 +333,11 @@ class CapabilitiesTest { sampling = ClientCapabilities.sampling, roots = ClientCapabilities.Roots(listChanged = false), elicitation = ClientCapabilities.elicitation, + extensions = mapOf( + "io.modelcontextprotocol/ui" to buildJsonObject { + put("mimeTypes", buildJsonObject { put("text/html", true) }) + }, + ), ) verifySerializationRoundTrip(original, McpJson) @@ -466,6 +526,32 @@ class CapabilitiesTest { ) } + @Test + fun `should serialize ServerCapabilities with extensions`() { + val capabilities = ServerCapabilities( + extensions = mapOf( + "io.modelcontextprotocol/ui" to EmptyJsonObject, + "com.example/custom" to buildJsonObject { + put("setting", "value") + }, + ), + ) + verifySerialization( + capabilities, + McpJson, + """ + { + "extensions": { + "io.modelcontextprotocol/ui": {}, + "com.example/custom": { + "setting": "value" + } + } + } + """.trimIndent(), + ) + } + @Test fun `should serialize ServerCapabilities with experimental`() { val experimental = buildJsonObject { @@ -499,6 +585,9 @@ class CapabilitiesTest { val experimental = buildJsonObject { put("feature1", buildJsonObject { put("enabled", true) }) } + val extensions = mapOf( + "io.modelcontextprotocol/ui" to EmptyJsonObject, + ) val capabilities = ServerCapabilities( tools = ServerCapabilities.Tools(listChanged = true), resources = ServerCapabilities.Resources( @@ -509,6 +598,7 @@ class CapabilitiesTest { logging = ServerCapabilities.Logging, completions = ServerCapabilities.Completions, experimental = experimental, + extensions = extensions, ) verifySerialization( capabilities, @@ -531,6 +621,9 @@ class CapabilitiesTest { "feature1": { "enabled": true } + }, + "extensions": { + "io.modelcontextprotocol/ui": {} } } """.trimIndent(), @@ -578,6 +671,7 @@ class CapabilitiesTest { assertNull(capabilities.logging) assertNull(capabilities.completions) assertNull(capabilities.experimental) + assertNull(capabilities.extensions) } @Test @@ -590,6 +684,9 @@ class CapabilitiesTest { ), prompts = ServerCapabilities.Prompts(listChanged = true), logging = ServerCapabilities.Logging, + extensions = mapOf( + "io.modelcontextprotocol/ui" to EmptyJsonObject, + ), ) verifySerializationRoundTrip(original, McpJson) diff --git a/kotlin-sdk-core/src/commonTest/kotlin/io/modelcontextprotocol/kotlin/sdk/types/dsl/CapabilitiesDslTest.kt b/kotlin-sdk-core/src/commonTest/kotlin/io/modelcontextprotocol/kotlin/sdk/types/dsl/CapabilitiesDslTest.kt index e4a949fd..53dd5c79 100644 --- a/kotlin-sdk-core/src/commonTest/kotlin/io/modelcontextprotocol/kotlin/sdk/types/dsl/CapabilitiesDslTest.kt +++ b/kotlin-sdk-core/src/commonTest/kotlin/io/modelcontextprotocol/kotlin/sdk/types/dsl/CapabilitiesDslTest.kt @@ -4,7 +4,9 @@ import io.kotest.matchers.nulls.shouldBeNull import io.kotest.matchers.nulls.shouldNotBeNull import io.kotest.matchers.shouldBe import io.modelcontextprotocol.kotlin.sdk.ExperimentalMcpApi +import io.modelcontextprotocol.kotlin.sdk.types.EmptyJsonObject import io.modelcontextprotocol.kotlin.sdk.types.buildInitializeRequest +import kotlinx.serialization.json.buildJsonObject import kotlinx.serialization.json.double import kotlinx.serialization.json.jsonPrimitive import kotlinx.serialization.json.put @@ -31,6 +33,7 @@ class CapabilitiesDslTest { roots.shouldBeNull() elicitation.shouldBeNull() experimental.shouldBeNull() + extensions.shouldBeNull() } } @@ -56,6 +59,13 @@ class CapabilitiesDslTest { put("beta", false) put("maxConcurrency", 10) } + extensions( + mapOf( + "io.modelcontextprotocol/ui" to buildJsonObject { + put("mimeTypes", "text/html") + }, + ), + ) } info("Test", "1.0") } @@ -80,6 +90,11 @@ class CapabilitiesDslTest { get("beta")?.jsonPrimitive?.content shouldBe "false" get("maxConcurrency")?.jsonPrimitive?.content shouldBe "10" } + extensions shouldNotBeNull { + get("io.modelcontextprotocol/ui") shouldNotBeNull { + get("mimeTypes")?.jsonPrimitive?.content shouldBe "text/html" + } + } } } @@ -110,6 +125,50 @@ class CapabilitiesDslTest { requestNull.params.capabilities.roots?.listChanged.shouldBeNull() } + @Test + fun `capabilities should build with extensions containing empty settings`() { + val request = buildInitializeRequest { + protocolVersion = "2024-11-05" + capabilities { + extensions( + mapOf( + "io.modelcontextprotocol/ui" to EmptyJsonObject, + "com.example/custom" to EmptyJsonObject, + ), + ) + } + info("Test", "1.0") + } + + request.params.capabilities.shouldNotBeNull { + extensions shouldNotBeNull { + size shouldBe 2 + get("io.modelcontextprotocol/ui") shouldBe EmptyJsonObject + get("com.example/custom") shouldBe EmptyJsonObject + } + } + } + + @Test + fun `capabilities should overwrite extensions when set multiple times`() { + val request = buildInitializeRequest { + protocolVersion = "2024-11-05" + capabilities { + extensions(mapOf("io.modelcontextprotocol/ui" to EmptyJsonObject)) + extensions(mapOf("com.example/custom" to EmptyJsonObject)) // Should overwrite + } + info("Test", "1.0") + } + + request.params.capabilities.shouldNotBeNull { + extensions shouldNotBeNull { + size shouldBe 1 + get("com.example/custom") shouldBe EmptyJsonObject + get("io.modelcontextprotocol/ui").shouldBeNull() + } + } + } + @Test fun `capabilities should overwrite when same field set multiple times`() { val request = buildInitializeRequest { diff --git a/kotlin-sdk-core/src/commonTest/kotlin/io/modelcontextprotocol/kotlin/sdk/types/dsl/InitializeDslTest.kt b/kotlin-sdk-core/src/commonTest/kotlin/io/modelcontextprotocol/kotlin/sdk/types/dsl/InitializeDslTest.kt index cb351157..aa53cce9 100644 --- a/kotlin-sdk-core/src/commonTest/kotlin/io/modelcontextprotocol/kotlin/sdk/types/dsl/InitializeDslTest.kt +++ b/kotlin-sdk-core/src/commonTest/kotlin/io/modelcontextprotocol/kotlin/sdk/types/dsl/InitializeDslTest.kt @@ -5,6 +5,7 @@ import io.kotest.matchers.nulls.shouldNotBeNull import io.kotest.matchers.shouldBe import io.modelcontextprotocol.kotlin.sdk.ExperimentalMcpApi import io.modelcontextprotocol.kotlin.sdk.types.ClientCapabilities +import io.modelcontextprotocol.kotlin.sdk.types.EmptyJsonObject import io.modelcontextprotocol.kotlin.sdk.types.Implementation import io.modelcontextprotocol.kotlin.sdk.types.buildInitializeRequest import kotlinx.serialization.json.buildJsonObject @@ -30,6 +31,11 @@ class InitializeDslTest { experimental { put("custom", true) } + extensions( + mapOf( + "io.modelcontextprotocol/ui" to EmptyJsonObject, + ), + ) } info( name = "TestClient", @@ -45,6 +51,9 @@ class InitializeDslTest { roots?.listChanged shouldBe true elicitation?.get("mode")?.jsonPrimitive?.content shouldBe "interactive" experimental?.get("custom")?.jsonPrimitive?.content shouldBe "true" + extensions shouldNotBeNull { + get("io.modelcontextprotocol/ui") shouldBe EmptyJsonObject + } } request.params.clientInfo.shouldNotBeNull { name shouldBe "TestClient" @@ -74,6 +83,9 @@ class InitializeDslTest { val samplingObj = buildJsonObject { put("key", "value") } val elicitationObj = buildJsonObject { put("key", "value") } val experimentalObj = buildJsonObject { put("key", "value") } + val extensionsMap = mapOf( + "io.modelcontextprotocol/ui" to buildJsonObject { put("key", "value") }, + ) val request = buildInitializeRequest { protocolVersion = "1.0" @@ -81,6 +93,7 @@ class InitializeDslTest { sampling(samplingObj) elicitation(elicitationObj) experimental(experimentalObj) + extensions(extensionsMap) } info("Test", "1.0") } @@ -89,6 +102,7 @@ class InitializeDslTest { sampling shouldBe samplingObj elicitation shouldBe elicitationObj experimental shouldBe experimentalObj + extensions shouldBe extensionsMap } }