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>
This commit is contained in:
Pavel Gorgulov 2026-03-10 20:05:44 +01:00 • committed by GitHub
commit 338f94804f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 188 additions and 8 deletions

View file

@ -4335,6 +4335,20 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/SubscribeRequestPara
public final fun serializer ()Lkotlinx/serialization/KSerializer; public final fun serializer ()Lkotlinx/serialization/KSerializer;
} }
public final class io/modelcontextprotocol/kotlin/sdk/types/TaskSupport : java/lang/Enum {
public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport$Companion;
public static final field Forbidden Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport;
public static final field Optional Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport;
public static final field Required Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport;
public static fun getEntries ()Lkotlin/enums/EnumEntries;
public static fun valueOf (Ljava/lang/String;)Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport;
public static fun values ()[Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport;
}
public final class io/modelcontextprotocol/kotlin/sdk/types/TaskSupport$Companion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}
public final class io/modelcontextprotocol/kotlin/sdk/types/TextContent : io/modelcontextprotocol/kotlin/sdk/types/MediaContent { public final class io/modelcontextprotocol/kotlin/sdk/types/TextContent : io/modelcontextprotocol/kotlin/sdk/types/MediaContent {
public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/TextContent$Companion; public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/TextContent$Companion;
public fun <init> (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/Annotations;Lkotlinx/serialization/json/JsonObject;)V public fun <init> (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/types/Annotations;Lkotlinx/serialization/json/JsonObject;)V
@ -4413,8 +4427,8 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/TextResourceContents
public final class io/modelcontextprotocol/kotlin/sdk/types/Tool : io/modelcontextprotocol/kotlin/sdk/types/WithMeta { public final class io/modelcontextprotocol/kotlin/sdk/types/Tool : io/modelcontextprotocol/kotlin/sdk/types/WithMeta {
public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/Tool$Companion; public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/Tool$Companion;
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 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
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 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
public final fun component1 ()Ljava/lang/String; public final fun component1 ()Ljava/lang/String;
public final fun component2 ()Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema; public final fun component2 ()Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;
public final fun component3 ()Ljava/lang/String; public final fun component3 ()Ljava/lang/String;
@ -4422,12 +4436,14 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/Tool : io/modelconte
public final fun component5 ()Ljava/lang/String; public final fun component5 ()Ljava/lang/String;
public final fun component6 ()Lio/modelcontextprotocol/kotlin/sdk/types/ToolAnnotations; public final fun component6 ()Lio/modelcontextprotocol/kotlin/sdk/types/ToolAnnotations;
public final fun component7 ()Ljava/util/List; public final fun component7 ()Ljava/util/List;
public final fun component8 ()Lkotlinx/serialization/json/JsonObject; public final fun component8 ()Lio/modelcontextprotocol/kotlin/sdk/types/ToolExecution;
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; public final fun component9 ()Lkotlinx/serialization/json/JsonObject;
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; 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;
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;
public fun equals (Ljava/lang/Object;)Z public fun equals (Ljava/lang/Object;)Z
public final fun getAnnotations ()Lio/modelcontextprotocol/kotlin/sdk/types/ToolAnnotations; public final fun getAnnotations ()Lio/modelcontextprotocol/kotlin/sdk/types/ToolAnnotations;
public final fun getDescription ()Ljava/lang/String; public final fun getDescription ()Ljava/lang/String;
public final fun getExecution ()Lio/modelcontextprotocol/kotlin/sdk/types/ToolExecution;
public final fun getIcons ()Ljava/util/List; public final fun getIcons ()Ljava/util/List;
public final fun getInputSchema ()Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema; public final fun getInputSchema ()Lio/modelcontextprotocol/kotlin/sdk/types/ToolSchema;
public fun getMeta ()Lkotlinx/serialization/json/JsonObject; public fun getMeta ()Lkotlinx/serialization/json/JsonObject;
@ -4491,6 +4507,35 @@ public final class io/modelcontextprotocol/kotlin/sdk/types/ToolAnnotations$Comp
public final fun serializer ()Lkotlinx/serialization/KSerializer; public final fun serializer ()Lkotlinx/serialization/KSerializer;
} }
public final class io/modelcontextprotocol/kotlin/sdk/types/ToolExecution {
public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/ToolExecution$Companion;
public fun <init> ()V
public fun <init> (Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport;)V
public synthetic fun <init> (Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport;
public final fun copy (Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport;)Lio/modelcontextprotocol/kotlin/sdk/types/ToolExecution;
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;
public fun equals (Ljava/lang/Object;)Z
public final fun getTaskSupport ()Lio/modelcontextprotocol/kotlin/sdk/types/TaskSupport;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public final synthetic class io/modelcontextprotocol/kotlin/sdk/types/ToolExecution$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
public static final field INSTANCE Lio/modelcontextprotocol/kotlin/sdk/types/ToolExecution$$serializer;
public final fun childSerializers ()[Lkotlinx/serialization/KSerializer;
public final fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lio/modelcontextprotocol/kotlin/sdk/types/ToolExecution;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public final fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public final fun serialize (Lkotlinx/serialization/encoding/Encoder;Lio/modelcontextprotocol/kotlin/sdk/types/ToolExecution;)V
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
}
public final class io/modelcontextprotocol/kotlin/sdk/types/ToolExecution$Companion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}
public final class io/modelcontextprotocol/kotlin/sdk/types/ToolListChangedNotification : io/modelcontextprotocol/kotlin/sdk/types/ServerNotification { public final class io/modelcontextprotocol/kotlin/sdk/types/ToolListChangedNotification : io/modelcontextprotocol/kotlin/sdk/types/ServerNotification {
public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/ToolListChangedNotification$Companion; public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/types/ToolListChangedNotification$Companion;
public fun <init> ()V public fun <init> ()V

View file

@ -1618,7 +1618,7 @@ public fun Tool(
title, title,
annotations, annotations,
icons, icons,
_meta, meta = _meta,
) )
/** /**

View file

@ -55,6 +55,8 @@ public fun CallToolResult.Companion.error(content: String, meta: JsonObject? = n
* @property icons Optional set of sized icons that clients can display in their user interface. * @property icons Optional set of sized icons that clients can display in their user interface.
* Clients MUST support at least PNG and JPEG formats. * Clients MUST support at least PNG and JPEG formats.
* Clients SHOULD also support SVG and WebP formats. * Clients SHOULD also support SVG and WebP formats.
* @property execution Optional execution-related properties for this tool,
* such as task-augmented execution support.
* @property meta Optional metadata for this tool. * @property meta Optional metadata for this tool.
*/ */
@Serializable @Serializable
@ -66,6 +68,7 @@ public data class Tool(
val title: String? = null, val title: String? = null,
val annotations: ToolAnnotations? = null, val annotations: ToolAnnotations? = null,
val icons: List<Icon>? = null, val icons: List<Icon>? = null,
val execution: ToolExecution? = null,
@SerialName("_meta") @SerialName("_meta")
override val meta: JsonObject? = null, override val meta: JsonObject? = null,
) : WithMeta ) : WithMeta
@ -92,6 +95,38 @@ public data class ToolSchema(
val type: String = "object" val type: String = "object"
} }
/**
* Execution-related properties for a tool.
*
* @property taskSupport Indicates whether this tool supports task-augmented execution.
* This allows clients to handle long-running operations through polling the task system.
* If omitted (`null`), consumers should treat it as [TaskSupport.Forbidden] per the spec.
*/
@Serializable
public data class ToolExecution(val taskSupport: TaskSupport? = null)
/**
* Indicates whether a tool supports task-augmented execution.
*
* - [Forbidden]: Tool does not support task-augmented execution (default when absent).
* - [Optional]: Tool may support task-augmented execution.
* - [Required]: Tool requires task-augmented execution.
*/
@Serializable
public enum class TaskSupport {
/** Tool does not support task-augmented execution. */
@SerialName("forbidden")
Forbidden,
/** Tool may support task-augmented execution. */
@SerialName("optional")
Optional,
/** Tool requires task-augmented execution. */
@SerialName("required")
Required,
}
/** /**
* Additional properties describing a Tool to clients. * Additional properties describing a Tool to clients.
* *

View file

@ -475,6 +475,102 @@ class ToolsTest {
assertEquals(null, result.structuredContent) assertEquals(null, result.structuredContent)
} }
@Test
fun `should serialize ToolExecution with taskSupport`() {
val execution = ToolExecution(taskSupport = TaskSupport.Required)
verifySerialization(
execution,
McpJson,
"""
{
"taskSupport": "required"
}
""".trimIndent(),
)
}
@Test
fun `should serialize ToolExecution without taskSupport`() {
val execution = ToolExecution()
verifySerialization(
execution,
McpJson,
"{}",
)
}
@Test
fun `should deserialize ToolExecution with taskSupport`() {
val json = """
{
"taskSupport": "optional"
}
""".trimIndent()
val execution = verifyDeserialization<ToolExecution>(McpJson, json)
assertEquals(TaskSupport.Optional, execution.taskSupport)
}
@Test
fun `should deserialize ToolExecution without taskSupport`() {
val json = "{}"
val execution = verifyDeserialization<ToolExecution>(McpJson, json)
assertEquals(null, execution.taskSupport)
}
@Test
fun `should serialize Tool with execution`() {
val tool = Tool(
name = "long-running-task",
inputSchema = ToolSchema(),
description = "A tool that supports task-augmented execution",
execution = ToolExecution(taskSupport = TaskSupport.Required),
)
verifySerialization(
tool,
McpJson,
"""
{
"name": "long-running-task",
"inputSchema": {
"type": "object"
},
"description": "A tool that supports task-augmented execution",
"execution": {
"taskSupport": "required"
}
}
""".trimIndent(),
)
}
@Test
fun `should deserialize Tool with execution`() {
val json = """
{
"name": "long-running-task",
"inputSchema": {
"type": "object"
},
"execution": {
"taskSupport": "forbidden"
}
}
""".trimIndent()
val tool = verifyDeserialization<Tool>(McpJson, json)
assertEquals("long-running-task", tool.name)
assertNotNull(tool.execution)
assertEquals(TaskSupport.Forbidden, tool.execution.taskSupport)
}
@Test @Test
fun `should serialize tool schema type even when defaults disabled`() { fun `should serialize tool schema type even when defaults disabled`() {
val tool = weatherTool() val tool = weatherTool()

View file

@ -99,8 +99,8 @@ public class io/modelcontextprotocol/kotlin/sdk/server/Server {
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 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
public final fun addResources (Ljava/util/List;)V public final fun addResources (Ljava/util/List;)V
public final fun addTool (Lio/modelcontextprotocol/kotlin/sdk/types/Tool;Lkotlin/jvm/functions/Function3;)V public final fun addTool (Lio/modelcontextprotocol/kotlin/sdk/types/Tool;Lkotlin/jvm/functions/Function3;)V
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 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
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 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
public final fun addTools (Ljava/util/List;)V public final fun addTools (Ljava/util/List;)V
public final fun clientConnection (Ljava/lang/String;)Lio/modelcontextprotocol/kotlin/sdk/server/ClientConnection; public final fun clientConnection (Ljava/lang/String;)Lio/modelcontextprotocol/kotlin/sdk/server/ClientConnection;
public final fun close (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun close (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;

View file

@ -38,6 +38,7 @@ import io.modelcontextprotocol.kotlin.sdk.types.SubscribeRequest
import io.modelcontextprotocol.kotlin.sdk.types.TextContent import io.modelcontextprotocol.kotlin.sdk.types.TextContent
import io.modelcontextprotocol.kotlin.sdk.types.Tool import io.modelcontextprotocol.kotlin.sdk.types.Tool
import io.modelcontextprotocol.kotlin.sdk.types.ToolAnnotations import io.modelcontextprotocol.kotlin.sdk.types.ToolAnnotations
import io.modelcontextprotocol.kotlin.sdk.types.ToolExecution
import io.modelcontextprotocol.kotlin.sdk.types.ToolSchema import io.modelcontextprotocol.kotlin.sdk.types.ToolSchema
import io.modelcontextprotocol.kotlin.sdk.types.UnsubscribeRequest import io.modelcontextprotocol.kotlin.sdk.types.UnsubscribeRequest
import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CancellationException
@ -313,6 +314,7 @@ public open class Server(
* @param inputSchema The expected input schema for the tool. * @param inputSchema The expected input schema for the tool.
* @param outputSchema The optional expected output schema for the tool. * @param outputSchema The optional expected output schema for the tool.
* @param toolAnnotations Optional additional tool information. * @param toolAnnotations Optional additional tool information.
* @param execution Optional execution-related properties, such as task-augmented execution support.
* @param meta Optional metadata as a [JsonObject]. * @param meta Optional metadata as a [JsonObject].
* @param handler A suspend function that handles executing the tool when called by the client. * @param handler A suspend function that handles executing the tool when called by the client.
* @throws IllegalStateException If the server does not support tools. * @throws IllegalStateException If the server does not support tools.
@ -325,6 +327,7 @@ public open class Server(
title: String? = null, title: String? = null,
outputSchema: ToolSchema? = null, outputSchema: ToolSchema? = null,
toolAnnotations: ToolAnnotations? = null, toolAnnotations: ToolAnnotations? = null,
execution: ToolExecution? = null,
meta: JsonObject? = null, meta: JsonObject? = null,
handler: suspend ClientConnection.(CallToolRequest) -> CallToolResult, handler: suspend ClientConnection.(CallToolRequest) -> CallToolResult,
) { ) {
@ -335,6 +338,7 @@ public open class Server(
description = description, description = description,
title = title, title = title,
annotations = toolAnnotations, annotations = toolAnnotations,
execution = execution,
meta = meta, meta = meta,
) )
addTool(tool, handler) addTool(tool, handler)