From 8e4b23ff098c1351558cfcea95150a72505d6361 Mon Sep 17 00:00:00 2001 From: devcrocod Date: Mon, 30 Mar 2026 21:58:19 +0200 Subject: [PATCH 1/6] enable detekt UndocumentedPublicProperty rule and add kdoc skill --- .claude/skills/kdoc/SKILL.md | 74 +++++++++++++++++++ config/detekt/detekt.yml | 6 ++ .../client/StreamableHttpClientTransport.kt | 7 +- .../kotlin/sdk/internal/utils.kt | 1 + .../kotlin/sdk/shared/Protocol.kt | 9 +++ .../sdk/shared/WebSocketMcpTransport.kt | 1 + .../kotlin/sdk/types/PingRequest.kt | 5 ++ .../kotlin/sdk/types/capabilities.kt | 8 ++ .../kotlin/sdk/types/common.kt | 13 +++- .../kotlin/sdk/types/completion.kt | 1 + .../kotlin/sdk/types/content.kt | 11 ++- .../kotlin/sdk/types/jsonRpc.kt | 15 +++- .../kotlin/sdk/types/jsonUtils.kt | 2 + .../kotlin/sdk/types/methods.kt | 2 + .../kotlin/sdk/types/notification.kt | 4 + .../kotlin/sdk/types/request.kt | 13 +++- .../kotlin/sdk/types/roots.kt | 1 + .../kotlin/sdk/types/sampling.kt | 11 ++- .../kotlin/sdk/types/tasks.kt | 9 +++ .../sdk/utils/ResourceTemplateMatcher.kt | 2 + .../kotlin/sdk/internal/utils.jvm.kt | 1 + .../kotlin/sdk/server/SSEServerTransport.kt | 2 + .../kotlin/sdk/server/ServerSession.kt | 2 + .../server/StreamableHttpServerTransport.kt | 26 ++----- 24 files changed, 201 insertions(+), 25 deletions(-) create mode 100644 .claude/skills/kdoc/SKILL.md diff --git a/.claude/skills/kdoc/SKILL.md b/.claude/skills/kdoc/SKILL.md new file mode 100644 index 000000000..476029367 --- /dev/null +++ b/.claude/skills/kdoc/SKILL.md @@ -0,0 +1,74 @@ +--- +name: kdoc +description: "Add KDoc documentation to Kotlin public API. Use whenever the user asks to document Kotlin code, add KDoc, generate API docs, mentions undocumented public declarations, or wants to improve existing documentation. Also trigger when the user says 'add docs', 'document this class/file/module', 'write KDoc', or asks about missing documentation in Kotlin code." +--- + +# KDoc Generator + +Add KDoc comments to public Kotlin API declarations. + +## What to document + +All public declarations (no explicit `private`/`internal`/`protected`): +- Classes, interfaces, objects, sealed classes/interfaces +- Functions, extension functions +- Properties +- Enum classes and entries +- Type aliases, annotation classes + +Include `@Deprecated` elements. + +## Context + +Read the implementation, not just the signature, to write accurate descriptions. Understanding what the code actually does prevents superficial or misleading documentation. + +## KDoc format + +**Class/interface example:** + +````kotlin +/** + * Manages active client sessions and their lifecycle. + * + * Sessions are created on first connection and cleaned up + * when the transport closes. + * + * @property maxSessions upper limit on concurrent sessions + * @property timeout idle timeout before a session is evicted + */ +```` + +**Function example:** + +````kotlin +/** + * Registers a new tool with the given handler. + * + * Example: + * ```kotlin + * server.addTool( + * name = "echo", + * description = "Echoes input back", + * ) { request -> + * CallToolResult(content = listOf(TextContent("Echo: ${request.arguments}"))) + * } + * ``` + * + * @param name unique tool identifier + * @param description human-readable tool description + * @param handler suspend function invoked when the tool is called + * @return the registered tool definition + */ +```` + +## Rules + +- Summary: concise first sentence starting with a third-person verb ("Creates", "Returns", "Represents"). Expand to 2-3 sentences only when genuinely complex +- **@property** in class-level KDoc for all public properties (never as individual KDoc on the property); **@param** for function parameters +- **@return** for non-Unit return types +- **Example block**: add for DSL builders, complex functions, extension functions with non-obvious usage. Skip for trivial one-liners and simple getters +- **DSL builders**: always include an Example showing full usage with the receiver scope — this is critical for discoverability +- KDoc links (`[ClassName]`, `[methodName]`): only where it adds clear navigational value +- No **@throws** — don't document exceptions +- No **suspend** notes — coroutine nature is visible from the signature +- **Existing KDoc**: rewrite if incomplete (missing @param/@return/@property) or low quality \ No newline at end of file diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index 2cb135abb..022e80cc9 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -22,3 +22,9 @@ empty-blocks: EmptyFunctionBlock: excludes: *testFolders +comments: + UndocumentedPublicProperty: + active: true + excludes: [ '**/test/**', '**/commonTest/**', '**/jvmTest/**', '**/generated-sources/**' ] + searchProtectedProperty: false + ignoreEnumEntries: true diff --git a/kotlin-sdk-client/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/client/StreamableHttpClientTransport.kt b/kotlin-sdk-client/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/client/StreamableHttpClientTransport.kt index 80f37aedc..999e25acb 100644 --- a/kotlin-sdk-client/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/client/StreamableHttpClientTransport.kt +++ b/kotlin-sdk-client/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/client/StreamableHttpClientTransport.kt @@ -51,7 +51,9 @@ private const val MCP_PROTOCOL_VERSION_HEADER = "mcp-protocol-version" private const val MCP_RESUMPTION_TOKEN_HEADER = "Last-Event-ID" /** - * Error class for Streamable HTTP transport errors. + * Represents an error from the Streamable HTTP transport. + * + * @property code HTTP status code associated with the error, or `null` if unavailable */ public class StreamableHttpError(public val code: Int? = null, message: String? = null) : Exception("Streamable HTTP error: $message") @@ -66,6 +68,9 @@ private sealed interface ConnectResult { * Client transport for Streamable HTTP: this implements the MCP Streamable HTTP transport specification. * It will connect to a server using HTTP POST for sending messages and HTTP GET with Server-Sent Events * for receiving messages. + * + * @property sessionId session identifier assigned by the server after initialization, or `null` before connection + * @property protocolVersion MCP protocol version negotiated with the server, or `null` before connection */ @Suppress("TooManyFunctions") public class StreamableHttpClientTransport( diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/internal/utils.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/internal/utils.kt index d1cbe781f..37a57b76c 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/internal/utils.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/internal/utils.kt @@ -2,4 +2,5 @@ package io.modelcontextprotocol.kotlin.sdk.internal import kotlinx.coroutines.CoroutineDispatcher +/** Platform-specific [CoroutineDispatcher] for I/O-bound operations. */ public expect val IODispatcher: CoroutineDispatcher diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/Protocol.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/Protocol.kt index 20739e0ad..5b2b6cada 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/Protocol.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/Protocol.kt @@ -42,6 +42,7 @@ import kotlin.time.Duration.Companion.seconds private val logger = KotlinLogging.logger { } +/** Default implementation name used in MCP handshake. */ public const val IMPLEMENTATION_NAME: String = "mcp-ktor" /** @@ -51,6 +52,8 @@ public typealias ProgressCallback = (Progress) -> Unit /** * Additional initialization options. + * + * @property timeout default timeout for outgoing requests */ public open class ProtocolOptions( /** @@ -139,6 +142,12 @@ internal val COMPLETED = CompletableDeferred(Unit).also { it.complete(Unit) } /** * Implements MCP protocol framing on top of a pluggable transport, including * features like request/response linking, notifications, and progress. + * + * @property transport the active transport, or `null` if not connected + * @property requestHandlers registered request handlers keyed by method name + * @property notificationHandlers registered notification handlers keyed by method name + * @property responseHandlers pending response handlers keyed by request ID + * @property progressHandlers registered progress callbacks keyed by progress token */ public abstract class Protocol(@PublishedApi internal val options: ProtocolOptions?) { public var transport: Transport? = null diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/WebSocketMcpTransport.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/WebSocketMcpTransport.kt index de75cc460..5f8bf9dac 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/WebSocketMcpTransport.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/WebSocketMcpTransport.kt @@ -17,6 +17,7 @@ import kotlinx.coroutines.launch import kotlin.concurrent.atomics.AtomicBoolean import kotlin.concurrent.atomics.ExperimentalAtomicApi +/** WebSocket subprotocol identifier for MCP connections. */ public const val MCP_SUBPROTOCOL: String = "mcp" private val logger = KotlinLogging.logger {} diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/PingRequest.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/PingRequest.kt index 2f1e3ae69..c45ed301b 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/PingRequest.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/PingRequest.kt @@ -4,6 +4,11 @@ import kotlinx.serialization.EncodeDefault import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.Serializable +/** + * Represents a ping request used to check if the connection is alive. + * + * @property meta optional request metadata + */ @Serializable public data class PingRequest(override val params: BaseRequestParams? = null) : ClientRequest, 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 cff3b8906..fae24c319 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 @@ -54,6 +54,10 @@ public data class ClientCapabilities( public val experimental: JsonObject? = null, ) { + /** + * @property sampling convenience value to enable the sampling capability + * @property elicitation convenience value to enable the elicitation capability + */ public companion object { public val sampling: JsonObject = EmptyJsonObject public val elicitation: JsonObject = EmptyJsonObject @@ -100,6 +104,10 @@ public data class ServerCapabilities( val experimental: JsonObject? = null, ) { + /** + * @property Logging convenience value to enable the logging capability + * @property Completions convenience value to enable the completions capability + */ public companion object { public val Logging: JsonObject = EmptyJsonObject public val Completions: JsonObject = EmptyJsonObject 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 3ae89979d..ac867af1d 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 @@ -8,10 +8,13 @@ import kotlinx.serialization.json.JsonObject // Protocol Version Constants // ============================================================================ +/** The latest supported MCP protocol version string. */ public const val LATEST_PROTOCOL_VERSION: String = "2025-11-25" +/** The default protocol version used when negotiation is not performed. */ public const val DEFAULT_NEGOTIATED_PROTOCOL_VERSION: String = "2025-06-18" +/** All MCP protocol versions supported by this SDK. */ public val SUPPORTED_PROTOCOL_VERSIONS: List = listOf( LATEST_PROTOCOL_VERSION, "2025-06-18", @@ -25,6 +28,8 @@ public val SUPPORTED_PROTOCOL_VERSIONS: List = listOf( /** * Represents an entity that includes additional metadata in its responses. + * + * @property meta optional metadata attached to this entity */ @Serializable public sealed interface WithMeta { @@ -123,13 +128,19 @@ public enum class Role { * * References are used to point to other entities (prompts, resources, etc.) * without including their full definitions. + * + * @property type discriminator identifying the reference subtype */ @Serializable(with = ReferencePolymorphicSerializer::class) public sealed interface Reference { public val type: ReferenceType } -/** Discriminator for [Reference] subtypes used in completion and other operations. */ +/** + * Discriminator for [Reference] subtypes used in completion and other operations. + * + * @property value serialized string representation of this reference type + */ @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/completion.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/completion.kt index 79a76ea53..c782e3e7d 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/completion.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/completion.kt @@ -12,6 +12,7 @@ import kotlinx.serialization.json.JsonObject * A request from the client to the server to ask for completion options. * * @property params The request parameters containing the argument to complete and its context. + * @property meta optional request metadata */ @Serializable public data class CompleteRequest(override val params: CompleteRequestParams) : ClientRequest { 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 45cfd0ddb..9bc1887aa 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,7 +8,11 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.json.JsonObject -/** Discriminator values for the polymorphic [ContentBlock] hierarchy. */ +/** + * Discriminator values for the polymorphic [ContentBlock] hierarchy. + * + * @property value serialized string representation of this content type + */ @Serializable public enum class ContentTypes(public val value: String) { @SerialName("text") @@ -27,6 +31,11 @@ public enum class ContentTypes(public val value: String) { EMBEDDED_RESOURCE("resource"), } +/** + * Base interface for all content blocks in the protocol. + * + * @property type discriminator identifying the content block subtype + */ @Serializable(with = ContentBlockPolymorphicSerializer::class) public sealed interface ContentBlock : WithMeta { public val type: ContentTypes 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 f42139f55..6e25ba4f1 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 @@ -14,6 +14,7 @@ import kotlin.jvm.JvmOverloads import kotlin.uuid.ExperimentalUuidApi import kotlin.uuid.Uuid +/** JSON-RPC protocol version used by MCP (`"2.0"`). */ public const val JSONRPC_VERSION: String = "2.0" /** @@ -40,12 +41,20 @@ public fun RequestId(value: Long): RequestId = RequestId.NumberId(value) @Serializable(with = RequestIdPolymorphicSerializer::class) public sealed interface RequestId { - /** A string-based request identifier. */ + /** + * A string-based request identifier. + * + * @property value the string representation of this request ID + */ @JvmInline @Serializable public value class StringId(public val value: String) : RequestId - /** A numeric request identifier. */ + /** + * A numeric request identifier. + * + * @property value the numeric representation of this request ID + */ @JvmInline @Serializable public value class NumberId(public val value: Long) : RequestId @@ -95,6 +104,8 @@ internal fun JSONRPCNotification.fromJSON(): Notification = * Base interface for all JSON-RPC 2.0 messages. * * All messages in the MCP protocol follow the JSON-RPC 2.0 specification. + * + * @property jsonrpc the JSON-RPC protocol version, always `"2.0"` */ @Serializable(with = JSONRPCMessagePolymorphicSerializer::class) public sealed interface JSONRPCMessage { diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/jsonUtils.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/jsonUtils.kt index 566905fb5..d83e01231 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/jsonUtils.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/jsonUtils.kt @@ -11,8 +11,10 @@ import kotlinx.serialization.json.add import kotlinx.serialization.json.buildJsonArray import kotlinx.serialization.json.buildJsonObject +/** Reusable empty [JsonObject] instance. */ public val EmptyJsonObject: JsonObject = JsonObject(emptyMap()) +/** Pre-configured [Json] instance for MCP serialization. */ @OptIn(ExperimentalSerializationApi::class) public val McpJson: Json by lazy { Json { diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/methods.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/methods.kt index 1d96fea03..da12fb55f 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/methods.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/methods.kt @@ -4,6 +4,8 @@ import kotlinx.serialization.Serializable /** * Represents a method in the protocol, which can be predefined or custom. + * + * @property value the string representation of this method name */ @Serializable(with = MethodSerializer::class) public sealed interface Method { diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/notification.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/notification.kt index cb1aa9908..1820a841a 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/notification.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/notification.kt @@ -11,6 +11,9 @@ import kotlinx.serialization.json.JsonObject /** * Represents a notification in the protocol. + * + * @property method the notification method identifier + * @property params optional notification parameters */ @Serializable(with = NotificationPolymorphicSerializer::class) public sealed interface Notification { @@ -73,6 +76,7 @@ public class Progress( * @property method The custom method name. By convention, custom methods often contain * organization-specific prefixes (e.g., "mycompany/custom_event"). * @property params Raw JSON parameters for the custom notification, if present. + * @property meta optional metadata for this notification */ @Serializable public data class CustomNotification(override val method: Method, override val params: BaseNotificationParams? = null) : diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/request.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/request.kt index 683186c15..015369381 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/request.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/request.kt @@ -11,6 +11,12 @@ import kotlinx.serialization.json.long import kotlinx.serialization.json.longOrNull import kotlin.jvm.JvmInline +/** + * Metadata attached to a request's `_meta` field. + * + * @property json the raw JSON object containing the metadata + * @property progressToken optional progress token for tracking request progress + */ @JvmInline @Serializable public value class RequestMeta(public val json: JsonObject) { @@ -60,6 +66,9 @@ public data class BaseRequestParams(@SerialName("_meta") override val meta: Requ /** * Represents a request in the protocol. + * + * @property method the request method identifier + * @property params optional request parameters */ @OptIn(ExperimentalSerializationApi::class) @Serializable(with = RequestPolymorphicSerializer::class) @@ -129,7 +138,9 @@ public data class EmptyResult(@SerialName("_meta") override val meta: JsonObject ServerResult /** - * Represents a request supporting pagination. + * Represents a paginated result. + * + * @property nextCursor opaque token for retrieving the next page of results, or `null` if no more results */ @Serializable public sealed interface PaginatedResult : RequestResult { diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/roots.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/roots.kt index af7b1e7a2..194ea4fb2 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/roots.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/roots.kt @@ -53,6 +53,7 @@ public data class Root( * `listChanged = true` to receive these requests. * * @property params Optional request parameters containing metadata. + * @property meta optional request metadata */ @Serializable public data class ListRootsRequest(override val params: BaseRequestParams? = null) : ServerRequest { 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 1ade1bfc5..97fc0c06c 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,10 +243,19 @@ public data class CreateMessageResult( override val meta: JsonObject? = null, ) : ClientResult -/** The reason why the LLM stopped generating tokens. */ +/** + * The reason why the LLM stopped generating tokens. + * + * @property value the string representation of this stop reason + */ @JvmInline @Serializable public value class StopReason(public val value: String) { + /** + * @property EndTurn generation ended naturally + * @property StopSequence a stop sequence was encountered + * @property MaxTokens the maximum token limit was reached + */ public companion object { public val EndTurn: StopReason = StopReason("endTurn") public val StopSequence: StopReason = StopReason("stopSequence") diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/tasks.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/tasks.kt index 42b5752af..0f154e5c0 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/tasks.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/tasks.kt @@ -17,6 +17,14 @@ public const val RELATED_TASK_META_KEY: String = "io.modelcontextprotocol/relate /** * Common fields shared by all types representing the task state. + * + * @property taskId the task identifier + * @property status current task state + * @property statusMessage optional human-readable message describing the current task state + * @property createdAt ISO 8601 timestamp when the task was created + * @property lastUpdatedAt ISO 8601 timestamp when the task was last updated + * @property ttl actual retention duration from creation in milliseconds, or `null` for unlimited + * @property pollInterval suggested polling interval in milliseconds */ public sealed interface TaskFields { public val taskId: String @@ -228,6 +236,7 @@ public data class GetTaskPayloadRequestParams( * The structure matches the result type of the original request. * For example, a tools/call task would return the [CallToolResult] structure. * + * @property json the raw JSON object containing the result payload * @property meta Optional metadata for this response. */ @JvmInline diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/utils/ResourceTemplateMatcher.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/utils/ResourceTemplateMatcher.kt index 5ba956d29..867cc9f1e 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/utils/ResourceTemplateMatcher.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/utils/ResourceTemplateMatcher.kt @@ -32,6 +32,8 @@ public class MatchResult(public val variables: Map, public val s * candidate URIs against that template via [match]. The returned [MatchResult.score] * must reflect match specificity so that a selection algorithm can prefer the most * specific template when multiple templates match the same URI. + * + * @property resourceTemplate the template to match URIs against */ public interface ResourceTemplateMatcher { diff --git a/kotlin-sdk-core/src/jvmMain/kotlin/io/modelcontextprotocol/kotlin/sdk/internal/utils.jvm.kt b/kotlin-sdk-core/src/jvmMain/kotlin/io/modelcontextprotocol/kotlin/sdk/internal/utils.jvm.kt index d00c1ab55..35a1e9802 100644 --- a/kotlin-sdk-core/src/jvmMain/kotlin/io/modelcontextprotocol/kotlin/sdk/internal/utils.jvm.kt +++ b/kotlin-sdk-core/src/jvmMain/kotlin/io/modelcontextprotocol/kotlin/sdk/internal/utils.jvm.kt @@ -3,5 +3,6 @@ package io.modelcontextprotocol.kotlin.sdk.internal import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers +/** Platform-specific [CoroutineDispatcher] for I/O-bound operations. */ public actual val IODispatcher: CoroutineDispatcher get() = Dispatchers.IO diff --git a/kotlin-sdk-server/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/server/SSEServerTransport.kt b/kotlin-sdk-server/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/server/SSEServerTransport.kt index 619266aa7..f8c658129 100644 --- a/kotlin-sdk-server/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/server/SSEServerTransport.kt +++ b/kotlin-sdk-server/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/server/SSEServerTransport.kt @@ -26,6 +26,8 @@ internal const val SESSION_ID_PARAM = "sessionId" * Server transport for SSE: this will send messages over an SSE connection and receive messages from HTTP POST requests. * * Creates a new SSE server transport, which will direct the client to POST messages to the relative or absolute URL identified by `_endpoint`. + * + * @property sessionId unique identifier for this transport session, generated randomly on creation */ @OptIn(ExperimentalAtomicApi::class) public class SseServerTransport(private val endpoint: String, private val session: ServerSSESession) : diff --git a/kotlin-sdk-server/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/server/ServerSession.kt b/kotlin-sdk-server/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/server/ServerSession.kt index a8a34aff3..1afbc5e0f 100644 --- a/kotlin-sdk-server/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/server/ServerSession.kt +++ b/kotlin-sdk-server/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/server/ServerSession.kt @@ -39,6 +39,8 @@ private val logger = KotlinLogging.logger {} /** * Represents a server session. + * + * @property sessionId unique identifier for this session, generated randomly on creation */ @Suppress("TooManyFunctions") public open class ServerSession( 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 821c525a1..0e30dab58 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 @@ -71,6 +71,7 @@ private data class SessionContext(val session: ServerSSESession?, val call: Appl * - No session validation is performed * * @param configuration Transport configuration. See [Configuration] for available options. + * @property sessionId session identifier assigned after initialization, or `null` in stateless mode */ @OptIn(ExperimentalUuidApi::class, ExperimentalAtomicApi::class) @Suppress("TooManyFunctions") @@ -122,25 +123,14 @@ public class StreamableHttpServerTransport(private val configuration: Configurat ) /** - * Configuration for managing various aspects of the StreamableHttpServerTransport. + * Configuration options for [StreamableHttpServerTransport]. * - * @property enableJsonResponse Determines whether the server should return JSON responses. - * Defaults to `false`. - * - * @property enableDnsRebindingProtection Enables DNS rebinding protection. - * Defaults to `false`. - * - * @property allowedHosts A list of hosts allowed for server communication. - * Defaults to `null`, allowing all hosts. - * - * @property allowedOrigins A list of allowed origins for CORS (Cross-Origin Resource Sharing). - * Defaults to `null`, allowing all origins. - * - * @property eventStore The `EventStore` instance for handling resumable events. - * Defaults to `null`, disabling resumability. - * - * @property retryInterval Retry interval for event handling or reconnection attempts. - * Defaults to `null`. + * @property enableJsonResponse when `true`, returns direct JSON responses instead of SSE streams + * @property enableDnsRebindingProtection enables DNS rebinding protection + * @property allowedHosts list of hosts allowed for server communication, or `null` to allow all + * @property allowedOrigins list of allowed CORS origins, or `null` to allow all + * @property eventStore store for resumable events, or `null` to disable resumability + * @property retryInterval retry interval for SSE reconnection attempts */ public class Configuration( public val enableJsonResponse: Boolean = false, From f5a8e3aa772569f3c89e41a083a5e485859e10c5 Mon Sep 17 00:00:00 2001 From: devcrocod Date: Mon, 30 Mar 2026 22:07:35 +0200 Subject: [PATCH 2/6] add missing KDoc comments for public classes, interfaces, and properties --- config/detekt/detekt.yml | 7 +++++++ .../kotlin/sdk/shared/Protocol.kt | 4 ++++ .../kotlin/sdk/shared/TransportSendOptions.kt | 6 ++++++ .../modelcontextprotocol/kotlin/sdk/types/content.kt | 3 +++ .../modelcontextprotocol/kotlin/sdk/types/jsonRpc.kt | 3 +++ .../modelcontextprotocol/kotlin/sdk/types/request.kt | 12 ++++++++++++ .../kotlin/sdk/types/resources.kt | 3 +++ 7 files changed, 38 insertions(+) diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index 022e80cc9..ee997c6ec 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -23,6 +23,13 @@ empty-blocks: excludes: *testFolders comments: + UndocumentedPublicClass: + active: true + excludes: [ '**/test/**', '**/commonTest/**', '**/jvmTest/**', '**/generated-sources/**' ] + ignoreDefaultCompanionObject: true + UndocumentedPublicFunction: + active: true + excludes: [ '**/test/**', '**/commonTest/**', '**/jvmTest/**', '**/generated-sources/**' ] UndocumentedPublicProperty: active: true excludes: [ '**/test/**', '**/commonTest/**', '**/jvmTest/**', '**/generated-sources/**' ] diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/Protocol.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/Protocol.kt index 5b2b6cada..43c0ae583 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/Protocol.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/Protocol.kt @@ -100,9 +100,13 @@ public class RequestOptions( public val onProgress: ProgressCallback? = null, public val timeout: Duration = DEFAULT_REQUEST_TIMEOUT, ) : TransportSendOptions(relatedRequestId, resumptionToken, onResumptionToken) { + /** Destructuring component for [onProgress]. */ public operator fun component4(): ProgressCallback? = onProgress + + /** Destructuring component for [timeout]. */ public operator fun component5(): Duration = timeout + /** Creates a copy of this [RequestOptions] with the specified fields replaced. */ public fun copy( relatedRequestId: RequestId? = this.relatedRequestId, resumptionToken: String? = this.resumptionToken, diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/TransportSendOptions.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/TransportSendOptions.kt index c56df04e9..549028881 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/TransportSendOptions.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/TransportSendOptions.kt @@ -17,10 +17,16 @@ public open class TransportSendOptions( public val resumptionToken: String? = null, public val onResumptionToken: ((String) -> Unit)? = null, ) { + /** Destructuring component for [relatedRequestId]. */ public operator fun component1(): RequestId? = relatedRequestId + + /** Destructuring component for [resumptionToken]. */ public operator fun component2(): String? = resumptionToken + + /** Destructuring component for [onResumptionToken]. */ public operator fun component3(): ((String) -> Unit)? = onResumptionToken + /** Creates a copy of this [TransportSendOptions] with the specified fields replaced. */ public open fun copy( relatedRequestId: RequestId? = this.relatedRequestId, resumptionToken: String? = this.resumptionToken, 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 9bc1887aa..a1c9e4fec 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 @@ -41,6 +41,9 @@ public sealed interface ContentBlock : WithMeta { public val type: ContentTypes } +/** + * Content block that carries media data such as text, images, or audio. + */ @Serializable(with = MediaContentPolymorphicSerializer::class) public sealed interface MediaContent : ContentBlock 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 6e25ba4f1..1a9ea2eca 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 @@ -112,6 +112,9 @@ public sealed interface JSONRPCMessage { public val jsonrpc: String } +/** + * Represents an empty JSON-RPC message used as a placeholder or no-op response. + */ @Serializable public data object JSONRPCEmptyMessage : JSONRPCMessage { override val jsonrpc: String = JSONRPC_VERSION diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/request.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/request.kt index 015369381..9f52ec9e8 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/request.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/request.kt @@ -49,6 +49,9 @@ public value class RequestMeta(public val json: JsonObject) { public operator fun get(key: String): JsonElement? = json[key] } +/** + * Base interface for parameters attached to a [Request]. + */ @Serializable public sealed interface RequestParams { /** @@ -61,6 +64,9 @@ public sealed interface RequestParams { public val meta: RequestMeta? } +/** + * Default [RequestParams] implementation carrying only optional metadata. + */ @Serializable public data class BaseRequestParams(@SerialName("_meta") override val meta: RequestMeta? = null) : RequestParams @@ -121,9 +127,15 @@ public sealed interface PaginatedRequest : Request { @Serializable(with = RequestResultPolymorphicSerializer::class) public sealed interface RequestResult : WithMeta +/** + * Represents a result returned by the server in response to a [ClientRequest]. + */ @Serializable(with = ClientResultPolymorphicSerializer::class) public sealed interface ClientResult : RequestResult +/** + * Represents a result returned by the client in response to a [ServerRequest]. + */ @Serializable(with = ServerResultPolymorphicSerializer::class) public sealed interface ServerResult : RequestResult diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/resources.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/resources.kt index fa316dec5..86ce3cee7 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/resources.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/resources.kt @@ -8,6 +8,9 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.json.JsonObject +/** + * Common interface for resource-like types that share URI, name, and description fields. + */ @Serializable public sealed interface ResourceLike : WithMeta From 078811e5ae925b6b90c7d07ba72bea6f736b2fa4 Mon Sep 17 00:00:00 2001 From: devcrocod Date: Tue, 31 Mar 2026 19:59:07 +0200 Subject: [PATCH 3/6] refactor detekt config to use testFolders alias in exclusion rules --- config/detekt/detekt.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index ee997c6ec..12426391a 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -25,13 +25,13 @@ empty-blocks: comments: UndocumentedPublicClass: active: true - excludes: [ '**/test/**', '**/commonTest/**', '**/jvmTest/**', '**/generated-sources/**' ] + excludes: [ *testFolders, '**/generated-sources/**' ] ignoreDefaultCompanionObject: true UndocumentedPublicFunction: active: true - excludes: [ '**/test/**', '**/commonTest/**', '**/jvmTest/**', '**/generated-sources/**' ] + excludes: [ *testFolders, '**/generated-sources/**' ] UndocumentedPublicProperty: active: true - excludes: [ '**/test/**', '**/commonTest/**', '**/jvmTest/**', '**/generated-sources/**' ] + excludes: [ *testFolders, '**/generated-sources/**' ] searchProtectedProperty: false ignoreEnumEntries: true From e2fc8b0c0c82760730829095d873e4e2a29369a6 Mon Sep 17 00:00:00 2001 From: devcrocod Date: Tue, 31 Mar 2026 20:15:47 +0200 Subject: [PATCH 4/6] refactor detekt config to centralize test and generated folders exclusions --- config/detekt/detekt.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index 12426391a..4d4473430 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -25,13 +25,19 @@ empty-blocks: comments: UndocumentedPublicClass: active: true - excludes: [ *testFolders, '**/generated-sources/**' ] + excludes: &testAndGeneratedFolders + - '**/test/**' + - '**/commonTest/**' + - '**/jvmTest/**' + - '**/jsTest/**' + - '**/iosTest/**' + - '**/generated-sources/**' ignoreDefaultCompanionObject: true UndocumentedPublicFunction: active: true - excludes: [ *testFolders, '**/generated-sources/**' ] + excludes: *testAndGeneratedFolders UndocumentedPublicProperty: active: true - excludes: [ *testFolders, '**/generated-sources/**' ] + excludes: *testAndGeneratedFolders searchProtectedProperty: false ignoreEnumEntries: true From e647f1373359df0c0cc5e8e89a2f6b97244d2bb4 Mon Sep 17 00:00:00 2001 From: devcrocod Date: Mon, 30 Mar 2026 21:58:19 +0200 Subject: [PATCH 5/6] enable detekt UndocumentedPublicProperty rule and add kdoc skill --- .../server/StreamableHttpServerTransport.kt | 26 +++++-------------- 1 file changed, 7 insertions(+), 19 deletions(-) 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 afb67c5f8..70948d9ce 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 @@ -125,26 +125,14 @@ public class StreamableHttpServerTransport(private val configuration: Configurat /** * Configuration options for [StreamableHttpServerTransport]. * - * @property enableJsonResponse Determines whether the server should return JSON responses. - * Defaults to `false`. - * - * @property enableDnsRebindingProtection Enables DNS rebinding protection. - * Defaults to `false`. - * - * @property allowedHosts A list of hosts allowed for server communication. - * Defaults to `null`, allowing all hosts. - * - * @property allowedOrigins A list of allowed origins for CORS (Cross-Origin Resource Sharing). - * Defaults to `null`, allowing all origins. - * - * @property eventStore The `EventStore` instance for handling resumable events. - * Defaults to `null`, disabling resumability. - * - * @property retryInterval Retry interval for event handling or reconnection attempts. - * Defaults to `null`. - * + * @property enableJsonResponse when `true`, returns direct JSON responses instead of SSE streams + * @property enableDnsRebindingProtection enables DNS rebinding protection + * @property allowedHosts list of hosts allowed for server communication, or `null` to allow all + * @property allowedOrigins list of allowed CORS origins, or `null` to allow all + * @property eventStore store for resumable events, or `null` to disable resumability + * @property retryInterval retry interval for SSE reconnection attempts * @property maxRequestBodySize Maximum allowed size (in bytes) for incoming request bodies. - * Defaults to 4 MB (4,194,304 bytes). + * Defaults to 4 MB (4,194,304 bytes). */ public class Configuration( public val enableJsonResponse: Boolean = false, From 85a5ccfc669c29044999936b614c4b9ea7160c58 Mon Sep 17 00:00:00 2001 From: devcrocod Date: Thu, 2 Apr 2026 13:42:06 +0200 Subject: [PATCH 6/6] add missing `type` and `mode` KDoc properties for schema and elicitation classes --- .../kotlin/sdk/types/elicitation.kt | 4 ++++ .../io/modelcontextprotocol/kotlin/sdk/types/schema.kt | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/elicitation.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/elicitation.kt index fc7787b49..bb303f0c6 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/elicitation.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/elicitation.kt @@ -46,6 +46,8 @@ public data class ElicitRequest(override val params: ElicitRequestParams) : Serv * Represents the parameters for an `elicitation/create` request. * * Implementations: [ElicitRequestFormParams], [ElicitRequestURLParams]. + * + * @property message The message to present to the user describing what information is being requested. */ @Serializable(with = ElicitRequestParamsSerializer::class) public sealed interface ElicitRequestParams : RequestParams { @@ -111,6 +113,7 @@ public fun ElicitRequestParams( * later via `tasks/result`. * @property requestedSchema A restricted subset of JSON Schema. Only top-level properties * are allowed, without nesting. + * @property mode The elicitation mode discriminator, always `"form"`. * @property meta Optional metadata. May include a progressToken for out-of-band progress notifications. */ @Serializable @@ -138,6 +141,7 @@ public data class ElicitRequestFormParams( * @property task If specified, the caller is requesting task-augmented execution. The request * will return a [CreateTaskResult] immediately, and the actual result can be retrieved * later via `tasks/result`. + * @property mode The elicitation mode discriminator, always `"url"`. * @property meta Optional metadata. May include a progressToken for out-of-band progress notifications. */ @Serializable diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/schema.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/schema.kt index dda2ac6d4..479cc66f0 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/schema.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/schema.kt @@ -24,6 +24,7 @@ public sealed interface PrimitiveSchemaDefinition * @property minLength Minimum string length. * @property maxLength Maximum string length. * @property format Optional format constraint (e.g., email, URI, date). + * @property type JSON Schema type discriminator, always `"string"`. * @property default Optional default value. */ @Serializable @@ -72,6 +73,7 @@ public sealed interface NumberSchemaDefinition : PrimitiveSchemaDefinition * @property description Optional description for the field. * @property minimum Minimum allowed value. * @property maximum Maximum allowed value. + * @property type JSON Schema type discriminator, always `"integer"`. * @property default Optional default value. */ @Serializable @@ -93,6 +95,7 @@ public data class IntegerSchema( * @property description Optional description for the field. * @property minimum Minimum allowed value. * @property maximum Maximum allowed value. + * @property type JSON Schema type discriminator, always `"number"`. * @property default Optional default value. */ @Serializable @@ -112,6 +115,7 @@ public data class DoubleSchema( * * @property title Optional display title for the field. * @property description Optional description for the field. + * @property type JSON Schema type discriminator, always `"boolean"`. * @property default Optional default value. */ @Serializable @@ -157,6 +161,7 @@ public sealed interface SingleSelectEnumSchema : EnumSchemaDefinition * @property title Optional display title for the field. * @property description Optional description for the field. * @property enumValues Array of enum values to choose from. + * @property type JSON Schema type discriminator, always `"string"`. * @property default Optional default value. */ @Serializable @@ -177,6 +182,7 @@ public data class UntitledSingleSelectEnumSchema( * @property title Optional display title for the field. * @property description Optional description for the field. * @property oneOf Array of enum options with values and display labels. + * @property type JSON Schema type discriminator, always `"string"`. * @property default Optional default value. */ @Serializable @@ -199,6 +205,7 @@ public data class TitledSingleSelectEnumSchema( * @property description Optional description for the field. * @property enumValues Array of enum values to choose from. * @property enumNames Display names for enum values. Non-standard according to JSON Schema 2020-12. + * @property type JSON Schema type discriminator, always `"string"`. * @property default Optional default value. */ @Deprecated("Use TitledSingleSelectEnumSchema instead") @@ -231,6 +238,7 @@ public sealed interface MultiSelectEnumSchema : EnumSchemaDefinition * @property minItems Minimum number of items to select. * @property maxItems Maximum number of items to select. * @property items Schema for the array items. + * @property type JSON Schema type discriminator, always `"array"`. * @property default Optional default value. */ @Serializable @@ -248,6 +256,7 @@ public data class UntitledMultiSelectEnumSchema( /** * Schema for the array items with plain enum values. * + * @property type JSON Schema type discriminator, always `"string"`. * @property enumValues Array of enum values to choose from. */ @Serializable @@ -268,6 +277,7 @@ public data class UntitledMultiSelectEnumSchema( * @property minItems Minimum number of items to select. * @property maxItems Maximum number of items to select. * @property items Schema for array items with enum options and display labels. + * @property type JSON Schema type discriminator, always `"array"`. * @property default Optional default value. */ @Serializable