diff --git a/conformance-test/README.md b/conformance-test/README.md index b1ad35559..0f08d751f 100644 --- a/conformance-test/README.md +++ b/conformance-test/README.md @@ -110,7 +110,7 @@ Tests the conformance server against all server scenarios: ## Known SDK Limitations -10 scenarios are expected to fail due to current SDK limitations (tracked in [ +9 scenarios are expected to fail due to current SDK limitations (tracked in [ `conformance-baseline.yml`](conformance-baseline.yml). | Scenario | Suite | Root Cause | @@ -122,7 +122,6 @@ Tests the conformance server against all server scenarios: | `elicitation-sep1034-defaults` | server | *(same as above)* | | `elicitation-sep1330-enums` | server | *(same as above)* | | `resources-templates-read` | server | SDK does not implement `addResourceTemplate()` with URI pattern matching; resources are looked up by exact URI | -| `initialize` | client | Conformance server sends a JSON-RPC response without `id`; `JSONRPCResponse.id` is non-nullable so deserialization fails | | `elicitation-sep1034-client-defaults` | client | SDK does not fill in `default` values from the elicitation request schema before sending the response | | `sse-retry` | client | Transport does not respect the SSE `retry` field timing or send `Last-Event-ID` on reconnection | diff --git a/conformance-test/conformance-baseline.yml b/conformance-test/conformance-baseline.yml index 0c4cb234a..9126f0d34 100644 --- a/conformance-test/conformance-baseline.yml +++ b/conformance-test/conformance-baseline.yml @@ -10,6 +10,5 @@ server: - resources-templates-read client: - - initialize - elicitation-sep1034-client-defaults - sse-retry diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/serializers.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/serializers.kt index a00b26be4..4d5974d92 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/serializers.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/serializers.kt @@ -371,21 +371,23 @@ internal object ServerResultPolymorphicSerializer : * Polymorphic serializer for [JSONRPCMessage] types. * Determines the message type based on the presence of specific fields: * - "error" -> JSONRPCError - * - "result" -> JSONRPCResponse + * - "result" + "id" -> JSONRPCResponse + * - "result" -> JSONRPCEmptyMessage * - "method" + "id" -> JSONRPCRequest * - "method" -> JSONRPCNotification */ internal object JSONRPCMessagePolymorphicSerializer : JsonContentPolymorphicSerializer(JSONRPCMessage::class) { override fun selectDeserializer(element: JsonElement): DeserializationStrategy { - val jsonObject = element.jsonObject + val jsonObj = element.jsonObject return when { - "error" in jsonObject -> JSONRPCError.serializer() - "result" in jsonObject -> JSONRPCResponse.serializer() - "method" in jsonObject && "id" in jsonObject -> JSONRPCRequest.serializer() - "method" in jsonObject -> JSONRPCNotification.serializer() - jsonObject.isEmpty() || jsonObject.keys == setOf("jsonrpc") -> JSONRPCEmptyMessage.serializer() - else -> throw SerializationException("Invalid JSONRPCMessage type: ${jsonObject.keys}") + "error" in jsonObj -> JSONRPCError.serializer() + "result" in jsonObj && "id" in jsonObj -> JSONRPCResponse.serializer() + "result" in jsonObj && jsonObj["result"]?.jsonObject?.isEmpty() == true -> JSONRPCEmptyMessage.serializer() + "method" in jsonObj && "id" in jsonObj -> JSONRPCRequest.serializer() + "method" in jsonObj -> JSONRPCNotification.serializer() + jsonObj.isEmpty() || jsonObj.keys == setOf("jsonrpc") -> JSONRPCEmptyMessage.serializer() + else -> throw SerializationException("Invalid JSONRPCMessage type: ${jsonObj.keys}") } } }