Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
250 changes: 250 additions & 0 deletions kotlin-sdk-core/api/kotlin-sdk-core.api

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.modelcontextprotocol.kotlin.sdk.types

/**
* DSL marker annotation for MCP builder classes.
*
* This annotation is used to prevent accidental access to outer DSL scopes
* within nested DSL blocks, ensuring type-safe and unambiguous builder usage.
*
* @see DslMarker
*/
@DslMarker
public annotation class McpDsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
package io.modelcontextprotocol.kotlin.sdk.types

import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonObjectBuilder
import kotlinx.serialization.json.buildJsonObject

/**
* DSL builder for constructing [ClientCapabilities] instances.
*
* This builder is used within [InitializeRequestBuilder] to configure client capabilities.
* All capabilities are optional - the presence of a capability indicates support for that feature.
*
* ## Available Functions (all optional)
* - [sampling] - Indicates support for sampling from an LLM
* - [roots] - Indicates support for listing roots
* - [elicitation] - Indicates support for elicitation from the server
* - [experimental] - Defines experimental, non-standard capabilities
*
* Example usage within [buildInitializeRequest][buildInitializeRequest]:
* ```kotlin
* val request = buildInitializeRequest {
* protocolVersion = "1.0"
* capabilities {
* sampling(ClientCapabilities.sampling)
* roots(listChanged = true)
* experimental {
* put("customFeature", JsonPrimitive(true))
* }
* }
* info("MyClient", "1.0.0")
* }
* ```
*
* @see ClientCapabilities
* @see InitializeRequestBuilder.capabilities
*/
@McpDsl
public class ClientCapabilitiesBuilder @PublishedApi internal constructor() {
private var sampling: JsonObject? = null
private var roots: ClientCapabilities.Roots? = null
private var elicitation: JsonObject? = null
private var experimental: JsonObject? = null

/**
* Indicates that the client supports sampling from an LLM.
*
* Use [ClientCapabilities.sampling] for default empty configuration.
*
* Example:
* ```kotlin
* capabilities {
* sampling(ClientCapabilities.sampling)
* }
* ```
*
* @param value The sampling capability configuration
*/
public fun sampling(value: JsonObject) {
this.sampling = value
}

/**
* Indicates that the client supports sampling from an LLM with custom configuration.
*
* Example:
* ```kotlin
* capabilities {
* sampling {
* put("temperature", JsonPrimitive(0.7))
* }
* }
* ```
*
* @param block Lambda for building the sampling configuration
*/
public fun sampling(block: JsonObjectBuilder.() -> Unit): Unit = sampling(buildJsonObject(block))

/**
* Indicates that the client supports listing roots.
*
* Example with listChanged notification:
* ```kotlin
* capabilities {
* roots(listChanged = true)
* }
* ```
*
* Example without listChanged:
* ```kotlin
* capabilities {
* roots()
* }
* ```
*
* @param listChanged Whether the client will emit notifications when the list of roots changes
*/
public fun roots(listChanged: Boolean? = null) {
this.roots = ClientCapabilities.Roots(listChanged)
}

/**
* Indicates that the client supports elicitation from the server.
*
* Use [ClientCapabilities.elicitation] for default empty configuration.
*
* Example:
* ```kotlin
* capabilities {
* elicitation(ClientCapabilities.elicitation)
* }
* ```
*
* @param value The elicitation capability configuration
*/
public fun elicitation(value: JsonObject) {
this.elicitation = value
}

/**
* Indicates that the client supports elicitation from the server with custom configuration.
*
* Example:
* ```kotlin
* capabilities {
* elicitation {
* put("mode", JsonPrimitive("interactive"))
* }
* }
* ```
*
* @param block Lambda for building the elicitation configuration
*/
public fun elicitation(block: JsonObjectBuilder.() -> Unit): Unit = elicitation(buildJsonObject(block))

/**
* Defines experimental, non-standard capabilities that the client supports.
*
* Example:
* ```kotlin
* capabilities {
* experimental(buildJsonObject {
* put("customFeature", JsonPrimitive(true))
* put("version", JsonPrimitive("1.0"))
* })
* }
* ```
*
* @param value The experimental capabilities configuration
*/
public fun experimental(value: JsonObject) {
this.experimental = value
}

/**
* Defines experimental, non-standard capabilities that the client supports using a DSL builder.
*
* Example:
* ```kotlin
* capabilities {
* experimental {
* put("customFeature", JsonPrimitive(true))
* put("beta", JsonObject(mapOf(
* "enabled" to JsonPrimitive(true),
* "version" to JsonPrimitive("2.0")
* )))
* }
* }
* ```
*
* @param block Lambda for building the experimental capabilities configuration
*/
public fun experimental(block: JsonObjectBuilder.() -> Unit): Unit = experimental(buildJsonObject(block))

@PublishedApi
internal fun build(): ClientCapabilities = ClientCapabilities(
sampling = sampling,
roots = roots,
elicitation = elicitation,
experimental = experimental,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
package io.modelcontextprotocol.kotlin.sdk.types

import io.modelcontextprotocol.kotlin.sdk.ExperimentalMcpApi
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract

/**
* Creates a [CompleteRequest] using a type-safe DSL builder.
*
* ## Required
* - [argument][CompleteRequestBuilder.argument] - Sets the argument name and value to complete
* - [ref][CompleteRequestBuilder.ref] - Sets the reference to a prompt or resource template
*
* ## Optional
* - [context][CompleteRequestBuilder.context] - Adds additional context for the completion
* - [meta][CompleteRequestBuilder.meta] - Adds metadata to the request
*
* Example with [PromptReference]:
* ```kotlin
* val request = buildCompleteRequest {
* argument("query", "user input")
* ref(PromptReference("searchPrompt"))
* }
* ```
*
* Example with [ResourceTemplateReference]:
* ```kotlin
* val request = buildCompleteRequest {
* argument("path", "/users/123")
* ref(ResourceTemplateReference("file:///{path}"))
* context {
* put("userId", "123")
* put("role", "admin")
* }
* }
* ```
*
* @param block Configuration lambda for setting up the completion request
* @return A configured [CompleteRequest] instance
* @see CompleteRequestBuilder
*/
@OptIn(ExperimentalContracts::class)
@ExperimentalMcpApi
internal inline fun buildCompleteRequest(block: CompleteRequestBuilder.() -> Unit): CompleteRequest {
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
return CompleteRequestBuilder().apply(block).build()
}

/**
* DSL builder for constructing [CompleteRequest] instances.
*
* This builder provides methods to configure completion requests for prompts or resource templates.
* Both [argument] and [ref] are required; [context] is optional.
*
* @see buildCompleteRequest
*/
@McpDsl
public class CompleteRequestBuilder @PublishedApi internal constructor() : RequestBuilder() {
private var arg: CompleteRequestParams.Argument? = null
private var ref: Reference? = null
private var ctx: CompleteRequestParams.Context? = null

/**
* Sets the argument for completion.
*
* This method specifies the name and value of the argument to be completed.
* This is a required field and must be called exactly once.
*
* Example:
* ```kotlin
* completeRequest {
* argument("query", "SELECT * FROM use")
* // ... other configuration
* }
* ```
*
* @param name The name of the argument to complete
* @param value The partial or full value of the argument
*/
public fun argument(name: String, value: String) {
arg = CompleteRequestParams.Argument(name, value)
}

/**
* Sets the reference to a prompt or resource template.
*
* This method specifies which prompt or resource template the completion request refers to.
*
* Example with prompt:
* ```kotlin
* completeRequest {
* ref(PromptReference("sqlQuery", "SQL Query Builder"))
* // ... other configuration
* }
* ```
*
* Example with resource template:
* ```kotlin
* completeRequest {
* ref(ResourceTemplateReference("file:///{path}"))
* // ... other configuration
* }
* ```
*
* @param value The [Reference] (either [PromptReference] or [ResourceTemplateReference])
*/
public fun ref(value: Reference) {
ref = value
}

/**
* Sets additional context for the completion request using a Map.
*
* This method allows providing additional key-value pairs that may be relevant
* for generating completions. This is an optional field.
*
* Example:
* ```kotlin
* completeRequest {
* context(mapOf("userId" to "123", "role" to "admin"))
* // ... other configuration
* }
* ```
*
* @param arguments A map of context key-value pairs
*/
public fun context(arguments: Map<String, String>) {
ctx = CompleteRequestParams.Context(arguments)
}

/**
* Sets additional context for the completion request using a DSL builder.
*
* This method allows providing additional key-value pairs that may be relevant
* for generating completions using a type-safe builder syntax. This is an optional field.
*
* Example:
* ```kotlin
* completeRequest {
* context {
* put("userId", "123")
* put("role", "admin")
* put("environment", "production")
* }
* // ... other configuration
* }
* ```
*
* @param block Lambda with receiver for building the context map
*/
public fun context(block: MutableMap<String, String>.() -> Unit) {
ctx = CompleteRequestParams.Context(buildMap(block))
}

@PublishedApi
override fun build(): CompleteRequest {
val argument = requireNotNull(arg) {
"Missing required field 'argument(name, value)'. Example: argument(\"query\", \"user input\")"
}

val reference = requireNotNull(ref) {
"Missing required field 'ref(Reference)'. Use ref(PromptReference(\"name\")) or ref(ResourceTemplateReference(\"uri\"))"
}

val params = CompleteRequestParams(argument = argument, ref = reference, context = ctx, meta = meta)
return CompleteRequest(params)
}
}
Loading
Loading