From 6b0a8eea061cd19b829eb104122c8451cc5fd120 Mon Sep 17 00:00:00 2001 From: Bilal Oumehdi Date: Tue, 13 Jan 2026 02:51:33 +0100 Subject: [PATCH] feat: remove JsonSchema an use a Map for inputSchema --- .../modelcontextprotocol/spec/McpSchema.java | 38 ++-------------- .../client/McpAsyncClientTests.java | 3 +- .../server/AbstractMcpAsyncServerTests.java | 36 +++++----------- ...stractMcpClientServerIntegrationTests.java | 43 ++++++++----------- .../server/AbstractMcpSyncServerTests.java | 30 ++++--------- .../AsyncToolSpecificationBuilderTest.java | 31 +++---------- .../HttpServletStatelessIntegrationTests.java | 3 +- .../SyncToolSpecificationBuilderTest.java | 13 ++---- .../spec/McpSchemaTests.java | 23 ++++++---- .../modelcontextprotocol/util/ToolsUtils.java | 3 -- ...stractMcpClientServerIntegrationTests.java | 43 ++++++++----------- .../AbstractStatelessIntegrationTests.java | 17 ++------ .../server/AbstractMcpAsyncServerTests.java | 36 +++++----------- .../server/AbstractMcpSyncServerTests.java | 30 ++++--------- .../modelcontextprotocol/util/ToolsUtils.java | 3 -- 15 files changed, 107 insertions(+), 245 deletions(-) diff --git a/mcp-core/src/main/java/io/modelcontextprotocol/spec/McpSchema.java b/mcp-core/src/main/java/io/modelcontextprotocol/spec/McpSchema.java index b58f1c552..c271f734f 100644 --- a/mcp-core/src/main/java/io/modelcontextprotocol/spec/McpSchema.java +++ b/mcp-core/src/main/java/io/modelcontextprotocol/spec/McpSchema.java @@ -1330,27 +1330,6 @@ public ListToolsResult(List tools, String nextCursor) { } } - /** - * A JSON Schema object that describes the expected structure of arguments or output. - * - * @param type The type of the schema (e.g., "object") - * @param properties The properties of the schema object - * @param required List of required property names - * @param additionalProperties Whether additional properties are allowed - * @param defs Schema definitions using the newer $defs keyword - * @param definitions Schema definitions using the legacy definitions keyword - */ - @JsonInclude(JsonInclude.Include.NON_ABSENT) - @JsonIgnoreProperties(ignoreUnknown = true) - public record JsonSchema( // @formatter:off - @JsonProperty("type") String type, - @JsonProperty("properties") Map properties, - @JsonProperty("required") List required, - @JsonProperty("additionalProperties") Boolean additionalProperties, - @JsonProperty("$defs") Map defs, - @JsonProperty("definitions") Map definitions) { // @formatter:on - } - /** * Additional properties describing a Tool to clients. * @@ -1395,7 +1374,7 @@ public record Tool( // @formatter:off @JsonProperty("name") String name, @JsonProperty("title") String title, @JsonProperty("description") String description, - @JsonProperty("inputSchema") JsonSchema inputSchema, + @JsonProperty("inputSchema") Map inputSchema, @JsonProperty("outputSchema") Map outputSchema, @JsonProperty("annotations") ToolAnnotations annotations, @JsonProperty("_meta") Map meta) { // @formatter:on @@ -1412,7 +1391,7 @@ public static class Builder { private String description; - private JsonSchema inputSchema; + private Map inputSchema; private Map outputSchema; @@ -1435,13 +1414,13 @@ public Builder description(String description) { return this; } - public Builder inputSchema(JsonSchema inputSchema) { + public Builder inputSchema(Map inputSchema) { this.inputSchema = inputSchema; return this; } public Builder inputSchema(McpJsonMapper jsonMapper, String inputSchema) { - this.inputSchema = parseSchema(jsonMapper, inputSchema); + this.inputSchema = schemaToMap(jsonMapper, inputSchema); return this; } @@ -1482,15 +1461,6 @@ private static Map schemaToMap(McpJsonMapper jsonMapper, String } } - private static JsonSchema parseSchema(McpJsonMapper jsonMapper, String schema) { - try { - return jsonMapper.readValue(schema, JsonSchema.class); - } - catch (IOException e) { - throw new IllegalArgumentException("Invalid schema: " + schema, e); - } - } - /** * Used by the client to call a tool provided by the server. * diff --git a/mcp-core/src/test/java/io/modelcontextprotocol/client/McpAsyncClientTests.java b/mcp-core/src/test/java/io/modelcontextprotocol/client/McpAsyncClientTests.java index 48bf1da5b..a6738d4f8 100644 --- a/mcp-core/src/test/java/io/modelcontextprotocol/client/McpAsyncClientTests.java +++ b/mcp-core/src/test/java/io/modelcontextprotocol/client/McpAsyncClientTests.java @@ -44,11 +44,10 @@ private McpClientTransport createMockTransportForToolValidation(boolean hasOutpu Map inputSchemaMap = Map.of("type", "object", "properties", Map.of("expression", Map.of("type", "string")), "required", List.of("expression")); - McpSchema.JsonSchema inputSchema = new McpSchema.JsonSchema("object", inputSchemaMap, null, null, null, null); McpSchema.Tool.Builder toolBuilder = McpSchema.Tool.builder() .name("calculator") .description("Performs mathematical calculations") - .inputSchema(inputSchema); + .inputSchema(inputSchemaMap); if (hasOutputSchema) { Map outputSchema = Map.of("type", "object", "properties", diff --git a/mcp-core/src/test/java/io/modelcontextprotocol/server/AbstractMcpAsyncServerTests.java b/mcp-core/src/test/java/io/modelcontextprotocol/server/AbstractMcpAsyncServerTests.java index 090710248..a425d68fa 100644 --- a/mcp-core/src/test/java/io/modelcontextprotocol/server/AbstractMcpAsyncServerTests.java +++ b/mcp-core/src/test/java/io/modelcontextprotocol/server/AbstractMcpAsyncServerTests.java @@ -6,6 +6,7 @@ import java.time.Duration; import java.util.List; +import java.util.Map; import io.modelcontextprotocol.spec.McpSchema; import io.modelcontextprotocol.spec.McpSchema.CallToolResult; @@ -23,7 +24,6 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; -import static io.modelcontextprotocol.util.ToolsUtils.EMPTY_JSON_SCHEMA; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -94,11 +94,7 @@ void testImmediateClose() { @Test @Deprecated void testAddTool() { - Tool newTool = McpSchema.Tool.builder() - .name("new-tool") - .title("New test tool") - .inputSchema(EMPTY_JSON_SCHEMA) - .build(); + Tool newTool = McpSchema.Tool.builder().name("new-tool").title("New test tool").inputSchema(Map.of()).build(); var mcpAsyncServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0") .capabilities(ServerCapabilities.builder().tools(true).build()) .build(); @@ -113,11 +109,7 @@ void testAddTool() { @Test void testAddToolCall() { - Tool newTool = McpSchema.Tool.builder() - .name("new-tool") - .title("New test tool") - .inputSchema(EMPTY_JSON_SCHEMA) - .build(); + Tool newTool = McpSchema.Tool.builder().name("new-tool").title("New test tool").inputSchema(Map.of()).build(); var mcpAsyncServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0") .capabilities(ServerCapabilities.builder().tools(true).build()) @@ -138,7 +130,7 @@ void testAddDuplicateTool() { Tool duplicateTool = McpSchema.Tool.builder() .name(TEST_TOOL_NAME) .title("Duplicate tool") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); var mcpAsyncServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0") @@ -160,7 +152,7 @@ void testAddDuplicateToolCall() { Tool duplicateTool = McpSchema.Tool.builder() .name(TEST_TOOL_NAME) .title("Duplicate tool") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); var mcpAsyncServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0") @@ -184,7 +176,7 @@ void testDuplicateToolCallDuringBuilding() { Tool duplicateTool = McpSchema.Tool.builder() .name("duplicate-build-toolcall") .title("Duplicate toolcall during building") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); assertThatThrownBy(() -> prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0") @@ -204,7 +196,7 @@ void testDuplicateToolsInBatchListRegistration() { Tool duplicateTool = McpSchema.Tool.builder() .name("batch-list-tool") .title("Duplicate tool in batch list") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); List specs = List.of( @@ -232,7 +224,7 @@ void testDuplicateToolsInBatchVarargsRegistration() { Tool duplicateTool = McpSchema.Tool.builder() .name("batch-varargs-tool") .title("Duplicate tool in batch varargs") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); assertThatThrownBy(() -> prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0") @@ -254,11 +246,7 @@ void testDuplicateToolsInBatchVarargsRegistration() { @Test void testRemoveTool() { - Tool too = McpSchema.Tool.builder() - .name(TEST_TOOL_NAME) - .title("Duplicate tool") - .inputSchema(EMPTY_JSON_SCHEMA) - .build(); + Tool too = McpSchema.Tool.builder().name(TEST_TOOL_NAME).title("Duplicate tool").inputSchema(Map.of()).build(); var mcpAsyncServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0") .capabilities(ServerCapabilities.builder().tools(true).build()) @@ -285,11 +273,7 @@ void testRemoveNonexistentTool() { @Test void testNotifyToolsListChanged() { - Tool too = McpSchema.Tool.builder() - .name(TEST_TOOL_NAME) - .title("Duplicate tool") - .inputSchema(EMPTY_JSON_SCHEMA) - .build(); + Tool too = McpSchema.Tool.builder().name(TEST_TOOL_NAME).title("Duplicate tool").inputSchema(Map.of()).build(); var mcpAsyncServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0") .capabilities(ServerCapabilities.builder().tools(true).build()) diff --git a/mcp-core/src/test/java/io/modelcontextprotocol/server/AbstractMcpClientServerIntegrationTests.java b/mcp-core/src/test/java/io/modelcontextprotocol/server/AbstractMcpClientServerIntegrationTests.java index 1f5387f37..7996a476f 100644 --- a/mcp-core/src/test/java/io/modelcontextprotocol/server/AbstractMcpClientServerIntegrationTests.java +++ b/mcp-core/src/test/java/io/modelcontextprotocol/server/AbstractMcpClientServerIntegrationTests.java @@ -51,7 +51,6 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; -import static io.modelcontextprotocol.util.ToolsUtils.EMPTY_JSON_SCHEMA; import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; import static net.javacrumbs.jsonunit.assertj.JsonAssertions.json; import static org.assertj.core.api.Assertions.assertThat; @@ -103,7 +102,7 @@ void testCreateMessageWithoutSamplingCapabilities(String clientType) { var clientBuilder = clientBuilders.get(clientType); McpServerFeatures.AsyncToolSpecification tool = McpServerFeatures.AsyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { return exchange.createMessage(mock(McpSchema.CreateMessageRequest.class)) .then(Mono.just(mock(CallToolResult.class))); @@ -153,7 +152,7 @@ void testCreateMessageSuccess(String clientType) { AtomicReference samplingResult = new AtomicReference<>(); McpServerFeatures.AsyncToolSpecification tool = McpServerFeatures.AsyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { var createMessageRequest = McpSchema.CreateMessageRequest.builder() @@ -232,7 +231,7 @@ void testCreateMessageWithRequestTimeoutSuccess(String clientType) throws Interr AtomicReference samplingResult = new AtomicReference<>(); McpServerFeatures.AsyncToolSpecification tool = McpServerFeatures.AsyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { var createMessageRequest = McpSchema.CreateMessageRequest.builder() @@ -307,7 +306,7 @@ void testCreateMessageWithRequestTimeoutFail(String clientType) throws Interrupt .build(); McpServerFeatures.AsyncToolSpecification tool = McpServerFeatures.AsyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { var createMessageRequest = McpSchema.CreateMessageRequest.builder() @@ -357,7 +356,7 @@ void testCreateElicitationWithoutElicitationCapabilities(String clientType) { var clientBuilder = clientBuilders.get(clientType); McpServerFeatures.AsyncToolSpecification tool = McpServerFeatures.AsyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> exchange.createElicitation(mock(ElicitRequest.class)) .then(Mono.just(mock(CallToolResult.class)))) .build(); @@ -401,7 +400,7 @@ void testCreateElicitationSuccess(String clientType) { .build(); McpServerFeatures.AsyncToolSpecification tool = McpServerFeatures.AsyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { var elicitationRequest = McpSchema.ElicitRequest.builder() @@ -459,7 +458,7 @@ void testCreateElicitationWithRequestTimeoutSuccess(String clientType) { AtomicReference resultRef = new AtomicReference<>(); McpServerFeatures.AsyncToolSpecification tool = McpServerFeatures.AsyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { var elicitationRequest = McpSchema.ElicitRequest.builder() @@ -530,7 +529,7 @@ void testCreateElicitationWithRequestTimeoutFail(String clientType) { AtomicReference resultRef = new AtomicReference<>(); McpServerFeatures.AsyncToolSpecification tool = McpServerFeatures.AsyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { var elicitationRequest = ElicitRequest.builder() @@ -628,7 +627,7 @@ void testRootsWithoutCapability(String clientType) { var clientBuilder = clientBuilders.get(clientType); McpServerFeatures.SyncToolSpecification tool = McpServerFeatures.SyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { exchange.listRoots(); // try to list roots @@ -770,7 +769,7 @@ void testToolCallSuccess(String clientType) { .addContent(new McpSchema.TextContent("CALL RESPONSE; ctx=importantValue")) .build(); McpServerFeatures.SyncToolSpecification tool1 = McpServerFeatures.SyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { try { @@ -821,11 +820,7 @@ void testThrowingToolCallIsCaughtBeforeTimeout(String clientType) { McpSyncServer mcpServer = prepareSyncServerBuilder() .capabilities(ServerCapabilities.builder().tools(true).build()) .tools(McpServerFeatures.SyncToolSpecification.builder() - .tool(Tool.builder() - .name("tool1") - .description("tool1 description") - .inputSchema(EMPTY_JSON_SCHEMA) - .build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { // We trigger a timeout on blocking read, raising an exception Mono.never().block(Duration.ofSeconds(1)); @@ -863,7 +858,7 @@ void testToolCallSuccessWithTransportContextExtraction(String clientType) { .addContent(new McpSchema.TextContent("CALL RESPONSE; ctx=value")) .build(); McpServerFeatures.SyncToolSpecification tool1 = McpServerFeatures.SyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { McpTransportContext transportContext = exchange.transportContext(); @@ -919,7 +914,7 @@ void testToolListChangeHandlingSuccess(String clientType) { .build(); McpServerFeatures.SyncToolSpecification tool1 = McpServerFeatures.SyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { // perform a blocking call to a remote service try { @@ -985,11 +980,7 @@ void testToolListChangeHandlingSuccess(String clientType) { // Add a new tool McpServerFeatures.SyncToolSpecification tool2 = McpServerFeatures.SyncToolSpecification.builder() - .tool(Tool.builder() - .name("tool2") - .description("tool2 description") - .inputSchema(EMPTY_JSON_SCHEMA) - .build()) + .tool(Tool.builder().name("tool2").description("tool2 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> callResponse) .build(); @@ -1040,7 +1031,7 @@ void testLoggingNotification(String clientType) throws InterruptedException { .tool(Tool.builder() .name("logging-test") .description("Test logging notifications") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build()) .callHandler((exchange, request) -> { @@ -1157,7 +1148,7 @@ void testProgressNotification(String clientType) throws InterruptedException { .tool(McpSchema.Tool.builder() .name("progress-test") .description("Test progress notifications") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build()) .callHandler((exchange, request) -> { @@ -1315,7 +1306,7 @@ void testPingSuccess(String clientType) { .tool(Tool.builder() .name("ping-async-test") .description("Test ping async behavior") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build()) .callHandler((exchange, request) -> { diff --git a/mcp-core/src/test/java/io/modelcontextprotocol/server/AbstractMcpSyncServerTests.java b/mcp-core/src/test/java/io/modelcontextprotocol/server/AbstractMcpSyncServerTests.java index 915c658e3..4dd1788d2 100644 --- a/mcp-core/src/test/java/io/modelcontextprotocol/server/AbstractMcpSyncServerTests.java +++ b/mcp-core/src/test/java/io/modelcontextprotocol/server/AbstractMcpSyncServerTests.java @@ -5,6 +5,7 @@ package io.modelcontextprotocol.server; import java.util.List; +import java.util.Map; import io.modelcontextprotocol.spec.McpSchema; import io.modelcontextprotocol.spec.McpSchema.CallToolResult; @@ -20,7 +21,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import static io.modelcontextprotocol.util.ToolsUtils.EMPTY_JSON_SCHEMA; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -107,11 +107,7 @@ void testAddTool() { .capabilities(ServerCapabilities.builder().tools(true).build()) .build(); - Tool newTool = McpSchema.Tool.builder() - .name("new-tool") - .title("New test tool") - .inputSchema(EMPTY_JSON_SCHEMA) - .build(); + Tool newTool = McpSchema.Tool.builder().name("new-tool").title("New test tool").inputSchema(Map.of()).build(); assertThatCode(() -> mcpSyncServer.addTool(new McpServerFeatures.SyncToolSpecification(newTool, (exchange, args) -> CallToolResult.builder().content(List.of()).isError(false).build()))) .doesNotThrowAnyException(); @@ -125,11 +121,7 @@ void testAddToolCall() { .capabilities(ServerCapabilities.builder().tools(true).build()) .build(); - Tool newTool = McpSchema.Tool.builder() - .name("new-tool") - .title("New test tool") - .inputSchema(EMPTY_JSON_SCHEMA) - .build(); + Tool newTool = McpSchema.Tool.builder().name("new-tool").title("New test tool").inputSchema(Map.of()).build(); assertThatCode(() -> mcpSyncServer.addTool(McpServerFeatures.SyncToolSpecification.builder() .tool(newTool) @@ -145,7 +137,7 @@ void testAddDuplicateTool() { Tool duplicateTool = McpSchema.Tool.builder() .name(TEST_TOOL_NAME) .title("Duplicate tool") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); var mcpSyncServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0") @@ -165,7 +157,7 @@ void testAddDuplicateToolCall() { Tool duplicateTool = McpSchema.Tool.builder() .name(TEST_TOOL_NAME) .title("Duplicate tool") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); var mcpSyncServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0") @@ -187,7 +179,7 @@ void testDuplicateToolCallDuringBuilding() { Tool duplicateTool = McpSchema.Tool.builder() .name("duplicate-build-toolcall") .title("Duplicate toolcall during building") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); assertThatThrownBy(() -> prepareSyncServerBuilder().serverInfo("test-server", "1.0.0") @@ -205,7 +197,7 @@ void testDuplicateToolsInBatchListRegistration() { Tool duplicateTool = McpSchema.Tool.builder() .name("batch-list-tool") .title("Duplicate tool in batch list") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); List specs = List.of( McpServerFeatures.SyncToolSpecification.builder() @@ -232,7 +224,7 @@ void testDuplicateToolsInBatchVarargsRegistration() { Tool duplicateTool = McpSchema.Tool.builder() .name("batch-varargs-tool") .title("Duplicate tool in batch varargs") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); assertThatThrownBy(() -> prepareSyncServerBuilder().serverInfo("test-server", "1.0.0") @@ -253,11 +245,7 @@ void testDuplicateToolsInBatchVarargsRegistration() { @Test void testRemoveTool() { - Tool tool = McpSchema.Tool.builder() - .name(TEST_TOOL_NAME) - .title("Test tool") - .inputSchema(EMPTY_JSON_SCHEMA) - .build(); + Tool tool = McpSchema.Tool.builder().name(TEST_TOOL_NAME).title("Test tool").inputSchema(Map.of()).build(); var mcpSyncServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0") .capabilities(ServerCapabilities.builder().tools(true).build()) diff --git a/mcp-core/src/test/java/io/modelcontextprotocol/server/AsyncToolSpecificationBuilderTest.java b/mcp-core/src/test/java/io/modelcontextprotocol/server/AsyncToolSpecificationBuilderTest.java index 62332fcdb..55466241c 100644 --- a/mcp-core/src/test/java/io/modelcontextprotocol/server/AsyncToolSpecificationBuilderTest.java +++ b/mcp-core/src/test/java/io/modelcontextprotocol/server/AsyncToolSpecificationBuilderTest.java @@ -4,7 +4,6 @@ package io.modelcontextprotocol.server; -import static io.modelcontextprotocol.util.ToolsUtils.EMPTY_JSON_SCHEMA; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -31,11 +30,7 @@ class AsyncToolSpecificationBuilderTest { @Test void builderShouldCreateValidAsyncToolSpecification() { - Tool tool = McpSchema.Tool.builder() - .name("test-tool") - .title("A test tool") - .inputSchema(EMPTY_JSON_SCHEMA) - .build(); + Tool tool = McpSchema.Tool.builder().name("test-tool").title("A test tool").inputSchema(Map.of()).build(); McpServerFeatures.AsyncToolSpecification specification = McpServerFeatures.AsyncToolSpecification.builder() .tool(tool) @@ -59,11 +54,7 @@ void builderShouldThrowExceptionWhenToolIsNull() { @Test void builderShouldThrowExceptionWhenCallToolIsNull() { - Tool tool = McpSchema.Tool.builder() - .name("test-tool") - .title("A test tool") - .inputSchema(EMPTY_JSON_SCHEMA) - .build(); + Tool tool = McpSchema.Tool.builder().name("test-tool").title("A test tool").inputSchema(Map.of()).build(); assertThatThrownBy(() -> McpServerFeatures.AsyncToolSpecification.builder().tool(tool).build()) .isInstanceOf(IllegalArgumentException.class) @@ -72,11 +63,7 @@ void builderShouldThrowExceptionWhenCallToolIsNull() { @Test void builderShouldAllowMethodChaining() { - Tool tool = McpSchema.Tool.builder() - .name("test-tool") - .title("A test tool") - .inputSchema(EMPTY_JSON_SCHEMA) - .build(); + Tool tool = McpSchema.Tool.builder().name("test-tool").title("A test tool").inputSchema(Map.of()).build(); McpServerFeatures.AsyncToolSpecification.Builder builder = McpServerFeatures.AsyncToolSpecification.builder(); // Then - verify method chaining returns the same builder instance @@ -91,7 +78,7 @@ void builtSpecificationShouldExecuteCallToolCorrectly() { Tool tool = McpSchema.Tool.builder() .name("calculator") .title("Simple calculator") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); String expectedResult = "42"; @@ -123,7 +110,7 @@ void deprecatedConstructorShouldWorkCorrectly() { Tool tool = McpSchema.Tool.builder() .name("deprecated-tool") .title("A deprecated tool") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); String expectedResult = "deprecated result"; @@ -167,11 +154,7 @@ void deprecatedConstructorShouldWorkCorrectly() { @Test void fromSyncShouldConvertSyncToolSpecificationCorrectly() { - Tool tool = McpSchema.Tool.builder() - .name("sync-tool") - .title("A sync tool") - .inputSchema(EMPTY_JSON_SCHEMA) - .build(); + Tool tool = McpSchema.Tool.builder().name("sync-tool").title("A sync tool").inputSchema(Map.of()).build(); String expectedResult = "sync result"; // Create a sync tool specification @@ -212,7 +195,7 @@ void fromSyncShouldConvertSyncToolSpecificationWithDeprecatedCallCorrectly() { Tool tool = McpSchema.Tool.builder() .name("sync-deprecated-tool") .title("A sync tool with deprecated call") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); String expectedResult = "sync deprecated result"; McpAsyncServerExchange nullExchange = null; // Mock or create a suitable exchange diff --git a/mcp-core/src/test/java/io/modelcontextprotocol/server/HttpServletStatelessIntegrationTests.java b/mcp-core/src/test/java/io/modelcontextprotocol/server/HttpServletStatelessIntegrationTests.java index 491c2d4ed..ebae4d8d5 100644 --- a/mcp-core/src/test/java/io/modelcontextprotocol/server/HttpServletStatelessIntegrationTests.java +++ b/mcp-core/src/test/java/io/modelcontextprotocol/server/HttpServletStatelessIntegrationTests.java @@ -48,7 +48,6 @@ import static io.modelcontextprotocol.server.transport.HttpServletStatelessServerTransport.APPLICATION_JSON; import static io.modelcontextprotocol.server.transport.HttpServletStatelessServerTransport.TEXT_EVENT_STREAM; import static io.modelcontextprotocol.util.McpJsonMapperUtils.JSON_MAPPER; -import static io.modelcontextprotocol.util.ToolsUtils.EMPTY_JSON_SCHEMA; import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; import static net.javacrumbs.jsonunit.assertj.JsonAssertions.json; import static org.assertj.core.api.Assertions.assertThat; @@ -119,7 +118,7 @@ void testToolCallSuccess(String clientType) { .isError(false) .build(); McpStatelessServerFeatures.SyncToolSpecification tool1 = new McpStatelessServerFeatures.SyncToolSpecification( - Tool.builder().name("tool1").title("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build(), + Tool.builder().name("tool1").title("tool1 description").inputSchema(Map.of()).build(), (transportContext, request) -> { // perform a blocking call to a remote service String response = RestClient.create() diff --git a/mcp-core/src/test/java/io/modelcontextprotocol/server/SyncToolSpecificationBuilderTest.java b/mcp-core/src/test/java/io/modelcontextprotocol/server/SyncToolSpecificationBuilderTest.java index 9bcd2bc84..d34f212c0 100644 --- a/mcp-core/src/test/java/io/modelcontextprotocol/server/SyncToolSpecificationBuilderTest.java +++ b/mcp-core/src/test/java/io/modelcontextprotocol/server/SyncToolSpecificationBuilderTest.java @@ -4,7 +4,6 @@ package io.modelcontextprotocol.server; -import static io.modelcontextprotocol.util.ToolsUtils.EMPTY_JSON_SCHEMA; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -28,7 +27,7 @@ class SyncToolSpecificationBuilderTest { @Test void builderShouldCreateValidSyncToolSpecification() { - Tool tool = Tool.builder().name("test-tool").title("A test tool").inputSchema(EMPTY_JSON_SCHEMA).build(); + Tool tool = Tool.builder().name("test-tool").title("A test tool").inputSchema(Map.of()).build(); McpServerFeatures.SyncToolSpecification specification = McpServerFeatures.SyncToolSpecification.builder() .tool(tool) @@ -53,7 +52,7 @@ void builderShouldThrowExceptionWhenToolIsNull() { @Test void builderShouldThrowExceptionWhenCallToolIsNull() { - Tool tool = Tool.builder().name("test-tool").description("A test tool").inputSchema(EMPTY_JSON_SCHEMA).build(); + Tool tool = Tool.builder().name("test-tool").description("A test tool").inputSchema(Map.of()).build(); assertThatThrownBy(() -> McpServerFeatures.SyncToolSpecification.builder().tool(tool).build()) .isInstanceOf(IllegalArgumentException.class) @@ -62,7 +61,7 @@ void builderShouldThrowExceptionWhenCallToolIsNull() { @Test void builderShouldAllowMethodChaining() { - Tool tool = Tool.builder().name("test-tool").description("A test tool").inputSchema(EMPTY_JSON_SCHEMA).build(); + Tool tool = Tool.builder().name("test-tool").description("A test tool").inputSchema(Map.of()).build(); McpServerFeatures.SyncToolSpecification.Builder builder = McpServerFeatures.SyncToolSpecification.builder(); // Then - verify method chaining returns the same builder instance @@ -74,11 +73,7 @@ void builderShouldAllowMethodChaining() { @Test void builtSpecificationShouldExecuteCallToolCorrectly() { - Tool tool = Tool.builder() - .name("calculator") - .description("Simple calculator") - .inputSchema(EMPTY_JSON_SCHEMA) - .build(); + Tool tool = Tool.builder().name("calculator").description("Simple calculator").inputSchema(Map.of()).build(); String expectedResult = "42"; McpServerFeatures.SyncToolSpecification specification = McpServerFeatures.SyncToolSpecification.builder() diff --git a/mcp-core/src/test/java/io/modelcontextprotocol/spec/McpSchemaTests.java b/mcp-core/src/test/java/io/modelcontextprotocol/spec/McpSchemaTests.java index 6b0004cb9..5beb03b11 100644 --- a/mcp-core/src/test/java/io/modelcontextprotocol/spec/McpSchemaTests.java +++ b/mcp-core/src/test/java/io/modelcontextprotocol/spec/McpSchemaTests.java @@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.exc.InvalidTypeIdException; import io.modelcontextprotocol.spec.McpSchema.TextResourceContents; +import io.modelcontextprotocol.json.TypeRef; import net.javacrumbs.jsonunit.core.Option; /** @@ -694,13 +695,15 @@ void testJsonSchema() throws Exception { """; // Deserialize the original string to a JsonSchema object - McpSchema.JsonSchema schema = JSON_MAPPER.readValue(schemaJson, McpSchema.JsonSchema.class); + Map schema = JSON_MAPPER.readValue(schemaJson, new TypeRef>() { + }); // Serialize the object back to a string String serialized = JSON_MAPPER.writeValueAsString(schema); // Deserialize again - McpSchema.JsonSchema deserialized = JSON_MAPPER.readValue(serialized, McpSchema.JsonSchema.class); + Map deserialized = JSON_MAPPER.readValue(serialized, new TypeRef>() { + }); // Serialize one more time and compare with the first serialization String serializedAgain = JSON_MAPPER.writeValueAsString(deserialized); @@ -737,13 +740,15 @@ void testJsonSchemaWithDefinitions() throws Exception { """; // Deserialize the original string to a JsonSchema object - McpSchema.JsonSchema schema = JSON_MAPPER.readValue(schemaJson, McpSchema.JsonSchema.class); + Map schema = JSON_MAPPER.readValue(schemaJson, new TypeRef>() { + }); // Serialize the object back to a string String serialized = JSON_MAPPER.writeValueAsString(schema); // Deserialize again - McpSchema.JsonSchema deserialized = JSON_MAPPER.readValue(serialized, McpSchema.JsonSchema.class); + Map deserialized = JSON_MAPPER.readValue(serialized, new TypeRef>() { + }); // Serialize one more time and compare with the first serialization String serializedAgain = JSON_MAPPER.writeValueAsString(deserialized); @@ -826,8 +831,8 @@ void testToolWithComplexSchema() throws Exception { assertThatJson(serializedAgain).when(Option.IGNORING_ARRAY_ORDER).isEqualTo(json(serialized)); // Just verify the basic structure was preserved - assertThat(deserializedTool.inputSchema().defs()).isNotNull(); - assertThat(deserializedTool.inputSchema().defs()).containsKey("Address"); + assertThat(deserializedTool.inputSchema().containsKey("defs")); + // assertThat(deserializedTool.inputSchema().defs()).containsKey("Address"); } @Test @@ -847,14 +852,14 @@ void testToolWithMeta() throws Exception { } """; - McpSchema.JsonSchema schema = JSON_MAPPER.readValue(schemaJson, McpSchema.JsonSchema.class); + Map inputSchema = Map.of("inputSchema", schemaJson); Map meta = Map.of("metaKey", "metaValue"); McpSchema.Tool tool = McpSchema.Tool.builder() .name("addressTool") .title("addressTool") .description("Handles addresses") - .inputSchema(schema) + .inputSchema(inputSchema) .meta(meta) .build(); @@ -1095,7 +1100,7 @@ void testToolDeserialization() throws Exception { assertThat(tool.name()).isEqualTo("test-tool"); assertThat(tool.description()).isEqualTo("A test tool"); assertThat(tool.inputSchema()).isNotNull(); - assertThat(tool.inputSchema().type()).isEqualTo("object"); + assertThat(tool.inputSchema().get("type")).isEqualTo("object"); assertThat(tool.outputSchema()).isNotNull(); assertThat(tool.outputSchema()).containsKey("type"); assertThat(tool.outputSchema().get("type")).isEqualTo("object"); diff --git a/mcp-core/src/test/java/io/modelcontextprotocol/util/ToolsUtils.java b/mcp-core/src/test/java/io/modelcontextprotocol/util/ToolsUtils.java index ce8755223..e6085a5ce 100644 --- a/mcp-core/src/test/java/io/modelcontextprotocol/util/ToolsUtils.java +++ b/mcp-core/src/test/java/io/modelcontextprotocol/util/ToolsUtils.java @@ -9,7 +9,4 @@ public final class ToolsUtils { private ToolsUtils() { } - public static final McpSchema.JsonSchema EMPTY_JSON_SCHEMA = new McpSchema.JsonSchema("object", - Collections.emptyMap(), null, null, null, null); - } diff --git a/mcp-test/src/main/java/io/modelcontextprotocol/AbstractMcpClientServerIntegrationTests.java b/mcp-test/src/main/java/io/modelcontextprotocol/AbstractMcpClientServerIntegrationTests.java index 270bc4308..c1eae18bc 100644 --- a/mcp-test/src/main/java/io/modelcontextprotocol/AbstractMcpClientServerIntegrationTests.java +++ b/mcp-test/src/main/java/io/modelcontextprotocol/AbstractMcpClientServerIntegrationTests.java @@ -55,7 +55,6 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; -import static io.modelcontextprotocol.util.ToolsUtils.EMPTY_JSON_SCHEMA; import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; import static net.javacrumbs.jsonunit.assertj.JsonAssertions.json; import static org.assertj.core.api.Assertions.assertThat; @@ -107,7 +106,7 @@ void testCreateMessageWithoutSamplingCapabilities(String clientType) { var clientBuilder = clientBuilders.get(clientType); McpServerFeatures.AsyncToolSpecification tool = McpServerFeatures.AsyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { return exchange.createMessage(mock(McpSchema.CreateMessageRequest.class)) .then(Mono.just(mock(CallToolResult.class))); @@ -157,7 +156,7 @@ void testCreateMessageSuccess(String clientType) { AtomicReference samplingResult = new AtomicReference<>(); McpServerFeatures.AsyncToolSpecification tool = McpServerFeatures.AsyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { var createMessageRequest = McpSchema.CreateMessageRequest.builder() @@ -236,7 +235,7 @@ void testCreateMessageWithRequestTimeoutSuccess(String clientType) throws Interr AtomicReference samplingResult = new AtomicReference<>(); McpServerFeatures.AsyncToolSpecification tool = McpServerFeatures.AsyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { var createMessageRequest = McpSchema.CreateMessageRequest.builder() @@ -311,7 +310,7 @@ void testCreateMessageWithRequestTimeoutFail(String clientType) throws Interrupt .build(); McpServerFeatures.AsyncToolSpecification tool = McpServerFeatures.AsyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { var createMessageRequest = McpSchema.CreateMessageRequest.builder() @@ -361,7 +360,7 @@ void testCreateElicitationWithoutElicitationCapabilities(String clientType) { var clientBuilder = clientBuilders.get(clientType); McpServerFeatures.AsyncToolSpecification tool = McpServerFeatures.AsyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> exchange.createElicitation(mock(ElicitRequest.class)) .then(Mono.just(mock(CallToolResult.class)))) .build(); @@ -405,7 +404,7 @@ void testCreateElicitationSuccess(String clientType) { .build(); McpServerFeatures.AsyncToolSpecification tool = McpServerFeatures.AsyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { var elicitationRequest = McpSchema.ElicitRequest.builder() @@ -463,7 +462,7 @@ void testCreateElicitationWithRequestTimeoutSuccess(String clientType) { AtomicReference resultRef = new AtomicReference<>(); McpServerFeatures.AsyncToolSpecification tool = McpServerFeatures.AsyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { var elicitationRequest = McpSchema.ElicitRequest.builder() @@ -534,7 +533,7 @@ void testCreateElicitationWithRequestTimeoutFail(String clientType) { AtomicReference resultRef = new AtomicReference<>(); McpServerFeatures.AsyncToolSpecification tool = McpServerFeatures.AsyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { var elicitationRequest = ElicitRequest.builder() @@ -632,7 +631,7 @@ void testRootsWithoutCapability(String clientType) { var clientBuilder = clientBuilders.get(clientType); McpServerFeatures.SyncToolSpecification tool = McpServerFeatures.SyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { exchange.listRoots(); // try to list roots @@ -774,7 +773,7 @@ void testToolCallSuccess(String clientType) { .addContent(new McpSchema.TextContent("CALL RESPONSE; ctx=importantValue")) .build(); McpServerFeatures.SyncToolSpecification tool1 = McpServerFeatures.SyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { try { @@ -825,11 +824,7 @@ void testThrowingToolCallIsCaughtBeforeTimeout(String clientType) { McpSyncServer mcpServer = prepareSyncServerBuilder() .capabilities(ServerCapabilities.builder().tools(true).build()) .tools(McpServerFeatures.SyncToolSpecification.builder() - .tool(Tool.builder() - .name("tool1") - .description("tool1 description") - .inputSchema(EMPTY_JSON_SCHEMA) - .build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { // We trigger a timeout on blocking read, raising an exception Mono.never().block(Duration.ofSeconds(1)); @@ -867,7 +862,7 @@ void testToolCallSuccessWithTranportContextExtraction(String clientType) { .addContent(new McpSchema.TextContent("CALL RESPONSE; ctx=value")) .build(); McpServerFeatures.SyncToolSpecification tool1 = McpServerFeatures.SyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { McpTransportContext transportContext = exchange.transportContext(); @@ -923,7 +918,7 @@ void testToolListChangeHandlingSuccess(String clientType) { .build(); McpServerFeatures.SyncToolSpecification tool1 = McpServerFeatures.SyncToolSpecification.builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> { // perform a blocking call to a remote service try { @@ -989,11 +984,7 @@ void testToolListChangeHandlingSuccess(String clientType) { // Add a new tool McpServerFeatures.SyncToolSpecification tool2 = McpServerFeatures.SyncToolSpecification.builder() - .tool(Tool.builder() - .name("tool2") - .description("tool2 description") - .inputSchema(EMPTY_JSON_SCHEMA) - .build()) + .tool(Tool.builder().name("tool2").description("tool2 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> callResponse) .build(); @@ -1044,7 +1035,7 @@ void testLoggingNotification(String clientType) throws InterruptedException { .tool(Tool.builder() .name("logging-test") .description("Test logging notifications") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build()) .callHandler((exchange, request) -> { @@ -1161,7 +1152,7 @@ void testProgressNotification(String clientType) throws InterruptedException { .tool(McpSchema.Tool.builder() .name("progress-test") .description("Test progress notifications") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build()) .callHandler((exchange, request) -> { @@ -1319,7 +1310,7 @@ void testPingSuccess(String clientType) { .tool(Tool.builder() .name("ping-async-test") .description("Test ping async behavior") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build()) .callHandler((exchange, request) -> { diff --git a/mcp-test/src/main/java/io/modelcontextprotocol/AbstractStatelessIntegrationTests.java b/mcp-test/src/main/java/io/modelcontextprotocol/AbstractStatelessIntegrationTests.java index 240732ebe..f7bbffa3b 100644 --- a/mcp-test/src/main/java/io/modelcontextprotocol/AbstractStatelessIntegrationTests.java +++ b/mcp-test/src/main/java/io/modelcontextprotocol/AbstractStatelessIntegrationTests.java @@ -32,7 +32,6 @@ import org.junit.jupiter.params.provider.ValueSource; import reactor.core.publisher.Mono; -import static io.modelcontextprotocol.util.ToolsUtils.EMPTY_JSON_SCHEMA; import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; import static net.javacrumbs.jsonunit.assertj.JsonAssertions.json; import static org.assertj.core.api.Assertions.assertThat; @@ -85,7 +84,7 @@ void testToolCallSuccess(String clientType) { var callResponse = new McpSchema.CallToolResult(List.of(new McpSchema.TextContent("CALL RESPONSE")), null); McpStatelessServerFeatures.SyncToolSpecification tool1 = McpStatelessServerFeatures.SyncToolSpecification .builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((ctx, request) -> { try { @@ -135,11 +134,7 @@ void testThrowingToolCallIsCaughtBeforeTimeout(String clientType) { McpStatelessSyncServer mcpServer = prepareSyncServerBuilder() .capabilities(ServerCapabilities.builder().tools(true).build()) .tools(McpStatelessServerFeatures.SyncToolSpecification.builder() - .tool(Tool.builder() - .name("tool1") - .description("tool1 description") - .inputSchema(EMPTY_JSON_SCHEMA) - .build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((context, request) -> { // We trigger a timeout on blocking read, raising an exception Mono.never().block(Duration.ofSeconds(1)); @@ -173,7 +168,7 @@ void testToolListChangeHandlingSuccess(String clientType) { var callResponse = new McpSchema.CallToolResult(List.of(new McpSchema.TextContent("CALL RESPONSE")), null); McpStatelessServerFeatures.SyncToolSpecification tool1 = McpStatelessServerFeatures.SyncToolSpecification .builder() - .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build()) + .tool(Tool.builder().name("tool1").description("tool1 description").inputSchema(Map.of()).build()) .callHandler((ctx, request) -> { // perform a blocking call to a remote service try { @@ -231,11 +226,7 @@ void testToolListChangeHandlingSuccess(String clientType) { // Add a new tool McpStatelessServerFeatures.SyncToolSpecification tool2 = McpStatelessServerFeatures.SyncToolSpecification .builder() - .tool(Tool.builder() - .name("tool2") - .description("tool2 description") - .inputSchema(EMPTY_JSON_SCHEMA) - .build()) + .tool(Tool.builder().name("tool2").description("tool2 description").inputSchema(Map.of()).build()) .callHandler((exchange, request) -> callResponse) .build(); diff --git a/mcp-test/src/main/java/io/modelcontextprotocol/server/AbstractMcpAsyncServerTests.java b/mcp-test/src/main/java/io/modelcontextprotocol/server/AbstractMcpAsyncServerTests.java index d6677ec9a..5e01a62f9 100644 --- a/mcp-test/src/main/java/io/modelcontextprotocol/server/AbstractMcpAsyncServerTests.java +++ b/mcp-test/src/main/java/io/modelcontextprotocol/server/AbstractMcpAsyncServerTests.java @@ -6,6 +6,7 @@ import java.time.Duration; import java.util.List; +import java.util.Map; import io.modelcontextprotocol.spec.McpSchema; import io.modelcontextprotocol.spec.McpSchema.CallToolResult; @@ -25,7 +26,6 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; -import static io.modelcontextprotocol.util.ToolsUtils.EMPTY_JSON_SCHEMA; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -98,11 +98,7 @@ void testImmediateClose() { @Test @Deprecated void testAddTool() { - Tool newTool = McpSchema.Tool.builder() - .name("new-tool") - .title("New test tool") - .inputSchema(EMPTY_JSON_SCHEMA) - .build(); + Tool newTool = McpSchema.Tool.builder().name("new-tool").title("New test tool").inputSchema(Map.of()).build(); var mcpAsyncServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0") .capabilities(ServerCapabilities.builder().tools(true).build()) .build(); @@ -117,11 +113,7 @@ void testAddTool() { @Test void testAddToolCall() { - Tool newTool = McpSchema.Tool.builder() - .name("new-tool") - .title("New test tool") - .inputSchema(EMPTY_JSON_SCHEMA) - .build(); + Tool newTool = McpSchema.Tool.builder().name("new-tool").title("New test tool").inputSchema(Map.of()).build(); var mcpAsyncServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0") .capabilities(ServerCapabilities.builder().tools(true).build()) @@ -142,7 +134,7 @@ void testAddDuplicateTool() { Tool duplicateTool = McpSchema.Tool.builder() .name(TEST_TOOL_NAME) .title("Duplicate tool") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); var mcpAsyncServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0") @@ -164,7 +156,7 @@ void testAddDuplicateToolCall() { Tool duplicateTool = McpSchema.Tool.builder() .name(TEST_TOOL_NAME) .title("Duplicate tool") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); var mcpAsyncServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0") @@ -188,7 +180,7 @@ void testDuplicateToolCallDuringBuilding() { Tool duplicateTool = McpSchema.Tool.builder() .name("duplicate-build-toolcall") .title("Duplicate toolcall during building") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); assertThatThrownBy(() -> prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0") @@ -208,7 +200,7 @@ void testDuplicateToolsInBatchListRegistration() { Tool duplicateTool = McpSchema.Tool.builder() .name("batch-list-tool") .title("Duplicate tool in batch list") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); List specs = List.of( @@ -236,7 +228,7 @@ void testDuplicateToolsInBatchVarargsRegistration() { Tool duplicateTool = McpSchema.Tool.builder() .name("batch-varargs-tool") .title("Duplicate tool in batch varargs") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); assertThatThrownBy(() -> prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0") @@ -258,11 +250,7 @@ void testDuplicateToolsInBatchVarargsRegistration() { @Test void testRemoveTool() { - Tool too = McpSchema.Tool.builder() - .name(TEST_TOOL_NAME) - .title("Duplicate tool") - .inputSchema(EMPTY_JSON_SCHEMA) - .build(); + Tool too = McpSchema.Tool.builder().name(TEST_TOOL_NAME).title("Duplicate tool").inputSchema(Map.of()).build(); var mcpAsyncServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0") .capabilities(ServerCapabilities.builder().tools(true).build()) @@ -289,11 +277,7 @@ void testRemoveNonexistentTool() { @Test void testNotifyToolsListChanged() { - Tool too = McpSchema.Tool.builder() - .name(TEST_TOOL_NAME) - .title("Duplicate tool") - .inputSchema(EMPTY_JSON_SCHEMA) - .build(); + Tool too = McpSchema.Tool.builder().name(TEST_TOOL_NAME).title("Duplicate tool").inputSchema(Map.of()).build(); var mcpAsyncServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0") .capabilities(ServerCapabilities.builder().tools(true).build()) diff --git a/mcp-test/src/main/java/io/modelcontextprotocol/server/AbstractMcpSyncServerTests.java b/mcp-test/src/main/java/io/modelcontextprotocol/server/AbstractMcpSyncServerTests.java index 0a59d0aae..e4b9afd81 100644 --- a/mcp-test/src/main/java/io/modelcontextprotocol/server/AbstractMcpSyncServerTests.java +++ b/mcp-test/src/main/java/io/modelcontextprotocol/server/AbstractMcpSyncServerTests.java @@ -5,6 +5,7 @@ package io.modelcontextprotocol.server; import java.util.List; +import java.util.Map; import io.modelcontextprotocol.spec.McpSchema; import io.modelcontextprotocol.spec.McpSchema.CallToolResult; @@ -20,7 +21,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import static io.modelcontextprotocol.util.ToolsUtils.EMPTY_JSON_SCHEMA; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -106,11 +106,7 @@ void testAddTool() { .capabilities(ServerCapabilities.builder().tools(true).build()) .build(); - Tool newTool = McpSchema.Tool.builder() - .name("new-tool") - .title("New test tool") - .inputSchema(EMPTY_JSON_SCHEMA) - .build(); + Tool newTool = McpSchema.Tool.builder().name("new-tool").title("New test tool").inputSchema(Map.of()).build(); assertThatCode(() -> mcpSyncServer.addTool(new McpServerFeatures.SyncToolSpecification(newTool, (exchange, args) -> CallToolResult.builder().content(List.of()).isError(false).build()))) .doesNotThrowAnyException(); @@ -124,11 +120,7 @@ void testAddToolCall() { .capabilities(ServerCapabilities.builder().tools(true).build()) .build(); - Tool newTool = McpSchema.Tool.builder() - .name("new-tool") - .title("New test tool") - .inputSchema(EMPTY_JSON_SCHEMA) - .build(); + Tool newTool = McpSchema.Tool.builder().name("new-tool").title("New test tool").inputSchema(Map.of()).build(); assertThatCode(() -> mcpSyncServer.addTool(McpServerFeatures.SyncToolSpecification.builder() .tool(newTool) @@ -144,7 +136,7 @@ void testAddDuplicateTool() { Tool duplicateTool = McpSchema.Tool.builder() .name(TEST_TOOL_NAME) .title("Duplicate tool") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); var mcpSyncServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0") @@ -164,7 +156,7 @@ void testAddDuplicateToolCall() { Tool duplicateTool = McpSchema.Tool.builder() .name(TEST_TOOL_NAME) .title("Duplicate tool") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); var mcpSyncServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0") @@ -186,7 +178,7 @@ void testDuplicateToolCallDuringBuilding() { Tool duplicateTool = McpSchema.Tool.builder() .name("duplicate-build-toolcall") .title("Duplicate toolcall during building") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); assertThatThrownBy(() -> prepareSyncServerBuilder().serverInfo("test-server", "1.0.0") @@ -204,7 +196,7 @@ void testDuplicateToolsInBatchListRegistration() { Tool duplicateTool = McpSchema.Tool.builder() .name("batch-list-tool") .title("Duplicate tool in batch list") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); List specs = List.of( McpServerFeatures.SyncToolSpecification.builder() @@ -231,7 +223,7 @@ void testDuplicateToolsInBatchVarargsRegistration() { Tool duplicateTool = McpSchema.Tool.builder() .name("batch-varargs-tool") .title("Duplicate tool in batch varargs") - .inputSchema(EMPTY_JSON_SCHEMA) + .inputSchema(Map.of()) .build(); assertThatThrownBy(() -> prepareSyncServerBuilder().serverInfo("test-server", "1.0.0") @@ -252,11 +244,7 @@ void testDuplicateToolsInBatchVarargsRegistration() { @Test void testRemoveTool() { - Tool tool = McpSchema.Tool.builder() - .name(TEST_TOOL_NAME) - .title("Test tool") - .inputSchema(EMPTY_JSON_SCHEMA) - .build(); + Tool tool = McpSchema.Tool.builder().name(TEST_TOOL_NAME).title("Test tool").inputSchema(Map.of()).build(); var mcpSyncServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0") .capabilities(ServerCapabilities.builder().tools(true).build()) diff --git a/mcp-test/src/main/java/io/modelcontextprotocol/util/ToolsUtils.java b/mcp-test/src/main/java/io/modelcontextprotocol/util/ToolsUtils.java index ce8755223..e6085a5ce 100644 --- a/mcp-test/src/main/java/io/modelcontextprotocol/util/ToolsUtils.java +++ b/mcp-test/src/main/java/io/modelcontextprotocol/util/ToolsUtils.java @@ -9,7 +9,4 @@ public final class ToolsUtils { private ToolsUtils() { } - public static final McpSchema.JsonSchema EMPTY_JSON_SCHEMA = new McpSchema.JsonSchema("object", - Collections.emptyMap(), null, null, null, null); - }