feat: Added the annotations attribute to McpSchema.Tool (#313)

Signed-off-by: Sun Yuhan <sunyuhan1998@users.noreply.github.com>
This commit is contained in:
Sun Yuhan 2025-06-13 19:58:12 +08:00 • committed by Christian Tzolov
commit ba5bc94963
2 changed files with 52 additions and 5 deletions

View file

@ -806,6 +806,17 @@ public final class McpSchema {
@JsonProperty("definitions") Map<String, Object> definitions) {
} // @formatter:on
@JsonInclude(JsonInclude.Include.NON_ABSENT)
@JsonIgnoreProperties(ignoreUnknown = true)
public record ToolAnnotations( // @formatter:off
@JsonProperty("title") String title,
@JsonProperty("readOnlyHint") Boolean readOnlyHint,
@JsonProperty("destructiveHint") Boolean destructiveHint,
@JsonProperty("idempotentHint") Boolean idempotentHint,
@JsonProperty("openWorldHint") Boolean openWorldHint,
@JsonProperty("returnDirect") Boolean returnDirect) {
} // @formatter:on
/**
* Represents a tool that the server provides. Tools enable servers to expose
* executable functionality to the system. Through these tools, you can interact with
@ -817,17 +828,23 @@ public final class McpSchema {
* used by clients to improve the LLM's understanding of available tools.
* @param inputSchema A JSON Schema object that describes the expected structure of
* the arguments when calling this tool. This allows clients to validate tool
* arguments before sending them to the server.
* @param annotations Additional properties describing a Tool to clients. arguments
* before sending them to the server.
*/
@JsonInclude(JsonInclude.Include.NON_ABSENT)
@JsonIgnoreProperties(ignoreUnknown = true)
public record Tool( // @formatter:off
@JsonProperty("name") String name,
@JsonProperty("description") String description,
@JsonProperty("inputSchema") JsonSchema inputSchema) {
@JsonProperty("name") String name,
@JsonProperty("description") String description,
@JsonProperty("inputSchema") JsonSchema inputSchema,
@JsonProperty("annotations") ToolAnnotations annotations) {
public Tool(String name, String description, String schema) {
this(name, description, parseSchema(schema));
this(name, description, parseSchema(schema), null);
}
public Tool(String name, String description, String schema, ToolAnnotations annotations) {
this(name, description, parseSchema(schema), annotations);
}
} // @formatter:on

View file

@ -682,6 +682,36 @@ public class McpSchemaTests {
assertThat(deserializedTool.inputSchema().defs()).containsKey("Address");
}
@Test
void testToolWithAnnotations() throws Exception {
String schemaJson = """
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"value": {
"type": "number"
}
},
"required": ["name"]
}
""";
McpSchema.ToolAnnotations annotations = new McpSchema.ToolAnnotations("A test tool", false, false, false, false,
false);
McpSchema.Tool tool = new McpSchema.Tool("test-tool", "A test tool", schemaJson, annotations);
String value = mapper.writeValueAsString(tool);
assertThatJson(value).when(Option.IGNORING_ARRAY_ORDER)
.when(Option.IGNORING_EXTRA_ARRAY_ITEMS)
.isObject()
.isEqualTo(
json("""
{"name":"test-tool","description":"A test tool","inputSchema":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"number"}},"required":["name"]},"annotations":{"title":"A test tool","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false,"returnDirect":false}}"""));
}
@Test
void testCallToolRequest() throws Exception {
Map<String, Object> arguments = new HashMap<>();