diff --git a/kotlin-sdk-core/api/kotlin-sdk-core.api b/kotlin-sdk-core/api/kotlin-sdk-core.api index fa85476f..def7e8be 100644 --- a/kotlin-sdk-core/api/kotlin-sdk-core.api +++ b/kotlin-sdk-core/api/kotlin-sdk-core.api @@ -581,6 +581,15 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/AudioContent$Compani public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/AudioContentBuilder : io/modelcontextprotocol/kotlin/sdk/types/MediaContentBuilder { + public fun ()V + public synthetic fun build ()Lio/modelcontextprotocol/kotlin/sdk/types/MediaContent; + public final fun getData ()Ljava/lang/String; + public final fun getMimeType ()Ljava/lang/String; + public final fun setData (Ljava/lang/String;)V + public final fun setMimeType (Ljava/lang/String;)V +} + public final class io/modelcontextprotocol/kotlin/sdk/types/BaseNotificationParams : io/modelcontextprotocol/kotlin/sdk/types/NotificationParams { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/BaseNotificationParams$Companion; public fun ()V @@ -706,6 +715,16 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/CallToolRequest$Comp public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/CallToolRequestBuilder : io/modelcontextprotocol/kotlin/sdk/types/RequestBuilder { + public fun ()V + public final fun arguments (Lkotlin/jvm/functions/Function1;)V + public final fun arguments (Lkotlinx/serialization/json/JsonObject;)V + public fun build ()Lio/modelcontextprotocol/kotlin/sdk/types/CallToolRequest; + public synthetic fun build$kotlin_sdk_core ()Lio/modelcontextprotocol/kotlin/sdk/types/Request; + public final fun getName ()Ljava/lang/String; + public final fun setName (Ljava/lang/String;)V +} + public final class io/modelcontextprotocol/kotlin/sdk/types/CallToolRequestParams : io/modelcontextprotocol/kotlin/sdk/types/RequestParams { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/CallToolRequestParams$Companion; public synthetic fun (Ljava/lang/String;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;ILkotlin/jvm/internal/DefaultConstructorMarker;)V @@ -904,6 +923,19 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/ClientCapabilities$R public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/ClientCapabilitiesBuilder { + public fun ()V + public final fun build ()Lio/modelcontextprotocol/kotlin/sdk/types/ClientCapabilities; + public final fun elicitation (Lkotlin/jvm/functions/Function1;)V + public final fun elicitation (Lkotlinx/serialization/json/JsonObject;)V + public final fun experimental (Lkotlin/jvm/functions/Function1;)V + public final fun experimental (Lkotlinx/serialization/json/JsonObject;)V + public final fun roots (Ljava/lang/Boolean;)V + public static synthetic fun roots$default (Lio/modelcontextprotocol/kotlin/sdk/types/ClientCapabilitiesBuilder;Ljava/lang/Boolean;ILjava/lang/Object;)V + public final fun sampling (Lkotlin/jvm/functions/Function1;)V + public final fun sampling (Lkotlinx/serialization/json/JsonObject;)V +} + public abstract interface class io/modelcontextprotocol/kotlin/sdk/types/ClientNotification : io/modelcontextprotocol/kotlin/sdk/types/Notification { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/ClientNotification$Companion; } @@ -974,6 +1006,16 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/CompleteRequest$Comp public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/CompleteRequestBuilder : io/modelcontextprotocol/kotlin/sdk/types/RequestBuilder { + public fun ()V + public final fun argument (Ljava/lang/String;Ljava/lang/String;)V + public fun build ()Lio/modelcontextprotocol/kotlin/sdk/types/CompleteRequest; + public synthetic fun build$kotlin_sdk_core ()Lio/modelcontextprotocol/kotlin/sdk/types/Request; + public final fun context (Ljava/util/Map;)V + public final fun context (Lkotlin/jvm/functions/Function1;)V + public final fun ref (Lio/modelcontextprotocol/kotlin/sdk/types/Reference;)V +} + public final class io/modelcontextprotocol/kotlin/sdk/types/CompleteRequestParams : io/modelcontextprotocol/kotlin/sdk/types/RequestParams { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/CompleteRequestParams$Companion; public synthetic fun (Lio/modelcontextprotocol/kotlin/sdk/types/CompleteRequestParams$Argument;Lio/modelcontextprotocol/kotlin/sdk/types/Reference;Lio/modelcontextprotocol/kotlin/sdk/types/CompleteRequestParams$Context;Lkotlinx/serialization/json/JsonObject;ILkotlin/jvm/internal/DefaultConstructorMarker;)V @@ -1197,6 +1239,28 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/CreateMessageRequest public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/CreateMessageRequestBuilder : io/modelcontextprotocol/kotlin/sdk/types/RequestBuilder { + public fun ()V + public fun build ()Lio/modelcontextprotocol/kotlin/sdk/types/CreateMessageRequest; + public synthetic fun build$kotlin_sdk_core ()Lio/modelcontextprotocol/kotlin/sdk/types/Request; + public final fun getContext ()Lio/modelcontextprotocol/kotlin/sdk/types/IncludeContext; + public final fun getMaxTokens ()Ljava/lang/Integer; + public final fun getStopSequences ()Ljava/util/List; + public final fun getSystemPrompt ()Ljava/lang/String; + public final fun getTemperature ()Ljava/lang/Double; + public final fun messages (Ljava/util/List;)V + public final fun messages (Lkotlin/jvm/functions/Function1;)V + public final fun metadata (Lkotlin/jvm/functions/Function1;)V + public final fun preferences (Lio/modelcontextprotocol/kotlin/sdk/types/ModelPreferences;)V + public final fun preferences (Ljava/util/List;Ljava/lang/Double;Ljava/lang/Double;Ljava/lang/Double;)V + public static synthetic fun preferences$default (Lio/modelcontextprotocol/kotlin/sdk/types/CreateMessageRequestBuilder;Ljava/util/List;Ljava/lang/Double;Ljava/lang/Double;Ljava/lang/Double;ILjava/lang/Object;)V + public final fun setContext (Lio/modelcontextprotocol/kotlin/sdk/types/IncludeContext;)V + public final fun setMaxTokens (Ljava/lang/Integer;)V + public final fun setStopSequences (Ljava/util/List;)V + public final fun setSystemPrompt (Ljava/lang/String;)V + public final fun setTemperature (Ljava/lang/Double;)V +} + public final class io/modelcontextprotocol/kotlin/sdk/types/CreateMessageRequestParams : io/modelcontextprotocol/kotlin/sdk/types/RequestParams { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/CreateMessageRequestParams$Companion; public synthetic fun (ILjava/util/List;Lio/modelcontextprotocol/kotlin/sdk/types/ModelPreferences;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/IncludeContext;Ljava/lang/Double;Ljava/util/List;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;ILkotlin/jvm/internal/DefaultConstructorMarker;)V @@ -1367,6 +1431,16 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/ElicitRequest$Compan public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/ElicitRequestBuilder : io/modelcontextprotocol/kotlin/sdk/types/RequestBuilder { + public fun ()V + public fun build ()Lio/modelcontextprotocol/kotlin/sdk/types/ElicitRequest; + public synthetic fun build$kotlin_sdk_core ()Lio/modelcontextprotocol/kotlin/sdk/types/Request; + public final fun getMessage ()Ljava/lang/String; + public final fun requestedSchema (Lio/modelcontextprotocol/kotlin/sdk/types/ElicitRequestParams$RequestedSchema;)V + public final fun requestedSchema (Lkotlin/jvm/functions/Function1;)V + public final fun setMessage (Ljava/lang/String;)V +} + public final class io/modelcontextprotocol/kotlin/sdk/types/ElicitRequestParams : io/modelcontextprotocol/kotlin/sdk/types/RequestParams { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/ElicitRequestParams$Companion; public synthetic fun (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ElicitRequestParams$RequestedSchema;Lkotlinx/serialization/json/JsonObject;ILkotlin/jvm/internal/DefaultConstructorMarker;)V @@ -1430,6 +1504,15 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/ElicitRequestParams$ public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/ElicitRequestedSchemaBuilder { + public fun ()V + public final fun build ()Lio/modelcontextprotocol/kotlin/sdk/types/ElicitRequestParams$RequestedSchema; + public final fun getRequired ()Ljava/util/List; + public final fun properties (Lkotlin/jvm/functions/Function1;)V + public final fun properties (Lkotlinx/serialization/json/JsonObject;)V + public final fun setRequired (Ljava/util/List;)V +} + public final class io/modelcontextprotocol/kotlin/sdk/types/ElicitResult : io/modelcontextprotocol/kotlin/sdk/types/ClientResult { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/ElicitResult$Companion; public fun (Lio/modelcontextprotocol/kotlin/sdk/types/ElicitResult$Action;Lkotlinx/serialization/json/JsonObject;Lkotlinx/serialization/json/JsonObject;)V @@ -1575,6 +1658,16 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/GetPromptRequest$Com public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/GetPromptRequestBuilder : io/modelcontextprotocol/kotlin/sdk/types/RequestBuilder { + public fun ()V + public fun build ()Lio/modelcontextprotocol/kotlin/sdk/types/GetPromptRequest; + public synthetic fun build$kotlin_sdk_core ()Lio/modelcontextprotocol/kotlin/sdk/types/Request; + public final fun getArguments ()Ljava/util/Map; + public final fun getName ()Ljava/lang/String; + public final fun setArguments (Ljava/util/Map;)V + public final fun setName (Ljava/lang/String;)V +} + public final class io/modelcontextprotocol/kotlin/sdk/types/GetPromptRequestParams : io/modelcontextprotocol/kotlin/sdk/types/RequestParams { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/GetPromptRequestParams$Companion; public synthetic fun (Ljava/lang/String;Ljava/util/Map;Lkotlinx/serialization/json/JsonObject;ILkotlin/jvm/internal/DefaultConstructorMarker;)V @@ -1723,6 +1816,15 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/ImageContent$Compani public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/ImageContentBuilder : io/modelcontextprotocol/kotlin/sdk/types/MediaContentBuilder { + public fun ()V + public synthetic fun build ()Lio/modelcontextprotocol/kotlin/sdk/types/MediaContent; + public final fun getData ()Ljava/lang/String; + public final fun getMimeType ()Ljava/lang/String; + public final fun setData (Ljava/lang/String;)V + public final fun setMimeType (Ljava/lang/String;)V +} + public final class io/modelcontextprotocol/kotlin/sdk/types/Implementation { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/Implementation$Companion; public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)V @@ -1806,6 +1908,19 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/InitializeRequest$Co public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/InitializeRequestBuilder : io/modelcontextprotocol/kotlin/sdk/types/RequestBuilder { + public fun ()V + public fun build ()Lio/modelcontextprotocol/kotlin/sdk/types/InitializeRequest; + public synthetic fun build$kotlin_sdk_core ()Lio/modelcontextprotocol/kotlin/sdk/types/Request; + public final fun capabilities (Lio/modelcontextprotocol/kotlin/sdk/types/ClientCapabilities;)V + public final fun capabilities (Lkotlin/jvm/functions/Function1;)V + public final fun getProtocolVersion ()Ljava/lang/String; + public final fun info (Lio/modelcontextprotocol/kotlin/sdk/types/Implementation;)V + public final fun info (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)V + public static synthetic fun info$default (Lio/modelcontextprotocol/kotlin/sdk/types/InitializeRequestBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;ILjava/lang/Object;)V + public final fun setProtocolVersion (Ljava/lang/String;)V +} + public final class io/modelcontextprotocol/kotlin/sdk/types/InitializeRequestParams : io/modelcontextprotocol/kotlin/sdk/types/RequestParams { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/InitializeRequestParams$Companion; public synthetic fun (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ClientCapabilities;Lio/modelcontextprotocol/kotlin/sdk/types/Implementation;Lkotlinx/serialization/json/JsonObject;ILkotlin/jvm/internal/DefaultConstructorMarker;)V @@ -2092,6 +2207,12 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/ListPromptsRequest$C public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/ListPromptsRequestBuilder : io/modelcontextprotocol/kotlin/sdk/types/PaginatedRequestBuilder { + public fun ()V + public fun build ()Lio/modelcontextprotocol/kotlin/sdk/types/ListPromptsRequest; + public synthetic fun build$kotlin_sdk_core ()Lio/modelcontextprotocol/kotlin/sdk/types/Request; +} + public final class io/modelcontextprotocol/kotlin/sdk/types/ListPromptsResult : io/modelcontextprotocol/kotlin/sdk/types/PaginatedResult, io/modelcontextprotocol/kotlin/sdk/types/ServerResult { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/ListPromptsResult$Companion; public fun (Ljava/util/List;Ljava/lang/String;Lkotlinx/serialization/json/JsonObject;)V @@ -2160,6 +2281,12 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/ListResourceTemplate public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/ListResourceTemplatesRequestBuilder : io/modelcontextprotocol/kotlin/sdk/types/PaginatedRequestBuilder { + public fun ()V + public fun build ()Lio/modelcontextprotocol/kotlin/sdk/types/ListResourceTemplatesRequest; + public synthetic fun build$kotlin_sdk_core ()Lio/modelcontextprotocol/kotlin/sdk/types/Request; +} + public final class io/modelcontextprotocol/kotlin/sdk/types/ListResourceTemplatesResult : io/modelcontextprotocol/kotlin/sdk/types/PaginatedResult, io/modelcontextprotocol/kotlin/sdk/types/ServerResult { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/ListResourceTemplatesResult$Companion; public fun (Ljava/util/List;Ljava/lang/String;Lkotlinx/serialization/json/JsonObject;)V @@ -2228,6 +2355,12 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/ListResourcesRequest public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/ListResourcesRequestBuilder : io/modelcontextprotocol/kotlin/sdk/types/PaginatedRequestBuilder { + public fun ()V + public fun build ()Lio/modelcontextprotocol/kotlin/sdk/types/ListResourcesRequest; + public synthetic fun build$kotlin_sdk_core ()Lio/modelcontextprotocol/kotlin/sdk/types/Request; +} + public final class io/modelcontextprotocol/kotlin/sdk/types/ListResourcesResult : io/modelcontextprotocol/kotlin/sdk/types/PaginatedResult, io/modelcontextprotocol/kotlin/sdk/types/ServerResult { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/ListResourcesResult$Companion; public fun (Ljava/util/List;Ljava/lang/String;Lkotlinx/serialization/json/JsonObject;)V @@ -2294,6 +2427,12 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/ListRootsRequest$Com public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/ListRootsRequestBuilder : io/modelcontextprotocol/kotlin/sdk/types/RequestBuilder { + public fun ()V + public fun build ()Lio/modelcontextprotocol/kotlin/sdk/types/ListRootsRequest; + public synthetic fun build$kotlin_sdk_core ()Lio/modelcontextprotocol/kotlin/sdk/types/Request; +} + public final class io/modelcontextprotocol/kotlin/sdk/types/ListRootsResult : io/modelcontextprotocol/kotlin/sdk/types/ClientResult { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/ListRootsResult$Companion; public fun (Ljava/util/List;Lkotlinx/serialization/json/JsonObject;)V @@ -2360,6 +2499,12 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/ListToolsRequest$Com public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/ListToolsRequestBuilder : io/modelcontextprotocol/kotlin/sdk/types/PaginatedRequestBuilder { + public fun ()V + public fun build ()Lio/modelcontextprotocol/kotlin/sdk/types/ListToolsRequest; + public synthetic fun build$kotlin_sdk_core ()Lio/modelcontextprotocol/kotlin/sdk/types/Request; +} + public final class io/modelcontextprotocol/kotlin/sdk/types/ListToolsResult : io/modelcontextprotocol/kotlin/sdk/types/PaginatedResult, io/modelcontextprotocol/kotlin/sdk/types/ServerResult { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/ListToolsResult$Companion; public fun (Ljava/util/List;Ljava/lang/String;Lkotlinx/serialization/json/JsonObject;)V @@ -2476,6 +2621,9 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/LoggingMessageNotifi public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public abstract interface annotation class io/modelcontextprotocol/kotlin/sdk/types/McpDsl : java/lang/annotation/Annotation { +} + public final class io/modelcontextprotocol/kotlin/sdk/types/McpException : java/lang/Exception { public fun (ILjava/lang/String;Lkotlinx/serialization/json/JsonElement;)V public synthetic fun (ILjava/lang/String;Lkotlinx/serialization/json/JsonElement;ILkotlin/jvm/internal/DefaultConstructorMarker;)V @@ -2496,6 +2644,19 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/MediaContent$Default public static fun get_meta (Lio/modelcontextprotocol/kotlin/sdk/types/MediaContent;)Lkotlinx/serialization/json/JsonObject; } +public abstract class io/modelcontextprotocol/kotlin/sdk/types/MediaContentBuilder { + public fun ()V + public final fun annotations (Lio/modelcontextprotocol/kotlin/sdk/types/Annotations;)V + public final fun annotations (Ljava/util/List;Ljava/lang/Double;Ljava/lang/String;)V + public static synthetic fun annotations$default (Lio/modelcontextprotocol/kotlin/sdk/types/MediaContentBuilder;Ljava/util/List;Ljava/lang/Double;Ljava/lang/String;ILjava/lang/Object;)V + public abstract fun build ()Lio/modelcontextprotocol/kotlin/sdk/types/MediaContent; + protected final fun getAnnotations ()Lio/modelcontextprotocol/kotlin/sdk/types/Annotations; + protected final fun getMeta ()Lkotlinx/serialization/json/JsonObject; + public final fun meta (Lkotlin/jvm/functions/Function1;)V + protected final fun setAnnotations (Lio/modelcontextprotocol/kotlin/sdk/types/Annotations;)V + protected final fun setMeta (Lkotlinx/serialization/json/JsonObject;)V +} + public abstract interface class io/modelcontextprotocol/kotlin/sdk/types/Method { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/Method$Companion; public abstract fun getValue ()Ljava/lang/String; @@ -2669,6 +2830,12 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/PaginatedRequest$Def public static fun getMeta-VI-3G7E (Lio/modelcontextprotocol/kotlin/sdk/types/PaginatedRequest;)Lkotlinx/serialization/json/JsonObject; } +public abstract class io/modelcontextprotocol/kotlin/sdk/types/PaginatedRequestBuilder : io/modelcontextprotocol/kotlin/sdk/types/RequestBuilder { + public fun ()V + public final fun getCursor ()Ljava/lang/String; + public final fun setCursor (Ljava/lang/String;)V +} + public final class io/modelcontextprotocol/kotlin/sdk/types/PaginatedRequestParams : io/modelcontextprotocol/kotlin/sdk/types/RequestParams { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/PaginatedRequestParams$Companion; public synthetic fun (Ljava/lang/String;Lkotlinx/serialization/json/JsonObject;ILkotlin/jvm/internal/DefaultConstructorMarker;)V @@ -2744,6 +2911,12 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/PingRequest$Companio public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/PingRequestBuilder : io/modelcontextprotocol/kotlin/sdk/types/RequestBuilder { + public fun ()V + public fun build ()Lio/modelcontextprotocol/kotlin/sdk/types/PingRequest; + public synthetic fun build$kotlin_sdk_core ()Lio/modelcontextprotocol/kotlin/sdk/types/Request; +} + public final class io/modelcontextprotocol/kotlin/sdk/types/Progress { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/Progress$Companion; public fun (DLjava/lang/Double;Ljava/lang/String;)V @@ -3074,6 +3247,14 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/ReadResourceRequest$ public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/ReadResourceRequestBuilder : io/modelcontextprotocol/kotlin/sdk/types/RequestBuilder { + public fun ()V + public fun build ()Lio/modelcontextprotocol/kotlin/sdk/types/ReadResourceRequest; + public synthetic fun build$kotlin_sdk_core ()Lio/modelcontextprotocol/kotlin/sdk/types/Request; + public final fun getUri ()Ljava/lang/String; + public final fun setUri (Ljava/lang/String;)V +} + public final class io/modelcontextprotocol/kotlin/sdk/types/ReadResourceRequestParams : io/modelcontextprotocol/kotlin/sdk/types/RequestParams { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/ReadResourceRequestParams$Companion; public synthetic fun (Ljava/lang/String;Lkotlinx/serialization/json/JsonObject;ILkotlin/jvm/internal/DefaultConstructorMarker;)V @@ -3168,6 +3349,13 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/Request$Companion { public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public abstract class io/modelcontextprotocol/kotlin/sdk/types/RequestBuilder { + public fun ()V + protected final fun getMeta-VI-3G7E ()Lkotlinx/serialization/json/JsonObject; + public final fun meta (Lkotlin/jvm/functions/Function1;)V + protected final fun setMeta-mJxasco (Lkotlinx/serialization/json/JsonObject;)V +} + public abstract interface class io/modelcontextprotocol/kotlin/sdk/types/RequestId { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/RequestId$Companion; } @@ -3268,6 +3456,19 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/RequestMeta$Companio public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/RequestMetaBuilder { + public final fun progressToken (I)V + public final fun progressToken (J)V + public final fun progressToken (Ljava/lang/String;)V + public final fun put (Ljava/lang/String;Ljava/lang/Number;)Lkotlinx/serialization/json/JsonElement; + public final fun put (Ljava/lang/String;Ljava/lang/String;)Lkotlinx/serialization/json/JsonElement; + public final fun put (Ljava/lang/String;Ljava/lang/Void;)Lkotlinx/serialization/json/JsonElement; + public final fun put (Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;)Lkotlinx/serialization/json/JsonElement; + public final fun put (Ljava/lang/String;Z)Lkotlinx/serialization/json/JsonElement; + public final fun putJsonArray (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lkotlinx/serialization/json/JsonElement; + public final fun putJsonObject (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lkotlinx/serialization/json/JsonElement; +} + public abstract interface class io/modelcontextprotocol/kotlin/sdk/types/RequestParams { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/RequestParams$Companion; public abstract fun getMeta-VI-3G7E ()Lkotlinx/serialization/json/JsonObject; @@ -3674,6 +3875,24 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/SamplingMessage$Comp public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/SamplingMessageBuilder { + public fun ()V + public final fun assistant (Lio/modelcontextprotocol/kotlin/sdk/types/MediaContent;)V + public final fun build ()Ljava/util/List; + public final fun user (Lio/modelcontextprotocol/kotlin/sdk/types/MediaContent;)V +} + +public final class io/modelcontextprotocol/kotlin/sdk/types/Sampling_dslKt { + public static final fun assistant (Lio/modelcontextprotocol/kotlin/sdk/types/SamplingMessageBuilder;Lkotlin/jvm/functions/Function0;)V + public static final fun assistantAudio (Lio/modelcontextprotocol/kotlin/sdk/types/SamplingMessageBuilder;Lkotlin/jvm/functions/Function1;)V + public static final fun assistantImage (Lio/modelcontextprotocol/kotlin/sdk/types/SamplingMessageBuilder;Lkotlin/jvm/functions/Function1;)V + public static final fun assistantText (Lio/modelcontextprotocol/kotlin/sdk/types/SamplingMessageBuilder;Lkotlin/jvm/functions/Function1;)V + public static final fun user (Lio/modelcontextprotocol/kotlin/sdk/types/SamplingMessageBuilder;Lkotlin/jvm/functions/Function0;)V + public static final fun userAudio (Lio/modelcontextprotocol/kotlin/sdk/types/SamplingMessageBuilder;Lkotlin/jvm/functions/Function1;)V + public static final fun userImage (Lio/modelcontextprotocol/kotlin/sdk/types/SamplingMessageBuilder;Lkotlin/jvm/functions/Function1;)V + public static final fun userText (Lio/modelcontextprotocol/kotlin/sdk/types/SamplingMessageBuilder;Lkotlin/jvm/functions/Function1;)V +} + public final class io/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/ServerCapabilities$Companion; public fun ()V @@ -3863,6 +4082,14 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/SetLevelRequest$Comp public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/SetLevelRequestBuilder : io/modelcontextprotocol/kotlin/sdk/types/RequestBuilder { + public fun ()V + public fun build ()Lio/modelcontextprotocol/kotlin/sdk/types/SetLevelRequest; + public synthetic fun build$kotlin_sdk_core ()Lio/modelcontextprotocol/kotlin/sdk/types/Request; + public final fun getLoggingLevel ()Lio/modelcontextprotocol/kotlin/sdk/types/LoggingLevel; + public final fun setLoggingLevel (Lio/modelcontextprotocol/kotlin/sdk/types/LoggingLevel;)V +} + public final class io/modelcontextprotocol/kotlin/sdk/types/SetLevelRequestParams : io/modelcontextprotocol/kotlin/sdk/types/RequestParams { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/SetLevelRequestParams$Companion; public synthetic fun (Lio/modelcontextprotocol/kotlin/sdk/types/LoggingLevel;Lkotlinx/serialization/json/JsonObject;ILkotlin/jvm/internal/DefaultConstructorMarker;)V @@ -3959,6 +4186,14 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/SubscribeRequest$Com public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/SubscribeRequestBuilder : io/modelcontextprotocol/kotlin/sdk/types/RequestBuilder { + public fun ()V + public fun build ()Lio/modelcontextprotocol/kotlin/sdk/types/SubscribeRequest; + public synthetic fun build$kotlin_sdk_core ()Lio/modelcontextprotocol/kotlin/sdk/types/Request; + public final fun getUri ()Ljava/lang/String; + public final fun setUri (Ljava/lang/String;)V +} + public final class io/modelcontextprotocol/kotlin/sdk/types/SubscribeRequestParams : io/modelcontextprotocol/kotlin/sdk/types/RequestParams { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/SubscribeRequestParams$Companion; public synthetic fun (Ljava/lang/String;Lkotlinx/serialization/json/JsonObject;ILkotlin/jvm/internal/DefaultConstructorMarker;)V @@ -4023,6 +4258,13 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/TextContent$Companio public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/TextContentBuilder : io/modelcontextprotocol/kotlin/sdk/types/MediaContentBuilder { + public fun ()V + public synthetic fun build ()Lio/modelcontextprotocol/kotlin/sdk/types/MediaContent; + public final fun getText ()Ljava/lang/String; + public final fun setText (Ljava/lang/String;)V +} + public final class io/modelcontextprotocol/kotlin/sdk/types/TextResourceContents : io/modelcontextprotocol/kotlin/sdk/types/ResourceContents { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/TextResourceContents$Companion; public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/json/JsonObject;)V @@ -4274,6 +4516,14 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/UnsubscribeRequest$C public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class io/modelcontextprotocol/kotlin/sdk/types/UnsubscribeRequestBuilder : io/modelcontextprotocol/kotlin/sdk/types/RequestBuilder { + public fun ()V + public fun build ()Lio/modelcontextprotocol/kotlin/sdk/types/UnsubscribeRequest; + public synthetic fun build$kotlin_sdk_core ()Lio/modelcontextprotocol/kotlin/sdk/types/Request; + public final fun getUri ()Ljava/lang/String; + public final fun setUri (Ljava/lang/String;)V +} + public final class io/modelcontextprotocol/kotlin/sdk/types/UnsubscribeRequestParams : io/modelcontextprotocol/kotlin/sdk/types/RequestParams { public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/UnsubscribeRequestParams$Companion; public synthetic fun (Ljava/lang/String;Lkotlinx/serialization/json/JsonObject;ILkotlin/jvm/internal/DefaultConstructorMarker;)V diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/McpDsl.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/McpDsl.kt new file mode 100644 index 00000000..3c5e3ede --- /dev/null +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/McpDsl.kt @@ -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 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 new file mode 100644 index 00000000..b132a5ed --- /dev/null +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/capabilities.dsl.kt @@ -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, + ) +} diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/completion.dsl.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/completion.dsl.kt new file mode 100644 index 00000000..dbefd314 --- /dev/null +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/completion.dsl.kt @@ -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) { + 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.() -> 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) + } +} 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 new file mode 100644 index 00000000..e538af57 --- /dev/null +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/content.dsl.kt @@ -0,0 +1,272 @@ +package io.modelcontextprotocol.kotlin.sdk.types + +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonObjectBuilder +import kotlinx.serialization.json.buildJsonObject + +/** + * Base DSL builder for constructing [MediaContent] instances. + * + * This abstract class provides common functionality for all media content builders: + * - [annotations] - Optional metadata annotations + * - [meta] - Optional additional metadata + * + * Concrete implementations: + * - [TextContentBuilder] - For text content + * - [ImageContentBuilder] - For image content (base64-encoded) + * - [AudioContentBuilder] - For audio content (base64-encoded) + * + * @see TextContentBuilder + * @see ImageContentBuilder + * @see AudioContentBuilder + */ +@McpDsl +public abstract class MediaContentBuilder { + protected var annotations: Annotations? = null + protected var meta: JsonObject? = null + + /** + * Sets optional annotations for the content. + * + * Annotations provide additional metadata about the content such as audience, + * priority, and last modification time. + * + * Example: + * ```kotlin + * userText { + * text = "Hello" + * annotations(Annotations(priority = 0.8)) + * } + * ``` + * + * @param annotations The [Annotations] instance + */ + public fun annotations(annotations: Annotations) { + this.annotations = annotations + } + + /** + * Sets optional annotations for the content with individual parameters. + * + * Example with all parameters: + * ```kotlin + * userText { + * text = "Important update" + * annotations( + * audience = listOf(Role.User, Role.Assistant), + * priority = 0.8, + * lastModified = "2025-01-12T15:00:58Z" + * ) + * } + * ``` + * + * @param audience The intended audience for this content (list of [Role]) + * @param priority Priority hint for this content (0.0 to 1.0) + * @param lastModified ISO 8601 timestamp of the last modification + * @see Annotations + */ + public fun annotations(audience: List? = null, priority: Double? = null, lastModified: String? = null) { + this.annotations = Annotations(audience, priority, lastModified) + } + + /** + * Sets optional metadata for the content using a DSL builder. + * + * Example: + * ```kotlin + * userText { + * text = "Hello" + * meta { + * put("source", JsonPrimitive("user-input")) + * } + * } + * ``` + * + * @param block Lambda for building the metadata + */ + public fun meta(block: JsonObjectBuilder.() -> Unit) { + meta = buildJsonObject(block) + } + + @PublishedApi + internal abstract fun build(): MediaContent +} + +/** + * DSL builder for constructing [TextContent] instances. + * + * ## Required + * - [text] - The text content string + * + * ## Optional + * - [annotations] - Content annotations (inherited from [MediaContentBuilder]) + * - [meta] - Additional metadata (inherited from [MediaContentBuilder]) + * + * Example usage in sampling messages: + * ```kotlin + * createMessageRequest { + * maxTokens = 100 + * messages { + * userText { + * text = "What is the capital of France?" + * } + * } + * } + * ``` + * + * Example with annotations: + * ```kotlin + * userText { + * text = "Important message" + * annotations(Annotations(priority = 1.0)) + * } + * ``` + * + * @see TextContent + * @see MediaContentBuilder + */ +@McpDsl +public class TextContentBuilder @PublishedApi internal constructor() : MediaContentBuilder() { + /** + * The text content. This is a required field. + */ + public var text: String? = null + + override fun build(): TextContent { + val text = requireNotNull(text) { + "Missing required field 'text'. Example: text = \"Hello, world!\"" + } + + return TextContent(text = text, annotations = annotations, meta = meta) + } +} + +/** + * DSL builder for constructing [ImageContent] instances. + * + * ## Required + * - [data] - The base64-encoded image data + * - [mimeType] - The MIME type of the image (e.g., "image/png", "image/jpeg") + * + * ## Optional + * - [annotations] - Content annotations (inherited from [MediaContentBuilder]) + * - [meta] - Additional metadata (inherited from [MediaContentBuilder]) + * + * Example usage in sampling messages: + * ```kotlin + * createMessageRequest { + * maxTokens = 100 + * messages { + * userImage { + * data = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB..." + * mimeType = "image/png" + * } + * } + * } + * ``` + * + * Example with annotations: + * ```kotlin + * userImage { + * data = base64EncodedImageData + * mimeType = "image/jpeg" + * annotations(Annotations(priority = 0.9)) + * } + * ``` + * + * @see ImageContent + * @see MediaContentBuilder + */ +@McpDsl +public class ImageContentBuilder @PublishedApi internal constructor() : MediaContentBuilder() { + /** + * The base64-encoded image data. This is a required field. + */ + public var data: String? = null + + /** + * The MIME type of the image (e.g., "image/png", "image/jpeg"). This is a required field. + */ + public var mimeType: String? = null + + override fun build(): ImageContent { + val data = requireNotNull(data) { + "Missing required field 'data'. Provide base64-encoded image data" + } + val mime = requireNotNull(mimeType) { + "Missing required field 'mimeType'. Example: mimeType = \"image/png\"" + } + + return ImageContent( + data = data, + mimeType = mime, + annotations = annotations, + meta = meta, + ) + } +} + +/** + * DSL builder for constructing [AudioContent] instances. + * + * ## Required + * - [data] - The base64-encoded audio data + * - [mimeType] - The MIME type of the audio (e.g., "audio/wav", "audio/mpeg") + * + * ## Optional + * - [annotations] - Content annotations (inherited from [MediaContentBuilder]) + * - [meta] - Additional metadata (inherited from [MediaContentBuilder]) + * + * Example usage in sampling messages: + * ```kotlin + * createMessageRequest { + * maxTokens = 100 + * messages { + * userAudio { + * data = "UklGRiQAAABXQVZFZm10IBAAAAABAAEA..." + * mimeType = "audio/wav" + * } + * } + * } + * ``` + * + * Example with annotations: + * ```kotlin + * userAudio { + * data = base64EncodedAudioData + * mimeType = "audio/mpeg" + * annotations(Annotations(priority = 0.7)) + * } + * ``` + * + * @see AudioContent + * @see MediaContentBuilder + */ +@McpDsl +public class AudioContentBuilder @PublishedApi internal constructor() : MediaContentBuilder() { + /** + * The base64-encoded audio data. This is a required field. + */ + public var data: String? = null + + /** + * The MIME type of the audio (e.g., "audio/wav", "audio/mpeg"). This is a required field. + */ + public var mimeType: String? = null + + override fun build(): AudioContent { + val data = requireNotNull(data) { + "Missing required field 'data'. Provide base64-encoded audio data" + } + val mime = requireNotNull(mimeType) { + "Missing required field 'mimeType'. Example: mimeType = \"audio/wav\"" + } + + return AudioContent( + data = data, + mimeType = mime, + annotations = annotations, + meta = meta, + ) + } +} diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/elicitation.dsl.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/elicitation.dsl.kt new file mode 100644 index 00000000..a4823cfd --- /dev/null +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/elicitation.dsl.kt @@ -0,0 +1,228 @@ +package io.modelcontextprotocol.kotlin.sdk.types + +import io.modelcontextprotocol.kotlin.sdk.ExperimentalMcpApi +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonObjectBuilder +import kotlinx.serialization.json.buildJsonObject +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract + +/** + * Creates an [ElicitRequest] using a type-safe DSL builder. + * + * ## Required + * - [message][ElicitRequestBuilder.message] - The message to present to the user + * - [requestedSchema][ElicitRequestBuilder.requestedSchema] - Schema defining the structure of requested data + * + * ## Optional + * - [meta][ElicitRequestBuilder.meta] - Metadata for the request + * + * Example requesting user information: + * ```kotlin + * val request = buildElicitRequest { + * message = "Please provide your contact information" + * requestedSchema { + * properties { + * put("email", JsonObject(mapOf( + * "type" to JsonPrimitive("string"), + * "description" to JsonPrimitive("Your email address") + * ))) + * put("name", JsonObject(mapOf( + * "type" to JsonPrimitive("string") + * ))) + * } + * required = listOf("email") + * } + * } + * ``` + * + * Example with simple text input: + * ```kotlin + * val request = buildElicitRequest { + * message = "Enter a project name" + * requestedSchema { + * properties { + * put("projectName", JsonObject(mapOf( + * "type" to JsonPrimitive("string"), + * "description" to JsonPrimitive("Name for the new project") + * ))) + * } + * } + * } + * ``` + * + * @param block Configuration lambda for setting up the elicitation request + * @return A configured [ElicitRequest] instance + * @see ElicitRequestBuilder + * @see ElicitRequest + */ +@OptIn(ExperimentalContracts::class) +@ExperimentalMcpApi +internal inline fun buildElicitRequest(block: ElicitRequestBuilder.() -> Unit): ElicitRequest { + contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } + return ElicitRequestBuilder().apply(block).build() +} + +/** + * DSL builder for constructing [ElicitRequest] instances. + * + * This builder is used to create requests that prompt users for structured input + * through forms or dialogs presented by the client. + * + * ## Required + * - [message] - The message to present to the user explaining what is being requested + * - [requestedSchema] - Schema defining the structure of the data to collect + * + * ## Optional + * - [meta] - Metadata for the request + * + * @see buildElicitRequest + * @see ElicitRequest + */ +@McpDsl +public class ElicitRequestBuilder @PublishedApi internal constructor() : RequestBuilder() { + /** + * The message to present to the user. This should clearly explain what information + * is being requested and why. This is a required field. + */ + public var message: String? = null + + private var requestedSchema: ElicitRequestParams.RequestedSchema? = null + + /** + * Sets the requested schema directly. + * + * Example: + * ```kotlin + * buildElicitRequest { + * message = "Enter details" + * requestedSchema(ElicitRequestParams.RequestedSchema( + * properties = buildJsonObject { + * put("name", JsonObject(mapOf("type" to JsonPrimitive("string")))) + * } + * )) + * } + * ``` + * + * @param schema The [ElicitRequestParams.RequestedSchema] instance + */ + public fun requestedSchema(schema: ElicitRequestParams.RequestedSchema) { + requestedSchema = schema + } + + /** + * Sets the requested schema using a DSL builder. + * + * This is the recommended way to define schemas. The schema defines the structure + * of data to be collected from the user, supporting only top-level primitive properties. + * + * Example: + * ```kotlin + * buildElicitRequest { + * message = "Configure settings" + * requestedSchema { + * properties { + * put("enabled", JsonObject(mapOf( + * "type" to JsonPrimitive("boolean"), + * "description" to JsonPrimitive("Enable feature") + * ))) + * put("apiKey", JsonObject(mapOf( + * "type" to JsonPrimitive("string") + * ))) + * } + * required = listOf("apiKey") + * } + * } + * ``` + * + * @param block Lambda for building the schema + * @see ElicitRequestedSchemaBuilder + */ + public fun requestedSchema(block: ElicitRequestedSchemaBuilder.() -> Unit) { + requestedSchema = ElicitRequestedSchemaBuilder().apply(block).build() + } + + @PublishedApi + override fun build(): ElicitRequest { + val message = requireNotNull(message) { + "Missing required field 'message'. Example: message = \"Please enter your name\"" + } + val requestedSchema = requireNotNull(requestedSchema) { + "Missing required field 'requestedSchema'. Use requestedSchema { properties { ... } }" + } + + val params = ElicitRequestParams(message = message, requestedSchema = requestedSchema, meta = meta) + return ElicitRequest(params) + } +} + +/** + * DSL builder for constructing [ElicitRequestParams.RequestedSchema] instances. + * + * Defines the JSON Schema structure for data to be collected from the user. + * Only supports top-level primitive properties. + * + * ## Required + * - [properties] - Schema definitions for each field + * + * ## Optional + * - [required] - List of required property names + * + * Example: + * ```kotlin + * requestedSchema { + * properties { + * put("username", JsonObject(mapOf( + * "type" to JsonPrimitive("string"), + * "description" to JsonPrimitive("Your username") + * ))) + * } + * required = listOf("username") + * } + * ``` + * + * @see ElicitRequestParams.RequestedSchema + */ +@McpDsl +public class ElicitRequestedSchemaBuilder @PublishedApi internal constructor() { + private var properties: JsonObject? = null + + /** + * List of required property names. If null, all fields are optional. + */ + public var required: List? = null + + /** + * Sets the schema properties directly. + * + * @param properties JsonObject containing property schemas + */ + public fun properties(properties: JsonObject) { + this.properties = properties + } + + /** + * Sets the schema properties using a DSL builder. + * + * Example: + * ```kotlin + * properties { + * put("email", JsonObject(mapOf( + * "type" to JsonPrimitive("string") + * ))) + * } + * ``` + * + * @param block Lambda for building the properties + */ + public fun properties(block: JsonObjectBuilder.() -> Unit): Unit = properties(buildJsonObject(block)) + + @PublishedApi + internal fun build(): ElicitRequestParams.RequestedSchema { + val properties = requireNotNull(properties) { + "Missing required field 'properties'. Use properties { put(\"fieldName\", schema) }" + } + return ElicitRequestParams.RequestedSchema(properties, required) + } +} diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/initialize.dsl.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/initialize.dsl.kt new file mode 100644 index 00000000..345b036f --- /dev/null +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/initialize.dsl.kt @@ -0,0 +1,206 @@ +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 an [InitializeRequest] using a type-safe DSL builder. + * + * ## Required + * - [protocolVersion][InitializeRequestBuilder.protocolVersion] - MCP protocol version + * - [capabilities][InitializeRequestBuilder.capabilities] - Client capabilities + * - [info][InitializeRequestBuilder.info] - Client implementation information + * + * ## Optional + * - [meta][InitializeRequestBuilder.meta] - Metadata for the request + * + * Example: + * ```kotlin + * val request = buildInitializeRequest { + * protocolVersion = "2024-11-05" + * capabilities { + * sampling(ClientCapabilities.sampling) + * roots(listChanged = true) + * } + * info("MyClient", "1.0.0") + * } + * ``` + * + * Example with full client info: + * ```kotlin + * val request = buildInitializeRequest { + * protocolVersion = "2024-11-05" + * capabilities { + * sampling(ClientCapabilities.sampling) + * experimental { + * put("feature", JsonPrimitive(true)) + * } + * } + * info( + * name = "MyAdvancedClient", + * version = "2.0.0", + * title = "Advanced MCP Client", + * websiteUrl = "https://example.com" + * ) + * } + * ``` + * + * @param block Configuration lambda for setting up the initialize request + * @return A configured [InitializeRequest] instance + * @see InitializeRequestBuilder + * @see InitializeRequest + */ +@OptIn(ExperimentalContracts::class) +@ExperimentalMcpApi +internal inline fun buildInitializeRequest(block: InitializeRequestBuilder.() -> Unit): InitializeRequest { + contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } + return InitializeRequestBuilder().apply(block).build() +} + +/** + * DSL builder for constructing [InitializeRequest] instances. + * + * This builder creates the initial handshake request to establish + * an MCP protocol connection between client and server. + * + * ## Required + * - [protocolVersion] - MCP protocol version string + * - [capabilities] - Client capabilities configuration + * - [info] - Client implementation details + * + * ## Optional + * - [meta] - Metadata for the request + * + * @see buildInitializeRequest + * @see InitializeRequest + */ +@McpDsl +public class InitializeRequestBuilder @PublishedApi internal constructor() : RequestBuilder() { + /** + * The MCP protocol version. This is a required field. + * + * Example: `protocolVersion = "2024-11-05"` + */ + public var protocolVersion: String? = null + + private var capabilities: ClientCapabilities? = null + private var info: Implementation? = null + + /** + * Sets client capabilities directly. + * + * Example: + * ```kotlin + * capabilities(ClientCapabilities( + * sampling = ClientCapabilities.sampling, + * roots = ClientCapabilities.Roots(listChanged = true) + * )) + * ``` + * + * @param value The [ClientCapabilities] instance + */ + public fun capabilities(value: ClientCapabilities) { + capabilities = value + } + + /** + * Sets client capabilities using a DSL builder. + * + * This is the recommended way to configure capabilities. + * + * Example: + * ```kotlin + * capabilities { + * sampling(ClientCapabilities.sampling) + * roots(listChanged = true) + * elicitation(ClientCapabilities.elicitation) + * } + * ``` + * + * @param block Lambda for building capabilities + * @see ClientCapabilitiesBuilder + */ + public fun capabilities(block: ClientCapabilitiesBuilder.() -> Unit) { + capabilities = ClientCapabilitiesBuilder().apply(block).build() + } + + /** + * Sets client implementation info directly. + * + * Example: + * ```kotlin + * info(Implementation( + * name = "MyClient", + * version = "1.0.0" + * )) + * ``` + * + * @param value The [Implementation] instance + */ + public fun info(value: Implementation) { + info = value + } + + /** + * Sets client implementation info using individual parameters. + * + * This is the recommended way to configure client info. + * + * Example with required fields only: + * ```kotlin + * info("MyClient", "1.0.0") + * ``` + * + * Example with all fields: + * ```kotlin + * info( + * name = "MyClient", + * version = "2.0.0", + * title = "My MCP Client", + * websiteUrl = "https://example.com", + * icons = listOf(Icon( + * src = "https://example.com/icon.png", + * mimeType = "image/png" + * )) + * ) + * ``` + * + * @param name Client implementation name + * @param version Client version string + * @param title Optional human-readable title + * @param websiteUrl Optional URL to client website + * @param icons Optional list of client icons + */ + public fun info( + name: String, + version: String, + title: String? = null, + websiteUrl: String? = null, + icons: List? = null, + ) { + info = Implementation(name = name, version = version, title = title, websiteUrl = websiteUrl, icons = icons) + } + + @PublishedApi + override fun build(): InitializeRequest { + val version = requireNotNull(protocolVersion) { + "Missing required field 'protocolVersion'. Example: protocolVersion = \"2024-11-05\"" + } + val capabilities = requireNotNull(capabilities) { + "Missing required field 'capabilities'. Use capabilities { ... }" + } + val info = requireNotNull(info) { + "Missing required field 'info'. Use info(\"clientName\", \"1.0.0\")" + } + + val params = InitializeRequestParams( + protocolVersion = version, + capabilities = capabilities, + clientInfo = info, + meta = meta, + ) + return InitializeRequest(params = params) + } +} diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/logging.dsl.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/logging.dsl.kt new file mode 100644 index 00000000..883d2cc2 --- /dev/null +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/logging.dsl.kt @@ -0,0 +1,87 @@ +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 [SetLevelRequest] using a type-safe DSL builder. + * + * ## Required + * - [loggingLevel][SetLevelRequestBuilder.loggingLevel] - The logging level to set + * + * ## Optional + * - [meta][SetLevelRequestBuilder.meta] - Metadata for the request + * + * Example setting info level: + * ```kotlin + * val request = buildSetLevelRequest { + * loggingLevel = LoggingLevel.Info + * } + * ``` + * + * Example setting debug level: + * ```kotlin + * val request = buildSetLevelRequest { + * loggingLevel = LoggingLevel.Debug + * } + * ``` + * + * @param block Configuration lambda for setting up the logging level request + * @return A configured [SetLevelRequest] instance + * @see SetLevelRequestBuilder + * @see SetLevelRequest + * @see LoggingLevel + */ +@OptIn(ExperimentalContracts::class) +@ExperimentalMcpApi +internal inline fun buildSetLevelRequest(block: SetLevelRequestBuilder.() -> Unit): SetLevelRequest { + contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } + return SetLevelRequestBuilder().apply(block).build() +} + +/** + * DSL builder for constructing [SetLevelRequest] instances. + * + * This builder creates requests to set the logging level for the server. + * + * ## Required + * - [loggingLevel] - The logging level to set + * + * ## Optional + * - [meta] - Metadata for the request + * + * @see buildSetLevelRequest + * @see SetLevelRequest + * @see LoggingLevel + */ +@McpDsl +public class SetLevelRequestBuilder @PublishedApi internal constructor() : RequestBuilder() { + /** + * The logging level to set. This is a required field. + * + * Available levels (from least to most severe): + * - [LoggingLevel.Debug] + * - [LoggingLevel.Info] + * - [LoggingLevel.Notice] + * - [LoggingLevel.Warning] + * - [LoggingLevel.Error] + * - [LoggingLevel.Critical] + * - [LoggingLevel.Alert] + * - [LoggingLevel.Emergency] + * + * Example: `loggingLevel = LoggingLevel.Warning` + */ + public var loggingLevel: LoggingLevel? = null + + @PublishedApi + override fun build(): SetLevelRequest { + val level = requireNotNull(loggingLevel) { + "Missing required field 'loggingLevel'. Example: loggingLevel = LoggingLevel.Info" + } + + val params = SetLevelRequestParams(level = level, meta = meta) + return SetLevelRequest(params = params) + } +} diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/pingRequest.dsl.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/pingRequest.dsl.kt new file mode 100644 index 00000000..2f5ac33e --- /dev/null +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/pingRequest.dsl.kt @@ -0,0 +1,59 @@ +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 [PingRequest] using a type-safe DSL builder. + * + * ## Optional + * - [meta][PingRequestBuilder.meta] - Metadata for the request + * + * Example with no parameters: + * ```kotlin + * val request = buildPingRequest { } + * ``` + * + * Example with metadata: + * ```kotlin + * val request = buildPingRequest { + * meta { + * put("timestamp", JsonPrimitive(System.currentTimeMillis())) + * } + * } + * ``` + * + * @param block Configuration lambda for setting up the ping request + * @return A configured [PingRequest] instance + * @see PingRequestBuilder + * @see PingRequest + */ +@OptIn(ExperimentalContracts::class) +@ExperimentalMcpApi +internal inline fun buildPingRequest(block: PingRequestBuilder.() -> Unit): PingRequest { + contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } + return PingRequestBuilder().apply(block).build() +} + +/** + * DSL builder for constructing [PingRequest] instances. + * + * This builder creates ping requests to check connection status with the server. + * All fields are optional. + * + * ## Optional + * - [meta] - Metadata for the request + * + * @see buildPingRequest + * @see PingRequest + */ +@McpDsl +public class PingRequestBuilder @PublishedApi internal constructor() : RequestBuilder() { + @PublishedApi + override fun build(): PingRequest { + val params = meta?.let { BaseRequestParams(meta = it) } + return PingRequest(params) + } +} diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/prompts.dsl.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/prompts.dsl.kt new file mode 100644 index 00000000..02eae95f --- /dev/null +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/prompts.dsl.kt @@ -0,0 +1,145 @@ +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 [GetPromptRequest] using a type-safe DSL builder. + * + * ## Required + * - [name][GetPromptRequestBuilder.name] - The name of the prompt to retrieve + * + * ## Optional + * - [arguments][GetPromptRequestBuilder.arguments] - Arguments to pass to the prompt + * - [meta][GetPromptRequestBuilder.meta] - Metadata for the request + * + * Example without arguments: + * ```kotlin + * val request = buildGetPromptRequest { + * name = "greeting" + * } + * ``` + * + * Example with arguments: + * ```kotlin + * val request = buildGetPromptRequest { + * name = "userProfile" + * arguments = mapOf( + * "userId" to "123", + * "includeDetails" to "true" + * ) + * } + * ``` + * + * @param block Configuration lambda for setting up the get prompt request + * @return A configured [GetPromptRequest] instance + * @see GetPromptRequestBuilder + * @see GetPromptRequest + */ +@OptIn(ExperimentalContracts::class) +@ExperimentalMcpApi +internal inline fun buildGetPromptRequest(block: GetPromptRequestBuilder.() -> Unit): GetPromptRequest { + contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } + return GetPromptRequestBuilder().apply(block).build() +} + +/** + * DSL builder for constructing [GetPromptRequest] instances. + * + * This builder retrieves a specific prompt by name, optionally with arguments. + * + * ## Required + * - [name] - The name of the prompt to retrieve + * + * ## Optional + * - [arguments] - Arguments to pass to the prompt + * - [meta] - Metadata for the request + * + * @see buildGetPromptRequest + * @see GetPromptRequest + */ +@McpDsl +public class GetPromptRequestBuilder @PublishedApi internal constructor() : RequestBuilder() { + /** + * The name of the prompt to retrieve. This is a required field. + * + * Example: `name = "greeting"` + */ + public var name: String? = null + + /** + * Optional arguments to pass to the prompt. + * + * Example: + * ```kotlin + * arguments = mapOf("userId" to "123", "lang" to "en") + * ``` + */ + public var arguments: Map? = null + + @PublishedApi + override fun build(): GetPromptRequest { + val name = requireNotNull(name) { + "Missing required field 'name'. Example: name = \"promptName\"" + } + + val params = GetPromptRequestParams(name = name, arguments = arguments, meta = meta) + return GetPromptRequest(params) + } +} + +/** + * Creates a [ListPromptsRequest] using a type-safe DSL builder. + * + * ## Optional + * - [cursor][ListPromptsRequestBuilder.cursor] - Pagination cursor for fetching next page + * - [meta][ListPromptsRequestBuilder.meta] - Metadata for the request + * + * Example without pagination: + * ```kotlin + * val request = buildListPromptsRequest { } + * ``` + * + * Example with pagination: + * ```kotlin + * val request = buildListPromptsRequest { + * cursor = "eyJwYWdlIjogMn0=" + * } + * ``` + * + * @param block Configuration lambda for setting up the list prompts request + * @return A configured [ListPromptsRequest] instance + * @see ListPromptsRequestBuilder + * @see ListPromptsRequest + */ +@OptIn(ExperimentalContracts::class) +@ExperimentalMcpApi +internal inline fun buildListPromptsRequest(block: ListPromptsRequestBuilder.() -> Unit): ListPromptsRequest { + contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } + return ListPromptsRequestBuilder().apply(block).build() +} + +/** + * DSL builder for constructing [ListPromptsRequest] instances. + * + * This builder retrieves a list of available prompts, with optional pagination support. + * All fields are optional. + * + * ## Optional + * - [cursor] - Pagination cursor (inherited from [PaginatedRequestBuilder]) + * - [meta] - Metadata for the request (inherited from [RequestBuilder]) + * + * @see buildListPromptsRequest + * @see ListPromptsRequest + * @see PaginatedRequestBuilder + */ +@McpDsl +public class ListPromptsRequestBuilder @PublishedApi internal constructor() : PaginatedRequestBuilder() { + @PublishedApi + override fun build(): ListPromptsRequest { + val params = paginatedRequestParams(cursor = cursor, meta = meta) + return ListPromptsRequest(params) + } +} diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/request.dsl.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/request.dsl.kt new file mode 100644 index 00000000..3e2a1504 --- /dev/null +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/request.dsl.kt @@ -0,0 +1,208 @@ +package io.modelcontextprotocol.kotlin.sdk.types + +import kotlinx.serialization.json.JsonArrayBuilder +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonNull +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonObjectBuilder +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.buildJsonArray +import kotlinx.serialization.json.buildJsonObject + +/** + * Base DSL builder for constructing MCP request instances. + * + * This abstract class provides common functionality for all request builders, + * including optional metadata support. + * + * All concrete request builder classes extend this base to inherit [meta] functionality. + * + * @see RequestMetaBuilder + * @see PaginatedRequestBuilder + */ +@McpDsl +public abstract class RequestBuilder { + protected var meta: RequestMeta? = null + + /** + * Sets request metadata using a DSL builder. + * + * Metadata can include progress tokens and custom fields for tracking requests. + * + * Example: + * ```kotlin + * initializeRequest { + * protocolVersion = "2024-11-05" + * meta { + * progressToken("progress-123") + * put("customField", "value") + * } + * // ... other configuration + * } + * ``` + * + * @param builderAction Lambda for building request metadata + * @see RequestMetaBuilder + */ + public fun meta(builderAction: RequestMetaBuilder.() -> Unit) { + meta = RequestMetaBuilder().apply(builderAction).build() + } + + internal abstract fun build(): Request +} + +/** + * DSL builder for constructing [RequestMeta] instances. + * + * This builder creates metadata for MCP requests, supporting progress tokens + * and custom key-value pairs. + * + * Example: + * ```kotlin + * meta { + * progressToken("progress-123") + * put("requestId", "req-456") + * put("priority", 1) + * putJsonObject("context") { + * put("source", "api") + * } + * } + * ``` + * + * @see RequestMeta + * @see RequestBuilder.meta + */ +@McpDsl +public class RequestMetaBuilder internal constructor() { + private val content: MutableMap = linkedMapOf() + + /** + * Sets the progress token as a string. + * + * Progress tokens are used for out-of-band progress notifications. + * + * Example: `progressToken("progress-123")` + */ + public fun progressToken(value: String) { + content["progressToken"] = JsonPrimitive(value) + } + + /** + * Sets the progress token as a `Long`. + * + * Example: `progressToken(123L)` + */ + public fun progressToken(value: Long) { + content["progressToken"] = JsonPrimitive(value) + } + + /** + * Sets the progress token as an Int. + * + * Example: `progressToken(123)` + */ + public fun progressToken(value: Int) { + content["progressToken"] = JsonPrimitive(value) + } + + /** + * Adds a custom metadata field with a JsonElement value. + * + * @param key The metadata field name + * @param value The JsonElement value + * @return The previous value associated with the key, or null + */ + public fun put(key: String, value: JsonElement): JsonElement? = content.put(key, value) + + /** + * Adds a custom metadata field with a String value. + * + * Example: `put("requestId", "req-456")` + */ + public fun put(key: String, value: String): JsonElement? = put(key, JsonPrimitive(value)) + + /** + * Adds a custom metadata field with a Number value. + * + * Example: `put("priority", 1)` + */ + public fun put(key: String, value: Number): JsonElement? = put(key, JsonPrimitive(value)) + + /** + * Adds a custom metadata field with a Boolean value. + * + * Example: `put("urgent", true)` + */ + public fun put(key: String, value: Boolean): JsonElement? = put(key, JsonPrimitive(value)) + + /** + * Adds a custom metadata field with a null value. + * + * Example: `put("optionalField", null)` + */ + @Suppress("UNUSED_PARAMETER") + public fun put(key: String, value: Nothing?): JsonElement? = put(key, JsonNull) + + /** + * Adds a custom metadata field with a JsonObject value using a DSL builder. + * + * Example: + * ```kotlin + * putJsonObject("context") { + * put("source", "api") + * put("version", 2) + * } + * ``` + * + * @param key The metadata field name + * @param builderAction Lambda for building the JsonObject + */ + public fun putJsonObject(key: String, builderAction: JsonObjectBuilder.() -> Unit): JsonElement? = + put(key, buildJsonObject(builderAction)) + + /** + * Adds a custom metadata field with a JsonArray value using a DSL builder. + * + * Example: + * ```kotlin + * putJsonArray("tags") { + * add("important") + * add("urgent") + * } + * ``` + * + * @param key The metadata field name + * @param builderAction Lambda for building the JsonArray + */ + public fun putJsonArray(key: String, builderAction: JsonArrayBuilder.() -> Unit): JsonElement? = + put(key, buildJsonArray(builderAction)) + + internal fun build(): RequestMeta = RequestMeta(JsonObject(content)) +} + +/** + * Base DSL builder for constructing paginated MCP request instances. + * + * This abstract class extends [RequestBuilder] and adds pagination support + * through an optional cursor field. + * + * Example: + * ```kotlin + * listPromptsRequest { + * cursor = "eyJwYWdlIjogMn0=" + * } + * ``` + * + * @see RequestBuilder + */ +@McpDsl +public abstract class PaginatedRequestBuilder : RequestBuilder() { + /** + * Optional pagination cursor for fetching the next page of results. + * + * The cursor value is typically obtained from the previous page's response. + * + * Example: `cursor = "eyJwYWdlIjogMn0="` + */ + public var cursor: String? = null +} diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/resources.dsl.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/resources.dsl.kt new file mode 100644 index 00000000..db40cd7e --- /dev/null +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/resources.dsl.kt @@ -0,0 +1,302 @@ +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 [ListResourcesRequest] using a type-safe DSL builder. + * + * ## Optional + * - [cursor][ListResourcesRequestBuilder.cursor] - Pagination cursor for fetching next page + * - [meta][ListResourcesRequestBuilder.meta] - Metadata for the request + * + * Example without pagination: + * ```kotlin + * val request = buildListResourcesRequest { } + * ``` + * + * Example with pagination: + * ```kotlin + * val request = buildListResourcesRequest { + * cursor = "eyJwYWdlIjogMn0=" + * } + * ``` + * + * @param block Configuration lambda for setting up the list resources request + * @return A configured [ListResourcesRequest] instance + * @see ListResourcesRequestBuilder + * @see ListResourcesRequest + */ +@OptIn(ExperimentalContracts::class) +@ExperimentalMcpApi +internal inline fun buildListResourcesRequest(block: ListResourcesRequestBuilder.() -> Unit): ListResourcesRequest { + contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } + return ListResourcesRequestBuilder().apply(block).build() +} + +/** + * DSL builder for constructing [ListResourcesRequest] instances. + * + * This builder retrieves a list of available resources, with optional pagination support. + * All fields are optional. + * + * ## Optional + * - [cursor] - Pagination cursor (inherited from [PaginatedRequestBuilder]) + * - [meta] - Metadata for the request (inherited from [RequestBuilder]) + * + * @see buildListResourcesRequest + * @see ListResourcesRequest + * @see PaginatedRequestBuilder + */ +@McpDsl +public class ListResourcesRequestBuilder @PublishedApi internal constructor() : PaginatedRequestBuilder() { + @PublishedApi + override fun build(): ListResourcesRequest { + val params = paginatedRequestParams(cursor = cursor, meta = meta) + return ListResourcesRequest(params) + } +} + +/** + * Creates a [ReadResourceRequest] using a type-safe DSL builder. + * + * ## Required + * - [uri][ReadResourceRequestBuilder.uri] - The URI of the resource to read + * + * ## Optional + * - [meta][ReadResourceRequestBuilder.meta] - Metadata for the request + * + * Example: + * ```kotlin + * val request = buildReadResourceRequest { + * uri = "file:///path/to/resource.txt" + * } + * ``` + * + * @param block Configuration lambda for setting up the read resource request + * @return A configured [ReadResourceRequest] instance + * @see ReadResourceRequestBuilder + * @see ReadResourceRequest + */ +@OptIn(ExperimentalContracts::class) +@ExperimentalMcpApi +internal inline fun buildReadResourceRequest(block: ReadResourceRequestBuilder.() -> Unit): ReadResourceRequest { + contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } + return ReadResourceRequestBuilder().apply(block).build() +} + +/** + * DSL builder for constructing [ReadResourceRequest] instances. + * + * This builder reads the contents of a specific resource by URI. + * + * ## Required + * - [uri] - The URI of the resource to read + * + * ## Optional + * - [meta] - Metadata for the request + * + * @see buildReadResourceRequest + * @see ReadResourceRequest + */ +@McpDsl +public class ReadResourceRequestBuilder @PublishedApi internal constructor() : RequestBuilder() { + /** + * The URI of the resource to read. This is a required field. + * + * Example: `uri = "file:///path/to/resource.txt"` + */ + public var uri: String? = null + + @PublishedApi + override fun build(): ReadResourceRequest { + val uri = requireNotNull(uri) { + "Missing required field 'uri'. Example: uri = \"file:///path/to/resource.txt\"" + } + + val params = ReadResourceRequestParams(uri = uri, meta = meta) + return ReadResourceRequest(params) + } +} + +/** + * Creates a [SubscribeRequest] using a type-safe DSL builder. + * + * ## Required + * - [uri][SubscribeRequestBuilder.uri] - The URI of the resource to subscribe to + * + * ## Optional + * - [meta][SubscribeRequestBuilder.meta] - Metadata for the request + * + * Example: + * ```kotlin + * val request = buildSubscribeRequest { + * uri = "file:///path/to/resource.txt" + * } + * ``` + * + * @param block Configuration lambda for setting up the subscribe request + * @return A configured [SubscribeRequest] instance + * @see SubscribeRequestBuilder + * @see SubscribeRequest + */ +@OptIn(ExperimentalContracts::class) +@ExperimentalMcpApi +internal inline fun buildSubscribeRequest(block: SubscribeRequestBuilder.() -> Unit): SubscribeRequest { + contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } + return SubscribeRequestBuilder().apply(block).build() +} + +/** + * DSL builder for constructing [SubscribeRequest] instances. + * + * This builder subscribes to updates for a specific resource by URI. + * + * ## Required + * - [uri] - The URI of the resource to subscribe to + * + * ## Optional + * - [meta] - Metadata for the request + * + * @see buildSubscribeRequest + * @see SubscribeRequest + */ +@McpDsl +public class SubscribeRequestBuilder @PublishedApi internal constructor() : RequestBuilder() { + /** + * The URI of the resource to subscribe to. This is a required field. + * + * Example: `uri = "file:///path/to/resource.txt"` + */ + public var uri: String? = null + + @PublishedApi + override fun build(): SubscribeRequest { + val uri = requireNotNull(uri) { + "Missing required field 'uri'. Example: uri = \"file:///path/to/resource.txt\"" + } + + val params = SubscribeRequestParams(uri = uri, meta = meta) + return SubscribeRequest(params) + } +} + +/** + * Creates an [UnsubscribeRequest] using a type-safe DSL builder. + * + * ## Required + * - [uri][UnsubscribeRequestBuilder.uri] - The URI of the resource to unsubscribe from + * + * ## Optional + * - [meta][UnsubscribeRequestBuilder.meta] - Metadata for the request + * + * Example: + * ```kotlin + * val request = buildUnsubscribeRequest { + * uri = "file:///path/to/resource.txt" + * } + * ``` + * + * @param block Configuration lambda for setting up the unsubscribe request + * @return A configured [UnsubscribeRequest] instance + * @see UnsubscribeRequestBuilder + * @see UnsubscribeRequest + */ +@OptIn(ExperimentalContracts::class) +@ExperimentalMcpApi +internal inline fun buildUnsubscribeRequest(block: UnsubscribeRequestBuilder.() -> Unit): UnsubscribeRequest { + contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } + return UnsubscribeRequestBuilder().apply(block).build() +} + +/** + * DSL builder for constructing [UnsubscribeRequest] instances. + * + * This builder unsubscribes from updates for a specific resource by URI. + * + * ## Required + * - [uri] - The URI of the resource to unsubscribe from + * + * ## Optional + * - [meta] - Metadata for the request + * + * @see buildUnsubscribeRequest + * @see UnsubscribeRequest + */ +@McpDsl +public class UnsubscribeRequestBuilder @PublishedApi internal constructor() : RequestBuilder() { + /** + * The URI of the resource to unsubscribe from. This is a required field. + * + * Example: `uri = "file:///path/to/resource.txt"` + */ + public var uri: String? = null + + @PublishedApi + override fun build(): UnsubscribeRequest { + val uri = requireNotNull(uri) { + "Missing required field 'uri'. Example: uri = \"file:///path/to/resource.txt\"" + } + + val params = UnsubscribeRequestParams(uri = uri, meta = meta) + return UnsubscribeRequest(params) + } +} + +/** + * Creates a [ListResourceTemplatesRequest] using a type-safe DSL builder. + * + * ## Optional + * - [cursor][ListResourceTemplatesRequestBuilder.cursor] - Pagination cursor for fetching next page + * - [meta][ListResourceTemplatesRequestBuilder.meta] - Metadata for the request + * + * Example without pagination: + * ```kotlin + * val request = buildListResourceTemplatesRequest { } + * ``` + * + * Example with pagination: + * ```kotlin + * val request = buildListResourceTemplatesRequest { + * cursor = "eyJwYWdlIjogMn0=" + * } + * ``` + * + * @param block Configuration lambda for setting up the list resource templates request + * @return A configured [ListResourceTemplatesRequest] instance + * @see ListResourceTemplatesRequestBuilder + * @see ListResourceTemplatesRequest + */ +@OptIn(ExperimentalContracts::class) +@ExperimentalMcpApi +internal inline fun buildListResourceTemplatesRequest( + block: ListResourceTemplatesRequestBuilder.() -> Unit, +): ListResourceTemplatesRequest { + contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } + return ListResourceTemplatesRequestBuilder().apply(block).build() +} + +/** + * DSL builder for constructing [ListResourceTemplatesRequest] instances. + * + * This builder retrieves a list of available resource templates, with optional pagination support. + * All fields are optional. + * + * ## Optional + * - [cursor] - Pagination cursor (inherited from [PaginatedRequestBuilder]) + * - [meta] - Metadata for the request (inherited from [RequestBuilder]) + * + * @see buildListResourceTemplatesRequest + * @see ListResourceTemplatesRequest + * @see PaginatedRequestBuilder + */ +@McpDsl +public class ListResourceTemplatesRequestBuilder @PublishedApi internal constructor() : PaginatedRequestBuilder() { + @PublishedApi + override fun build(): ListResourceTemplatesRequest { + val params = paginatedRequestParams(cursor = cursor, meta = meta) + return ListResourceTemplatesRequest(params) + } +} diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/roots.dsl.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/roots.dsl.kt new file mode 100644 index 00000000..a73f218c --- /dev/null +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/roots.dsl.kt @@ -0,0 +1,59 @@ +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 [ListRootsRequest] using a type-safe DSL builder. + * + * ## Optional + * - [meta][ListRootsRequestBuilder.meta] - Metadata for the request + * + * Example with no parameters: + * ```kotlin + * val request = buildListRootsRequest { } + * ``` + * + * Example with metadata: + * ```kotlin + * val request = buildListRootsRequest { + * meta { + * put("context", "initialization") + * } + * } + * ``` + * + * @param block Configuration lambda for setting up the list roots request + * @return A configured [ListRootsRequest] instance + * @see ListRootsRequestBuilder + * @see ListRootsRequest + */ +@OptIn(ExperimentalContracts::class) +@ExperimentalMcpApi +internal inline fun buildListRootsRequest(block: ListRootsRequestBuilder.() -> Unit): ListRootsRequest { + contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } + return ListRootsRequestBuilder().apply(block).build() +} + +/** + * DSL builder for constructing [ListRootsRequest] instances. + * + * This builder retrieves the list of root URIs provided by the client. + * All fields are optional. + * + * ## Optional + * - [meta] - Metadata for the request + * + * @see buildListRootsRequest + * @see ListRootsRequest + */ +@McpDsl +public class ListRootsRequestBuilder @PublishedApi internal constructor() : RequestBuilder() { + @PublishedApi + override fun build(): ListRootsRequest { + val params = meta?.let { BaseRequestParams(meta = it) } + return ListRootsRequest(params) + } +} diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/sampling.dsl.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/sampling.dsl.kt new file mode 100644 index 00000000..8e87304a --- /dev/null +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/sampling.dsl.kt @@ -0,0 +1,394 @@ +package io.modelcontextprotocol.kotlin.sdk.types + +import io.modelcontextprotocol.kotlin.sdk.ExperimentalMcpApi +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonObjectBuilder +import kotlinx.serialization.json.buildJsonObject +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract + +/** + * Creates a [CreateMessageRequest] using a type-safe DSL builder. + * + * ## Required + * - [maxTokens][CreateMessageRequestBuilder.maxTokens] - Maximum number of tokens to generate + * - [messages][CreateMessageRequestBuilder.messages] - List of conversation messages + * + * ## Optional + * - [systemPrompt][CreateMessageRequestBuilder.systemPrompt] - System-level instructions + * - [context][CreateMessageRequestBuilder.context] - Context inclusion settings + * - [temperature][CreateMessageRequestBuilder.temperature] - Sampling temperature + * - [stopSequences][CreateMessageRequestBuilder.stopSequences] - Sequences that stop generation + * - [preferences][CreateMessageRequestBuilder.preferences] - Model selection preferences + * - [metadata][CreateMessageRequestBuilder.metadata] - Additional metadata + * - [meta][CreateMessageRequestBuilder.meta] - Request metadata + * + * Example: + * ```kotlin + * val request = buildCreateMessageRequest { + * maxTokens = 1000 + * systemPrompt = "You are a helpful assistant" + * messages { + * user { "What is the capital of France?" } + * assistant { "The capital of France is Paris." } + * user { "What about Germany?" } + * } + * } + * ``` + * + * Example with preferences: + * ```kotlin + * val request = buildCreateMessageRequest { + * maxTokens = 500 + * temperature = 0.7 + * preferences( + * hints = listOf("claude-3-sonnet"), + * intelligence = 0.8 + * ) + * messages { + * user { "Explain quantum computing" } + * } + * } + * ``` + * + * @param block Configuration lambda for setting up the create message request + * @return A configured [CreateMessageRequest] instance + * @see CreateMessageRequestBuilder + * @see CreateMessageRequest + */ +@OptIn(ExperimentalContracts::class) +@ExperimentalMcpApi +internal inline fun buildCreateMessageRequest(block: CreateMessageRequestBuilder.() -> Unit): CreateMessageRequest { + contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } + return CreateMessageRequestBuilder().apply(block).build() +} + +/** + * DSL builder for constructing [CreateMessageRequest] instances. + * + * This builder creates LLM sampling requests with conversation history. + * + * ## Required + * - [maxTokens] - Maximum number of tokens to generate + * - [messages] - List of conversation messages + * + * ## Optional + * - [systemPrompt] - System-level instructions + * - [context] - Context inclusion settings + * - [temperature] - Sampling temperature (0.0-1.0) + * - [stopSequences] - Sequences that stop generation + * - [preferences] - Model selection preferences + * - [metadata] - Additional metadata + * - [meta] - Request metadata + * + * @see buildCreateMessageRequest + * @see CreateMessageRequest + */ +@McpDsl +public class CreateMessageRequestBuilder @PublishedApi internal constructor() : RequestBuilder() { + /** Maximum number of tokens to generate. This is a required field. */ + public var maxTokens: Int? = null + + /** Optional system-level instructions for the model. */ + public var systemPrompt: String? = null + + /** Optional context inclusion settings. */ + public var context: IncludeContext? = null + + /** Optional sampling temperature (0.0-1.0). Lower values are more deterministic. */ + public var temperature: Double? = null + + /** Optional sequences that will stop generation when encountered. */ + public var stopSequences: List? = null + + private var messages: List? = null + private var preferences: ModelPreferences? = null + private var metadata: JsonObject? = null + + /** + * Sets messages directly from a list. + * + * Example: + * ```kotlin + * messages(listOf( + * SamplingMessage(Role.User, TextContent("Hello")), + * SamplingMessage(Role.Assistant, TextContent("Hi!")) + * )) + * ``` + */ + public fun messages(messages: List) { + this.messages = messages + } + + /** + * Sets messages using a DSL builder. + * + * This is the recommended way to define conversation messages. + * + * Example: + * ```kotlin + * messages { + * user { "What is 2+2?" } + * assistant { "2+2 equals 4." } + * user { "What about 3+3?" } + * } + * ``` + */ + public fun messages(block: SamplingMessageBuilder.() -> Unit) { + this.messages = SamplingMessageBuilder().apply(block).build() + } + + /** + * Sets model preferences directly. + */ + public fun preferences(value: ModelPreferences) { + this.preferences = value + } + + /** + * Sets model selection preferences using individual parameters. + * + * Example: + * ```kotlin + * preferences( + * hints = listOf("claude-3-sonnet"), + * intelligence = 0.9, + * speed = 0.5 + * ) + * ``` + * + * @param hints Model name hints for selection + * @param cost Cost optimization priority (0.0-1.0) + * @param speed Speed optimization priority (0.0-1.0) + * @param intelligence Intelligence optimization priority (0.0-1.0) + */ + public fun preferences( + hints: List? = null, + cost: Double? = null, + speed: Double? = null, + intelligence: Double? = null, + ) { + this.preferences = ModelPreferences( + hints = hints?.map { ModelHint(it) }, + costPriority = cost, + speedPriority = speed, + intelligencePriority = intelligence, + ) + } + + /** + * Sets additional metadata using a DSL builder. + * + * Example: + * ```kotlin + * metadata { + * put("userId", "123") + * put("sessionId", "abc") + * } + * ``` + */ + public fun metadata(block: JsonObjectBuilder.() -> Unit) { + this.metadata = buildJsonObject(block) + } + + @PublishedApi + override fun build(): CreateMessageRequest { + val maxTokens = requireNotNull(maxTokens) { + "Missing required field 'maxTokens'. Example: maxTokens = 1000" + } + val messages = requireNotNull(messages) { + "Missing required field 'messages'. Use messages { user { \"text\" } }" + } + + val params = CreateMessageRequestParams( + maxTokens = maxTokens, + messages = messages, + modelPreferences = preferences, + systemPrompt = systemPrompt, + includeContext = context, + temperature = temperature, + stopSequences = stopSequences, + metadata = metadata, + meta = meta, + ) + return CreateMessageRequest(params) + } +} + +/** + * DSL builder for constructing lists of [SamplingMessage] instances. + * + * This builder creates a conversation history for LLM sampling requests. + * + * Example: + * ```kotlin + * messages { + * user { "Hello!" } + * assistant { "Hi! How can I help?" } + * user { "What's 2+2?" } + * } + * ``` + * + * @see SamplingMessage + * @see CreateMessageRequestBuilder.messages + */ +@McpDsl +public class SamplingMessageBuilder @PublishedApi internal constructor() { + private val messages = mutableListOf() + + /** + * Adds a user message with the specified content. + * + * Example: + * ```kotlin + * user(TextContent("Hello")) + * ``` + */ + public fun user(content: MediaContent) { + messages.add(SamplingMessage(Role.User, content)) + } + + /** + * Adds an assistant message with the specified content. + * + * Example: + * ```kotlin + * assistant(TextContent("Hi there!")) + * ``` + */ + public fun assistant(content: MediaContent) { + messages.add(SamplingMessage(Role.Assistant, content)) + } + + @PublishedApi + internal fun build(): List = messages +} + +/** + * Adds a user message with simple text content. + * + * Example: + * ```kotlin + * messages { + * user { "What is the weather today?" } + * } + * ``` + */ +@ExperimentalMcpApi +public fun SamplingMessageBuilder.user(block: () -> String): Unit = this.user(TextContent(text = block())) + +/** + * Adds a user message with text content using a DSL builder. + * + * Example: + * ```kotlin + * messages { + * userText { + * text = "Important message" + * annotations(priority = 1.0) + * } + * } + * ``` + */ +@ExperimentalMcpApi +public fun SamplingMessageBuilder.userText(block: TextContentBuilder.() -> Unit): Unit = + this.user(TextContentBuilder().apply(block).build()) + +/** + * Adds a user message with image content. + * + * Example: + * ```kotlin + * messages { + * userImage { + * data = base64ImageData + * mimeType = "image/png" + * } + * } + * ``` + */ +@ExperimentalMcpApi +public fun SamplingMessageBuilder.userImage(block: ImageContentBuilder.() -> Unit): Unit = + this.user(ImageContentBuilder().apply(block).build()) + +/** + * Adds a user message with audio content. + * + * Example: + * ```kotlin + * messages { + * userAudio { + * data = base64AudioData + * mimeType = "audio/wav" + * } + * } + * ``` + */ +@ExperimentalMcpApi +public fun SamplingMessageBuilder.userAudio(block: AudioContentBuilder.() -> Unit): Unit = + this.user(AudioContentBuilder().apply(block).build()) + +/** + * Adds an assistant message with simple text content. + * + * Example: + * ```kotlin + * messages { + * assistant { "The weather is sunny today." } + * } + * ``` + */ +@ExperimentalMcpApi +public fun SamplingMessageBuilder.assistant(block: () -> String): Unit = this.assistant(TextContent(text = block())) + +/** + * Adds an assistant message with text content using a DSL builder. + * + * Example: + * ```kotlin + * messages { + * assistantText { + * text = "Here's the answer" + * annotations(priority = 0.8) + * } + * } + * ``` + */ +@ExperimentalMcpApi +public fun SamplingMessageBuilder.assistantText(block: TextContentBuilder.() -> Unit): Unit = + this.assistant(TextContentBuilder().apply(block).build()) + +/** + * Adds an assistant message with image content. + * + * Example: + * ```kotlin + * messages { + * assistantImage { + * data = generatedImageData + * mimeType = "image/jpeg" + * } + * } + * ``` + */ +@ExperimentalMcpApi +public fun SamplingMessageBuilder.assistantImage(block: ImageContentBuilder.() -> Unit): Unit = + this.assistant(ImageContentBuilder().apply(block).build()) + +/** + * Adds an assistant message with audio content. + * + * Example: + * ```kotlin + * messages { + * assistantAudio { + * data = generatedAudioData + * mimeType = "audio/mpeg" + * } + * } + * ``` + */ +@ExperimentalMcpApi +public fun SamplingMessageBuilder.assistantAudio(block: AudioContentBuilder.() -> Unit): Unit = + this.assistant(AudioContentBuilder().apply(block).build()) diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/tools.dsl.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/tools.dsl.kt new file mode 100644 index 00000000..9a5adf10 --- /dev/null +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/tools.dsl.kt @@ -0,0 +1,172 @@ +package io.modelcontextprotocol.kotlin.sdk.types + +import io.modelcontextprotocol.kotlin.sdk.ExperimentalMcpApi +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonObjectBuilder +import kotlinx.serialization.json.buildJsonObject +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract + +/** + * Creates a [CallToolRequest] using a type-safe DSL builder. + * + * ## Required + * - [name][CallToolRequestBuilder.name] - The name of the tool to call + * + * ## Optional + * - [arguments][CallToolRequestBuilder.arguments] - Arguments to pass to the tool + * - [meta][CallToolRequestBuilder.meta] - Metadata for the request + * + * Example without arguments: + * ```kotlin + * val request = buildCallToolRequest { + * name = "getCurrentTime" + * } + * ``` + * + * Example with arguments: + * ```kotlin + * val request = buildCallToolRequest { + * name = "searchDatabase" + * arguments { + * put("query", "users") + * put("limit", 10) + * } + * } + * ``` + * + * @param block Configuration lambda for setting up the call tool request + * @return A configured [CallToolRequest] instance + * @see CallToolRequestBuilder + * @see CallToolRequest + */ +@OptIn(ExperimentalContracts::class) +@ExperimentalMcpApi +internal inline fun buildCallToolRequest(block: CallToolRequestBuilder.() -> Unit): CallToolRequest { + contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } + return CallToolRequestBuilder().apply(block).build() +} + +/** + * DSL builder for constructing [CallToolRequest] instances. + * + * This builder invokes a specific tool by name with optional arguments. + * + * ## Required + * - [name] - The name of the tool to call + * + * ## Optional + * - [arguments] - Arguments to pass to the tool + * - [meta] - Metadata for the request + * + * @see buildCallToolRequest + * @see CallToolRequest + */ +@McpDsl +public class CallToolRequestBuilder @PublishedApi internal constructor() : RequestBuilder() { + /** + * The name of the tool to call. This is a required field. + * + * Example: `name = "getCurrentTime"` + */ + public var name: String? = null + + private var arguments: JsonObject? = null + + /** + * Sets tool arguments directly from a JsonObject. + * + * Example: + * ```kotlin + * arguments(buildJsonObject { + * put("query", "users") + * }) + * ``` + */ + public fun arguments(arguments: JsonObject) { + this.arguments = arguments + } + + /** + * Sets tool arguments using a DSL builder. + * + * This is the recommended way to provide tool arguments. + * + * Example: + * ```kotlin + * arguments { + * put("query", "SELECT * FROM users") + * put("limit", 100) + * put("includeDeleted", false) + * } + * ``` + * + * @param block Lambda for building the arguments JsonObject + */ + public fun arguments(block: JsonObjectBuilder.() -> Unit): Unit = arguments(buildJsonObject(block)) + + @PublishedApi + override fun build(): CallToolRequest { + val name = requireNotNull(name) { + "Missing required field 'name'. Example: name = \"toolName\"" + } + + val params = CallToolRequestParams(name = name, arguments = arguments, meta = meta) + return CallToolRequest(params) + } +} + +/** + * Creates a [ListToolsRequest] using a type-safe DSL builder. + * + * ## Optional + * - [cursor][ListToolsRequestBuilder.cursor] - Pagination cursor for fetching next page + * - [meta][ListToolsRequestBuilder.meta] - Metadata for the request + * + * Example without pagination: + * ```kotlin + * val request = buildListToolsRequest { } + * ``` + * + * Example with pagination: + * ```kotlin + * val request = buildListToolsRequest { + * cursor = "eyJwYWdlIjogMn0=" + * } + * ``` + * + * @param block Configuration lambda for setting up the list tools request + * @return A configured [ListToolsRequest] instance + * @see ListToolsRequestBuilder + * @see ListToolsRequest + */ +@OptIn(ExperimentalContracts::class) +@ExperimentalMcpApi +internal inline fun buildListToolsRequest(block: ListToolsRequestBuilder.() -> Unit): ListToolsRequest { + contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } + return ListToolsRequestBuilder().apply(block).build() +} + +/** + * DSL builder for constructing [ListToolsRequest] instances. + * + * This builder retrieves a list of available tools, with optional pagination support. + * All fields are optional. + * + * ## Optional + * - [cursor] - Pagination cursor (inherited from [PaginatedRequestBuilder]) + * - [meta] - Metadata for the request (inherited from [RequestBuilder]) + * + * @see buildListToolsRequest + * @see ListToolsRequest + * @see PaginatedRequestBuilder + */ +@McpDsl +public class ListToolsRequestBuilder @PublishedApi internal constructor() : PaginatedRequestBuilder() { + @PublishedApi + override fun build(): ListToolsRequest { + val params = paginatedRequestParams(cursor = cursor, meta = meta) + return ListToolsRequest(params) + } +}