diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/ReadBuffer.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/ReadBuffer.kt index d3fc61f..d4c8b43 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/ReadBuffer.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/ReadBuffer.kt @@ -16,6 +16,7 @@ public class ReadBuffer { private val buffer: Buffer = Buffer() + /** Appends raw bytes to the internal buffer for subsequent message parsing. */ public fun append(chunk: ByteArray) { buffer.write(chunk) } @@ -86,6 +87,7 @@ public class ReadBuffer { } } + /** Clears all buffered data, discarding any partially received messages. */ public fun clear() { buffer.clear() } @@ -93,4 +95,5 @@ public class ReadBuffer { internal fun deserializeMessage(line: String): JSONRPCMessage = McpJson.decodeFromString(line) +/** Serializes a [JSONRPCMessage] to its JSON string representation with a trailing newline. */ public fun serializeMessage(message: JSONRPCMessage): String = McpJson.encodeToString(message) + "\n" 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 b132a5e..146eabf 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 @@ -171,6 +171,7 @@ public class ClientCapabilitiesBuilder @PublishedApi internal constructor() { */ public fun experimental(block: JsonObjectBuilder.() -> Unit): Unit = experimental(buildJsonObject(block)) + /** Constructs the [ClientCapabilities] instance from the current builder state. */ @PublishedApi internal fun build(): ClientCapabilities = ClientCapabilities( sampling = sampling, diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/common.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/common.kt index 7ec9c07..3ae8997 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/common.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/common.kt @@ -41,8 +41,10 @@ public sealed interface WithMeta { */ public typealias ProgressToken = RequestId +/** Creates a [ProgressToken] from a string value. */ public fun ProgressToken(value: String): ProgressToken = RequestId(value) +/** Creates a [ProgressToken] from a numeric value. */ public fun ProgressToken(value: Long): ProgressToken = RequestId(value) // ============================================================================ @@ -127,6 +129,7 @@ public sealed interface Reference { public val type: ReferenceType } +/** Discriminator for [Reference] subtypes used in completion and other operations. */ @Serializable public enum class ReferenceType(public val value: String) { @SerialName("ref/prompt") diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/content.dsl.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/content.dsl.kt index e538af5..8718dec 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/content.dsl.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/content.dsl.kt @@ -88,6 +88,7 @@ public abstract class MediaContentBuilder { meta = buildJsonObject(block) } + /** Constructs the [MediaContent] instance from the current builder state. */ @PublishedApi internal abstract fun build(): MediaContent } diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/content.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/content.kt index 0e6377f..45cfd0d 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/content.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/content.kt @@ -8,6 +8,7 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.json.JsonObject +/** Discriminator values for the polymorphic [ContentBlock] hierarchy. */ @Serializable public enum class ContentTypes(public val value: String) { @SerialName("text") diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/jsonRpc.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/jsonRpc.kt index 6a53d35..f42139f 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/jsonRpc.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/jsonRpc.kt @@ -40,10 +40,12 @@ public fun RequestId(value: Long): RequestId = RequestId.NumberId(value) @Serializable(with = RequestIdPolymorphicSerializer::class) public sealed interface RequestId { + /** A string-based request identifier. */ @JvmInline @Serializable public value class StringId(public val value: String) : RequestId + /** A numeric request identifier. */ @JvmInline @Serializable public value class NumberId(public val value: Long) : RequestId diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/sampling.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/sampling.kt index 41dc864..1ade1bf 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/sampling.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/sampling.kt @@ -243,6 +243,7 @@ public data class CreateMessageResult( override val meta: JsonObject? = null, ) : ClientResult +/** The reason why the LLM stopped generating tokens. */ @JvmInline @Serializable public value class StopReason(public val value: String) { diff --git a/kotlin-sdk-server/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/server/Server.kt b/kotlin-sdk-server/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/server/Server.kt index afed86a..e566d09 100644 --- a/kotlin-sdk-server/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/server/Server.kt +++ b/kotlin-sdk-server/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/server/Server.kt @@ -185,6 +185,7 @@ public open class Server( block(this) } + /** Closes this server, shutting down the notification service and all active sessions. */ public suspend fun close() { logger.debug { "Closing MCP server" } notificationService.close() @@ -718,6 +719,7 @@ public open class Server( // Start the ServerSession / ClientConnection redirection section + /** Returns the [ClientConnection] for the session identified by [sessionId]. */ public fun clientConnection(sessionId: String): ClientConnection = sessionRegistry.getSession(sessionId).clientConnection @@ -827,18 +829,22 @@ public open class Server( // End the ServerSession / ClientConnection redirection section // Start the notification handling section + + /** Registers a notification [handler] for the given [method] on all active sessions. */ public fun setNotificationHandler(method: Method, handler: (notification: T) -> Deferred) { sessions.forEach { (_, session) -> session.setNotificationHandler(method, handler) } } + /** Removes the notification handler for the given [method] from all active sessions. */ public fun removeNotificationHandler(method: Method) { sessions.forEach { (_, session) -> session.removeNotificationHandler(method) } } + /** Registers a notification [handler] for the given [method] on a specific session. */ public fun setNotificationHandler( sessionId: String, method: Method, @@ -847,6 +853,7 @@ public open class Server( sessionRegistry.getSessionOrNull(sessionId)?.setNotificationHandler(method, handler) } + /** Removes the notification handler for the given [method] from a specific session. */ public fun removeNotificationHandler(sessionId: String, method: Method) { sessionRegistry.getSessionOrNull(sessionId)?.removeNotificationHandler(method) } diff --git a/kotlin-sdk-server/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/server/StreamableHttpServerTransport.kt b/kotlin-sdk-server/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/server/StreamableHttpServerTransport.kt index d0bbcfb..821c525 100644 --- a/kotlin-sdk-server/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/server/StreamableHttpServerTransport.kt +++ b/kotlin-sdk-server/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/server/StreamableHttpServerTransport.kt @@ -418,6 +418,7 @@ public class StreamableHttpServerTransport(private val configuration: Configurat } } + /** Handles an HTTP GET request by establishing a standalone SSE stream for server-initiated notifications. */ @Suppress("ReturnCount") public suspend fun handleGetRequest(session: ServerSSESession?, call: ApplicationCall) { // NOTE: enableJsonResponse only controls how POST responses are delivered (JSON vs. SSE). @@ -465,6 +466,7 @@ public class StreamableHttpServerTransport(private val configuration: Configurat awaitCancellation() } + /** Handles an HTTP DELETE request by closing the session and the transport. */ public suspend fun handleDeleteRequest(call: ApplicationCall) { if (!validateSession(call) || !validateProtocolVersion(call)) return sessionId?.let { onSessionClosed?.invoke(it) }