diff --git a/kotlin-sdk-client/src/commonTest/kotlin/io/modelcontextprotocol/kotlin/sdk/client/StreamableHttpClientTransportTest.kt b/kotlin-sdk-client/src/commonTest/kotlin/io/modelcontextprotocol/kotlin/sdk/client/StreamableHttpClientTransportTest.kt index a72bd853..a6ff6646 100644 --- a/kotlin-sdk-client/src/commonTest/kotlin/io/modelcontextprotocol/kotlin/sdk/client/StreamableHttpClientTransportTest.kt +++ b/kotlin-sdk-client/src/commonTest/kotlin/io/modelcontextprotocol/kotlin/sdk/client/StreamableHttpClientTransportTest.kt @@ -16,7 +16,6 @@ import io.modelcontextprotocol.kotlin.sdk.Implementation import io.modelcontextprotocol.kotlin.sdk.JSONRPCMessage import io.modelcontextprotocol.kotlin.sdk.JSONRPCNotification import io.modelcontextprotocol.kotlin.sdk.JSONRPCRequest -import io.modelcontextprotocol.kotlin.sdk.RequestId import io.modelcontextprotocol.kotlin.sdk.shared.McpJson import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay @@ -50,7 +49,7 @@ class StreamableHttpClientTransportTest { @Test fun testSendJsonRpcMessage() = runTest { val message = JSONRPCRequest( - id = RequestId.StringId("test-id"), + id = "test-id", method = "test", params = buildJsonObject { }, ) @@ -78,7 +77,7 @@ class StreamableHttpClientTransportTest { @Test fun testStoreSessionId() = runTest { val initMessage = JSONRPCRequest( - id = RequestId.StringId("test-id"), + id = "test-id", method = "initialize", params = buildJsonObject { put( diff --git a/kotlin-sdk-core/api/kotlin-sdk-core.api b/kotlin-sdk-core/api/kotlin-sdk-core.api index 4f230ab4..bdefe7f0 100644 --- a/kotlin-sdk-core/api/kotlin-sdk-core.api +++ b/kotlin-sdk-core/api/kotlin-sdk-core.api @@ -1143,8 +1143,15 @@ public final class io/modelcontextprotocol/kotlin/sdk/JSONRPCNotification$Compan public final class io/modelcontextprotocol/kotlin/sdk/JSONRPCRequest : io/modelcontextprotocol/kotlin/sdk/JSONRPCMessage { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/JSONRPCRequest$Companion; + public fun (JLjava/lang/String;Lkotlinx/serialization/json/JsonElement;)V + public synthetic fun (JLjava/lang/String;Lkotlinx/serialization/json/JsonElement;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun (Lio/modelcontextprotocol/kotlin/sdk/RequestId;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;Ljava/lang/String;)V public synthetic fun (Lio/modelcontextprotocol/kotlin/sdk/RequestId;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Ljava/lang/String;)V + public fun (Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;)V + public synthetic fun (Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Lio/modelcontextprotocol/kotlin/sdk/RequestId; public final fun component2 ()Ljava/lang/String; public final fun component3 ()Lkotlinx/serialization/json/JsonElement; diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types.kt index 60adcca4..9fcafa4a 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types.kt @@ -17,8 +17,11 @@ import kotlin.concurrent.atomics.AtomicLong import kotlin.concurrent.atomics.ExperimentalAtomicApi import kotlin.concurrent.atomics.incrementAndFetch import kotlin.jvm.JvmInline +import kotlin.jvm.JvmOverloads import kotlin.time.ExperimentalTime import kotlin.time.Instant +import kotlin.uuid.ExperimentalUuidApi +import kotlin.uuid.Uuid public const val LATEST_PROTOCOL_VERSION: String = "2025-03-26" @@ -232,7 +235,50 @@ public data class JSONRPCRequest( val method: String, val params: JsonElement = EmptyJsonObject, val jsonrpc: String = JSONRPC_VERSION, -) : JSONRPCMessage +) : JSONRPCMessage { + + /** + * Creates a JSON-RPC request with a randomly generated string ID (using UUID) and the given method and parameters. + * + * @param id The string ID for the request. If not provided, a random UUID string is generated. + * @param method The method name for the request. + * @param params The parameters for the request as a JSON element. If not provided, an empty JSON object is used. + */ + @OptIn(ExperimentalUuidApi::class) + public constructor( + id: String = Uuid.random().toHexString(), + method: String, + params: JsonElement = EmptyJsonObject, + ) : this(id = RequestId.StringId(id), method = method, params = params) + + /** + * Creates a JSON-RPC request with a randomly generated string ID (using UUID), + * the given method name and parameters. + * + * @param method The method name for the request. + * @param params The parameters for the request as a JSON element. If not provided, an empty JSON object is used. + */ + @OptIn(ExperimentalUuidApi::class) + @JvmOverloads + public constructor( + method: String, + params: JsonElement = EmptyJsonObject, + ) : this(id = RequestId.StringId(Uuid.random().toHexString()), method = method, params = params) + + /** + * Creates a JSON-RPC request with a numeric ID (long) generated by a counter (to ensure uniqueness) + * and the given method and parameters. + * + * The `id` parameter is optional and defaults to a new unique long value generated + * by `REQUEST_MESSAGE_ID.incrementAndFetch()`. + * The `params` parameter is optional and defaults to an empty JSON object. + */ + public constructor( + id: Long = REQUEST_MESSAGE_ID.incrementAndFetch(), + method: String, + params: JsonElement = EmptyJsonObject, + ) : this(id = RequestId.NumberId(id), method = method, params = params) +} /** * A notification which does not expect a response. @@ -302,10 +348,12 @@ public data class JSONRPCError(val code: ErrorCode, val message: String, val dat public sealed interface NotificationParams : WithMeta /* Cancellation */ + /** * This notification can be sent by either side to indicate that it is cancelling a previously issued request. * - * The request SHOULD still be in-flight, but due to communication latency, it is always possible that this notification MAY arrive after the request has already finished. + * The request SHOULD still be in-flight, but due to communication latency, + * it is always possible that this notification MAY arrive after the request has already finished. * * This notification indicates that the result will be unused, so any associated processing SHOULD cease. * @@ -334,6 +382,7 @@ public data class CancelledNotification(override val params: Params) : } /* Initialization */ + /** * Describes the name and version of an MCP implementation. */ @@ -531,6 +580,7 @@ public data class InitializedNotification(override val params: Params = Params() } /* Ping */ + /** * A ping, issued by either the server or the client, to check that the other party is still alive. * The receiver must promptly respond, or else it may be disconnected. @@ -564,6 +614,7 @@ public sealed interface ProgressBase { } /* Progress notifications */ + /** * Represents a progress notification. * @@ -623,6 +674,7 @@ public data class ProgressNotification(override val params: Params) : } /* Pagination */ + /** * Represents a request supporting pagination. */ @@ -650,6 +702,7 @@ public sealed interface PaginatedResult : RequestResult { } /* Resources */ + /** * The contents of a specific resource or sub-resource. */ @@ -892,6 +945,7 @@ public data class ResourceUpdatedNotification(override val params: Params) : Ser } /* Prompts */ + /** * Describes an argument that a prompt can accept. */ @@ -1162,6 +1216,7 @@ public data class PromptListChangedNotification(override val params: Params = Pa } /* Tools */ + /** * Additional properties describing a Tool to clients. * @@ -1345,6 +1400,7 @@ public data class ToolListChangedNotification(override val params: Params = Para } /* Logging */ + /** * The severity of a log message. */ @@ -1404,6 +1460,7 @@ public data class LoggingMessageNotification(override val params: Params) : Serv } /* Sampling */ + /** * Hints to use for model selection. */ @@ -1648,6 +1705,7 @@ public data class CompleteResult(val completion: Completion, override val _meta: } /* Roots */ + /** * Represents a root directory or file that the server can operate on. */