Skip to content

Commit b6743ad

Browse files
SeanChinJunKaidevcrocod
authored andcommitted
feat: add tool annotations
1 parent 958e5e5 commit b6743ad

File tree

4 files changed

+62
-1
lines changed

4 files changed

+62
-1
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,14 +183,15 @@ public open class Server(
183183
name: String,
184184
description: String,
185185
inputSchema: Tool.Input = Tool.Input(),
186+
toolAnnotations: ToolAnnotations? = null,
186187
handler: suspend (CallToolRequest) -> CallToolResult
187188
) {
188189
if (capabilities.tools == null) {
189190
logger.error { "Failed to add tool '$name': Server does not support tools capability" }
190191
throw IllegalStateException("Server does not support tools capability. Enable it in ServerOptions.")
191192
}
192193
logger.info { "Registering tool: $name" }
193-
tools[name] = RegisteredTool(Tool(name, description, inputSchema), handler)
194+
tools[name] = RegisteredTool(Tool(name, description, inputSchema, toolAnnotations), handler)
194195
}
195196

196197
/**

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,58 @@ public class PromptListChangedNotification : ServerNotification {
10311031
}
10321032

10331033
/* Tools */
1034+
/**
1035+
* Additional properties describing a Tool to clients.
1036+
*
1037+
* NOTE: all properties in ToolAnnotations are **hints**.
1038+
* They are not guaranteed to provide a faithful description of
1039+
* tool behavior (including descriptive properties like `title`).
1040+
*
1041+
* Clients should never make tool use decisions based on ToolAnnotations
1042+
* received from untrusted servers.
1043+
*/
1044+
@Serializable
1045+
public data class ToolAnnotations(
1046+
/**
1047+
* A human-readable title for the tool.
1048+
*/
1049+
val title: String?,
1050+
/**
1051+
* If true, the tool does not modify its environment.
1052+
*
1053+
* Default: false
1054+
*/
1055+
val readOnlyHint: Boolean? = false,
1056+
/**
1057+
* If true, the tool may perform destructive updates to its environment.
1058+
* If false, the tool performs only additive updates.
1059+
*
1060+
* (This property is meaningful only when `readOnlyHint == false`)
1061+
*
1062+
* Default: true
1063+
*/
1064+
val destructiveHint: Boolean? = true,
1065+
/**
1066+
* If true, calling the tool repeatedly with the same arguments
1067+
* will have no additional effect on the its environment.
1068+
*
1069+
* (This property is meaningful only when `readOnlyHint == false`)
1070+
*
1071+
* Default: false
1072+
*/
1073+
val idempotentHint: Boolean? = false,
1074+
/**
1075+
* If true, this tool may interact with an "open world" of external
1076+
* entities. If false, the tool's domain of interaction is closed.
1077+
* For example, the world of a web search tool is open, whereas that
1078+
* of a memory tool is not.
1079+
*
1080+
* Default: true
1081+
*/
1082+
val openWorldHint: Boolean? = true,
1083+
)
1084+
1085+
10341086
/**
10351087
* Definition for a tool the client can call.
10361088
*/
@@ -1048,6 +1100,11 @@ public data class Tool(
10481100
* A JSON object defining the expected parameters for the tool.
10491101
*/
10501102
val inputSchema: Input,
1103+
1104+
/**
1105+
* Optional additional tool information.
1106+
*/
1107+
val annotations: ToolAnnotations?,
10511108
) {
10521109
@Serializable
10531110
public data class Input(

src/commonTest/kotlin/io/modelcontextprotocol/kotlin/sdk/ToolSerializationTest.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package io.modelcontextprotocol.kotlin.sdk
22

33
import io.kotest.assertions.json.shouldEqualJson
44
import io.modelcontextprotocol.kotlin.sdk.shared.McpJson
5+
import kotlinx.atomicfu.atomicArrayOfNulls
56
import kotlinx.serialization.encodeToString
67
import kotlinx.serialization.json.Json
78
import kotlinx.serialization.json.JsonPrimitive
@@ -33,6 +34,7 @@ class ToolSerializationTest {
3334
val getWeatherTool = Tool(
3435
name = "get_weather",
3536
description = "Get the current weather in a given location",
37+
annotations = null,
3638
inputSchema = Tool.Input(
3739
properties = buildJsonObject {
3840
put("location", buildJsonObject {

src/jvmTest/kotlin/client/ClientTest.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,7 @@ class ClientTest {
583583
Tool(
584584
name = "testTool",
585585
description = "testTool description",
586+
annotations = null,
586587
inputSchema = Tool.Input()
587588
)
588589
), nextCursor = null

0 commit comments

Comments
 (0)