Skip to content

Commit 338f948

Browse files
devcrocodkpavlov
andauthored
feat: add tool execution properties to Tool (#567)
closes #543 ## How Has This Been Tested? unit ## Breaking Changes binary compatibility in the Tool class ## Types of changes - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update ## Checklist - [x] I have read the [MCP Documentation](https://modelcontextprotocol.io) - [x] My code follows the repository's style guidelines - [x] New and existing tests pass locally - [ ] I have added appropriate error handling - [ ] I have added or updated documentation as needed --------- Co-authored-by: Konstantin Pavlov <1517853+kpavlov@users.noreply.github.com>
1 parent 0b39f57 commit 338f948

6 files changed

Lines changed: 188 additions & 8 deletions

File tree

kotlin-sdk-core/api/kotlin-sdk-core.api

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4335,6 +4335,20 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/SubscribeRequestPara
43354335
public final fun serializer ()Lkotlinx/serialization/KSerializer;
43364336
}
43374337

4338+
public final class io/modelcontextprotocol/kotlin/sdk/types/TaskSupport : java/lang/Enum {
4339+
public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport$Companion;
4340+
public static final field Forbidden Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport;
4341+
public static final field Optional Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport;
4342+
public static final field Required Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport;
4343+
public static fun getEntries ()Lkotlin/enums/EnumEntries;
4344+
public static fun valueOf (Ljava/lang/String;)Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport;
4345+
public static fun values ()[Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport;
4346+
}
4347+
4348+
public final class io/modelcontextprotocol/kotlin/sdk/types/TaskSupport$Companion {
4349+
public final fun serializer ()Lkotlinx/serialization/KSerializer;
4350+
}
4351+
43384352
public final class io/modelcontextprotocol/kotlin/sdk/types/TextContent : io/modelcontextprotocol/kotlin/sdk/types/MediaContent {
43394353
public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/TextContent$Companion;
43404354
public fun <init> (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/Annotations;Lkotlinx/serialization/json/JsonObject;)V
@@ -4413,21 +4427,23 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/TextResourceContents
44134427

44144428
public final class io/modelcontextprotocol/kotlin/sdk/types/Tool : io/modelcontextprotocol/kotlin/sdk/types/WithMeta {
44154429
public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/Tool$Companion;
4416-
public fun <init> (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolAnnotations;Ljava/util/List;Lkotlinx/serialization/json/JsonObject;)V
4417-
public synthetic fun <init> (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolAnnotations;Ljava/util/List;Lkotlinx/serialization/json/JsonObject;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
4430+
public fun <init> (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolAnnotations;Ljava/util/List;Lio/modelcontextprotocol/kotlin/sdk/types/ToolExecution;Lkotlinx/serialization/json/JsonObject;)V
4431+
public synthetic fun <init> (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolAnnotations;Ljava/util/List;Lio/modelcontextprotocol/kotlin/sdk/types/ToolExecution;Lkotlinx/serialization/json/JsonObject;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
44184432
public final fun component1 ()Ljava/lang/String;
44194433
public final fun component2 ()Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;
44204434
public final fun component3 ()Ljava/lang/String;
44214435
public final fun component4 ()Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;
44224436
public final fun component5 ()Ljava/lang/String;
44234437
public final fun component6 ()Lio/modelcontextprotocol/kotlin/sdk/types/ToolAnnotations;
44244438
public final fun component7 ()Ljava/util/List;
4425-
public final fun component8 ()Lkotlinx/serialization/json/JsonObject;
4426-
public final fun copy (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolAnnotations;Ljava/util/List;Lkotlinx/serialization/json/JsonObject;)Lio/modelcontextprotocol/kotlin/sdk/types/Tool;
4427-
public static synthetic fun copy$default (Lio/modelcontextprotocol/kotlin/sdk/types/Tool;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolAnnotations;Ljava/util/List;Lkotlinx/serialization/json/JsonObject;ILjava/lang/Object;)Lio/modelcontextprotocol/kotlin/sdk/types/Tool;
4439+
public final fun component8 ()Lio/modelcontextprotocol/kotlin/sdk/types/ToolExecution;
4440+
public final fun component9 ()Lkotlinx/serialization/json/JsonObject;
4441+
public final fun copy (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolAnnotations;Ljava/util/List;Lio/modelcontextprotocol/kotlin/sdk/types/ToolExecution;Lkotlinx/serialization/json/JsonObject;)Lio/modelcontextprotocol/kotlin/sdk/types/Tool;
4442+
public static synthetic fun copy$default (Lio/modelcontextprotocol/kotlin/sdk/types/Tool;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolAnnotations;Ljava/util/List;Lio/modelcontextprotocol/kotlin/sdk/types/ToolExecution;Lkotlinx/serialization/json/JsonObject;ILjava/lang/Object;)Lio/modelcontextprotocol/kotlin/sdk/types/Tool;
44284443
public fun equals (Ljava/lang/Object;)Z
44294444
public final fun getAnnotations ()Lio/modelcontextprotocol/kotlin/sdk/types/ToolAnnotations;
44304445
public final fun getDescription ()Ljava/lang/String;
4446+
public final fun getExecution ()Lio/modelcontextprotocol/kotlin/sdk/types/ToolExecution;
44314447
public final fun getIcons ()Ljava/util/List;
44324448
public final fun getInputSchema ()Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;
44334449
public fun getMeta ()Lkotlinx/serialization/json/JsonObject;
@@ -4491,6 +4507,35 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/ToolAnnotations$Comp
44914507
public final fun serializer ()Lkotlinx/serialization/KSerializer;
44924508
}
44934509

4510+
public final class io/modelcontextprotocol/kotlin/sdk/types/ToolExecution {
4511+
public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/ToolExecution$Companion;
4512+
public fun <init> ()V
4513+
public fun <init> (Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport;)V
4514+
public synthetic fun <init> (Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
4515+
public final fun component1 ()Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport;
4516+
public final fun copy (Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport;)Lio/modelcontextprotocol/kotlin/sdk/types/ToolExecution;
4517+
public static synthetic fun copy$default (Lio/modelcontextprotocol/kotlin/sdk/types/ToolExecution;Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport;ILjava/lang/Object;)Lio/modelcontextprotocol/kotlin/sdk/types/ToolExecution;
4518+
public fun equals (Ljava/lang/Object;)Z
4519+
public final fun getTaskSupport ()Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport;
4520+
public fun hashCode ()I
4521+
public fun toString ()Ljava/lang/String;
4522+
}
4523+
4524+
public final synthetic class io/modelcontextprotocol/kotlin/sdk/types/ToolExecution$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
4525+
public static final field INSTANCE Lio/modelcontextprotocol/kotlin/sdk/types/ToolExecution$$serializer;
4526+
public final fun childSerializers ()[Lkotlinx/serialization/KSerializer;
4527+
public final fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lio/modelcontextprotocol/kotlin/sdk/types/ToolExecution;
4528+
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
4529+
public final fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
4530+
public final fun serialize (Lkotlinx/serialization/encoding/Encoder;Lio/modelcontextprotocol/kotlin/sdk/types/ToolExecution;)V
4531+
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
4532+
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
4533+
}
4534+
4535+
public final class io/modelcontextprotocol/kotlin/sdk/types/ToolExecution$Companion {
4536+
public final fun serializer ()Lkotlinx/serialization/KSerializer;
4537+
}
4538+
44944539
public final class io/modelcontextprotocol/kotlin/sdk/types/ToolListChangedNotification : io/modelcontextprotocol/kotlin/sdk/types/ServerNotification {
44954540
public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/ToolListChangedNotification$Companion;
44964541
public fun <init> ()V

kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1618,7 +1618,7 @@ public fun Tool(
16181618
title,
16191619
annotations,
16201620
icons,
1621-
_meta,
1621+
meta = _meta,
16221622
)
16231623

16241624
/**

kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types/tools.kt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ public fun CallToolResult.Companion.error(content: String, meta: JsonObject? = n
5555
* @property icons Optional set of sized icons that clients can display in their user interface.
5656
* Clients MUST support at least PNG and JPEG formats.
5757
* Clients SHOULD also support SVG and WebP formats.
58+
* @property execution Optional execution-related properties for this tool,
59+
* such as task-augmented execution support.
5860
* @property meta Optional metadata for this tool.
5961
*/
6062
@Serializable
@@ -66,6 +68,7 @@ public data class Tool(
6668
val title: String? = null,
6769
val annotations: ToolAnnotations? = null,
6870
val icons: List<Icon>? = null,
71+
val execution: ToolExecution? = null,
6972
@SerialName("_meta")
7073
override val meta: JsonObject? = null,
7174
) : WithMeta
@@ -92,6 +95,38 @@ public data class ToolSchema(
9295
val type: String = "object"
9396
}
9497

98+
/**
99+
* Execution-related properties for a tool.
100+
*
101+
* @property taskSupport Indicates whether this tool supports task-augmented execution.
102+
* This allows clients to handle long-running operations through polling the task system.
103+
* If omitted (`null`), consumers should treat it as [TaskSupport.Forbidden] per the spec.
104+
*/
105+
@Serializable
106+
public data class ToolExecution(val taskSupport: TaskSupport? = null)
107+
108+
/**
109+
* Indicates whether a tool supports task-augmented execution.
110+
*
111+
* - [Forbidden]: Tool does not support task-augmented execution (default when absent).
112+
* - [Optional]: Tool may support task-augmented execution.
113+
* - [Required]: Tool requires task-augmented execution.
114+
*/
115+
@Serializable
116+
public enum class TaskSupport {
117+
/** Tool does not support task-augmented execution. */
118+
@SerialName("forbidden")
119+
Forbidden,
120+
121+
/** Tool may support task-augmented execution. */
122+
@SerialName("optional")
123+
Optional,
124+
125+
/** Tool requires task-augmented execution. */
126+
@SerialName("required")
127+
Required,
128+
}
129+
95130
/**
96131
* Additional properties describing a Tool to clients.
97132
*

kotlin-sdk-core/src/commonTest/kotlin/io/modelcontextprotocol/kotlin/sdk/types/ToolsTest.kt

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,102 @@ class ToolsTest {
475475
assertEquals(null, result.structuredContent)
476476
}
477477

478+
@Test
479+
fun `should serialize ToolExecution with taskSupport`() {
480+
val execution = ToolExecution(taskSupport = TaskSupport.Required)
481+
482+
verifySerialization(
483+
execution,
484+
McpJson,
485+
"""
486+
{
487+
"taskSupport": "required"
488+
}
489+
""".trimIndent(),
490+
)
491+
}
492+
493+
@Test
494+
fun `should serialize ToolExecution without taskSupport`() {
495+
val execution = ToolExecution()
496+
497+
verifySerialization(
498+
execution,
499+
McpJson,
500+
"{}",
501+
)
502+
}
503+
504+
@Test
505+
fun `should deserialize ToolExecution with taskSupport`() {
506+
val json = """
507+
{
508+
"taskSupport": "optional"
509+
}
510+
""".trimIndent()
511+
512+
val execution = verifyDeserialization<ToolExecution>(McpJson, json)
513+
514+
assertEquals(TaskSupport.Optional, execution.taskSupport)
515+
}
516+
517+
@Test
518+
fun `should deserialize ToolExecution without taskSupport`() {
519+
val json = "{}"
520+
521+
val execution = verifyDeserialization<ToolExecution>(McpJson, json)
522+
523+
assertEquals(null, execution.taskSupport)
524+
}
525+
526+
@Test
527+
fun `should serialize Tool with execution`() {
528+
val tool = Tool(
529+
name = "long-running-task",
530+
inputSchema = ToolSchema(),
531+
description = "A tool that supports task-augmented execution",
532+
execution = ToolExecution(taskSupport = TaskSupport.Required),
533+
)
534+
535+
verifySerialization(
536+
tool,
537+
McpJson,
538+
"""
539+
{
540+
"name": "long-running-task",
541+
"inputSchema": {
542+
"type": "object"
543+
},
544+
"description": "A tool that supports task-augmented execution",
545+
"execution": {
546+
"taskSupport": "required"
547+
}
548+
}
549+
""".trimIndent(),
550+
)
551+
}
552+
553+
@Test
554+
fun `should deserialize Tool with execution`() {
555+
val json = """
556+
{
557+
"name": "long-running-task",
558+
"inputSchema": {
559+
"type": "object"
560+
},
561+
"execution": {
562+
"taskSupport": "forbidden"
563+
}
564+
}
565+
""".trimIndent()
566+
567+
val tool = verifyDeserialization<Tool>(McpJson, json)
568+
569+
assertEquals("long-running-task", tool.name)
570+
assertNotNull(tool.execution)
571+
assertEquals(TaskSupport.Forbidden, tool.execution.taskSupport)
572+
}
573+
478574
@Test
479575
fun `should serialize tool schema type even when defaults disabled`() {
480576
val tool = weatherTool()

kotlin-sdk-server/api/kotlin-sdk-server.api

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ public class io/modelcontextprotocol/kotlin/sdk/server/Server {
9999
public static synthetic fun addResource$default (Lio/modelcontextprotocol/kotlin/sdk/server/Server;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)V
100100
public final fun addResources (Ljava/util/List;)V
101101
public final fun addTool (Lio/modelcontextprotocol/kotlin/sdk/types/Tool;Lkotlin/jvm/functions/Function3;)V
102-
public final fun addTool (Ljava/lang/String;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Lio/modelcontextprotocol/kotlin/sdk/types/ToolAnnotations;Lkotlinx/serialization/json/JsonObject;Lkotlin/jvm/functions/Function3;)V
103-
public static synthetic fun addTool$default (Lio/modelcontextprotocol/kotlin/sdk/server/Server;Ljava/lang/String;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Lio/modelcontextprotocol/kotlin/sdk/types/ToolAnnotations;Lkotlinx/serialization/json/JsonObject;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)V
102+
public final fun addTool (Ljava/lang/String;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Lio/modelcontextprotocol/kotlin/sdk/types/ToolAnnotations;Lio/modelcontextprotocol/kotlin/sdk/types/ToolExecution;Lkotlinx/serialization/json/JsonObject;Lkotlin/jvm/functions/Function3;)V
103+
public static synthetic fun addTool$default (Lio/modelcontextprotocol/kotlin/sdk/server/Server;Ljava/lang/String;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;Lio/modelcontextprotocol/kotlin/sdk/types/ToolAnnotations;Lio/modelcontextprotocol/kotlin/sdk/types/ToolExecution;Lkotlinx/serialization/json/JsonObject;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)V
104104
public final fun addTools (Ljava/util/List;)V
105105
public final fun clientConnection (Ljava/lang/String;)Lio/modelcontextprotocol/kotlin/sdk/server/ClientConnection;
106106
public final fun close (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;

kotlin-sdk-server/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/server/Server.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import io.modelcontextprotocol.kotlin.sdk.types.SubscribeRequest
3838
import io.modelcontextprotocol.kotlin.sdk.types.TextContent
3939
import io.modelcontextprotocol.kotlin.sdk.types.Tool
4040
import io.modelcontextprotocol.kotlin.sdk.types.ToolAnnotations
41+
import io.modelcontextprotocol.kotlin.sdk.types.ToolExecution
4142
import io.modelcontextprotocol.kotlin.sdk.types.ToolSchema
4243
import io.modelcontextprotocol.kotlin.sdk.types.UnsubscribeRequest
4344
import kotlinx.coroutines.CancellationException
@@ -313,6 +314,7 @@ public open class Server(
313314
* @param inputSchema The expected input schema for the tool.
314315
* @param outputSchema The optional expected output schema for the tool.
315316
* @param toolAnnotations Optional additional tool information.
317+
* @param execution Optional execution-related properties, such as task-augmented execution support.
316318
* @param meta Optional metadata as a [JsonObject].
317319
* @param handler A suspend function that handles executing the tool when called by the client.
318320
* @throws IllegalStateException If the server does not support tools.
@@ -325,6 +327,7 @@ public open class Server(
325327
title: String? = null,
326328
outputSchema: ToolSchema? = null,
327329
toolAnnotations: ToolAnnotations? = null,
330+
execution: ToolExecution? = null,
328331
meta: JsonObject? = null,
329332
handler: suspend ClientConnection.(CallToolRequest) -> CallToolResult,
330333
) {
@@ -335,6 +338,7 @@ public open class Server(
335338
description = description,
336339
title = title,
337340
annotations = toolAnnotations,
341+
execution = execution,
338342
meta = meta,
339343
)
340344
addTool(tool, handler)

0 commit comments

Comments
 (0)