diff --git a/mcp/src/main/java/io/modelcontextprotocol/client/McpClient.java b/mcp/src/main/java/io/modelcontextprotocol/client/McpClient.java index d8925b005..a6ac883ea 100644 --- a/mcp/src/main/java/io/modelcontextprotocol/client/McpClient.java +++ b/mcp/src/main/java/io/modelcontextprotocol/client/McpClient.java @@ -66,7 +66,7 @@ * McpClient.async(transport) * .requestTimeout(Duration.ofSeconds(10)) * .capabilities(new ClientCapabilities(...)) - * .clientInfo(new Implementation("My Client", "1.0.0")) + * .clientInfo(new Implementation("My Client", "Title", "1.0.0")) * .roots(new Root("file://workspace", "Workspace Files")) * .toolsChangeConsumer(tools -> Mono.fromRunnable(() -> System.out.println("Tools updated: " + tools))) * .resourcesChangeConsumer(resources -> Mono.fromRunnable(() -> System.out.println("Resources updated: " + resources))) @@ -163,7 +163,7 @@ class SyncSpec { private ClientCapabilities capabilities; - private Implementation clientInfo = new Implementation("Java SDK MCP Client", "1.0.0"); + private Implementation clientInfo = new Implementation("Java SDK MCP Client", null, "1.0.0"); private final Map roots = new HashMap<>(); @@ -421,7 +421,7 @@ class AsyncSpec { private ClientCapabilities capabilities; - private Implementation clientInfo = new Implementation("Spring AI MCP Client", "0.3.1"); + private Implementation clientInfo = new Implementation("Spring AI MCP Client", null, "0.3.1"); private final Map roots = new HashMap<>(); diff --git a/mcp/src/main/java/io/modelcontextprotocol/server/McpServer.java b/mcp/src/main/java/io/modelcontextprotocol/server/McpServer.java index d6ec2cc30..9cc1fc891 100644 --- a/mcp/src/main/java/io/modelcontextprotocol/server/McpServer.java +++ b/mcp/src/main/java/io/modelcontextprotocol/server/McpServer.java @@ -154,7 +154,7 @@ static AsyncSpecification async(McpServerTransportProvider transportProvider) { class AsyncSpecification { private static final McpSchema.Implementation DEFAULT_SERVER_INFO = new McpSchema.Implementation("mcp-server", - "1.0.0"); + null, "1.0.0"); private final McpServerTransportProvider transportProvider; @@ -256,15 +256,16 @@ public AsyncSpecification serverInfo(McpSchema.Implementation serverInfo) { * is a convenience method alternative to * {@link #serverInfo(McpSchema.Implementation)}. * @param name The server name. Must not be null or empty. + * @param title The server title. May be null or empty. * @param version The server version. Must not be null or empty. * @return This builder instance for method chaining * @throws IllegalArgumentException if name or version is null or empty * @see #serverInfo(McpSchema.Implementation) */ - public AsyncSpecification serverInfo(String name, String version) { + public AsyncSpecification serverInfo(String name, String title, String version) { Assert.hasText(name, "Name must not be null or empty"); Assert.hasText(version, "Version must not be null or empty"); - this.serverInfo = new McpSchema.Implementation(name, version); + this.serverInfo = new McpSchema.Implementation(name, title, version); return this; } @@ -646,7 +647,7 @@ public McpAsyncServer build() { class SyncSpecification { private static final McpSchema.Implementation DEFAULT_SERVER_INFO = new McpSchema.Implementation("mcp-server", - "1.0.0"); + null, "1.0.0"); private McpUriTemplateManagerFactory uriTemplateManagerFactory = new DeafaultMcpUriTemplateManagerFactory(); @@ -748,15 +749,16 @@ public SyncSpecification serverInfo(McpSchema.Implementation serverInfo) { * is a convenience method alternative to * {@link #serverInfo(McpSchema.Implementation)}. * @param name The server name. Must not be null or empty. + * @param title The server title. May be null or empty. * @param version The server version. Must not be null or empty. * @return This builder instance for method chaining * @throws IllegalArgumentException if name or version is null or empty * @see #serverInfo(McpSchema.Implementation) */ - public SyncSpecification serverInfo(String name, String version) { + public SyncSpecification serverInfo(String name, String title, String version) { Assert.hasText(name, "Name must not be null or empty"); Assert.hasText(version, "Version must not be null or empty"); - this.serverInfo = new McpSchema.Implementation(name, version); + this.serverInfo = new McpSchema.Implementation(name, title, version); return this; } diff --git a/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java b/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java index 597130946..67f74a150 100644 --- a/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java +++ b/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java @@ -437,6 +437,7 @@ public ServerCapabilities build() { @JsonIgnoreProperties(ignoreUnknown = true) public record Implementation(// @formatter:off @JsonProperty("name") String name, + @JsonProperty("title") String title, @JsonProperty("version") String version) { } // @formatter:on diff --git a/mcp/src/test/java/io/modelcontextprotocol/client/McpAsyncClientResponseHandlerTests.java b/mcp/src/test/java/io/modelcontextprotocol/client/McpAsyncClientResponseHandlerTests.java index a79bdf6c9..594fe4cb6 100644 --- a/mcp/src/test/java/io/modelcontextprotocol/client/McpAsyncClientResponseHandlerTests.java +++ b/mcp/src/test/java/io/modelcontextprotocol/client/McpAsyncClientResponseHandlerTests.java @@ -30,7 +30,8 @@ class McpAsyncClientResponseHandlerTests { - private static final McpSchema.Implementation SERVER_INFO = new McpSchema.Implementation("test-server", "1.0.0"); + private static final McpSchema.Implementation SERVER_INFO = new McpSchema.Implementation("test-server", null, + "1.0.0"); private static final McpSchema.ServerCapabilities SERVER_CAPABILITIES = McpSchema.ServerCapabilities.builder() .tools(true) @@ -57,7 +58,7 @@ private static MockMcpClientTransport initializationEnabledTransport( @Test void testSuccessfulInitialization() { - McpSchema.Implementation serverInfo = new McpSchema.Implementation("mcp-test-server", "0.0.1"); + McpSchema.Implementation serverInfo = new McpSchema.Implementation("mcp-test-server", null, "0.0.1"); McpSchema.ServerCapabilities serverCapabilities = McpSchema.ServerCapabilities.builder() .tools(false) .resources(true, true) // Enable both resources and resource templates diff --git a/mcp/src/test/java/io/modelcontextprotocol/client/McpAsyncClientTests.java b/mcp/src/test/java/io/modelcontextprotocol/client/McpAsyncClientTests.java index 14ca82791..6de9ff779 100644 --- a/mcp/src/test/java/io/modelcontextprotocol/client/McpAsyncClientTests.java +++ b/mcp/src/test/java/io/modelcontextprotocol/client/McpAsyncClientTests.java @@ -14,7 +14,7 @@ class McpAsyncClientTests { - public static final McpSchema.Implementation MOCK_SERVER_INFO = new McpSchema.Implementation("test-server", + public static final McpSchema.Implementation MOCK_SERVER_INFO = new McpSchema.Implementation("test-server", null, "1.0.0"); public static final McpSchema.ServerCapabilities MOCK_SERVER_CAPABILITIES = McpSchema.ServerCapabilities.builder() diff --git a/mcp/src/test/java/io/modelcontextprotocol/client/McpClientProtocolVersionTests.java b/mcp/src/test/java/io/modelcontextprotocol/client/McpClientProtocolVersionTests.java index bf4738496..b5d0a3327 100644 --- a/mcp/src/test/java/io/modelcontextprotocol/client/McpClientProtocolVersionTests.java +++ b/mcp/src/test/java/io/modelcontextprotocol/client/McpClientProtocolVersionTests.java @@ -24,7 +24,8 @@ class McpClientProtocolVersionTests { private static final Duration REQUEST_TIMEOUT = Duration.ofSeconds(30); - private static final McpSchema.Implementation CLIENT_INFO = new McpSchema.Implementation("test-client", "1.0.0"); + private static final McpSchema.Implementation CLIENT_INFO = new McpSchema.Implementation("test-client", null, + "1.0.0"); @Test void shouldUseLatestVersionByDefault() { @@ -45,7 +46,7 @@ void shouldUseLatestVersionByDefault() { transport.simulateIncomingMessage(new McpSchema.JSONRPCResponse(McpSchema.JSONRPC_VERSION, request.id(), new McpSchema.InitializeResult(McpSchema.LATEST_PROTOCOL_VERSION, null, - new McpSchema.Implementation("test-server", "1.0.0"), null), + new McpSchema.Implementation("test-server", null, "1.0.0"), null), null)); }).assertNext(result -> { assertThat(result.protocolVersion()).isEqualTo(McpSchema.LATEST_PROTOCOL_VERSION); @@ -78,10 +79,12 @@ void shouldNegotiateSpecificVersion() { McpSchema.InitializeRequest initRequest = (McpSchema.InitializeRequest) request.params(); assertThat(initRequest.protocolVersion()).isIn(List.of(oldVersion, McpSchema.LATEST_PROTOCOL_VERSION)); - transport.simulateIncomingMessage(new McpSchema.JSONRPCResponse(McpSchema.JSONRPC_VERSION, request.id(), - new McpSchema.InitializeResult(oldVersion, null, - new McpSchema.Implementation("test-server", "1.0.0"), null), - null)); + transport + .simulateIncomingMessage( + new McpSchema.JSONRPCResponse( + McpSchema.JSONRPC_VERSION, request.id(), new McpSchema.InitializeResult(oldVersion, + null, new McpSchema.Implementation("test-server", null, "1.0.0"), null), + null)); }).assertNext(result -> { assertThat(result.protocolVersion()).isEqualTo(oldVersion); }).verifyComplete(); @@ -109,7 +112,7 @@ void shouldFailForUnsupportedVersion() { transport.simulateIncomingMessage(new McpSchema.JSONRPCResponse(McpSchema.JSONRPC_VERSION, request.id(), new McpSchema.InitializeResult(unsupportedVersion, null, - new McpSchema.Implementation("test-server", "1.0.0"), null), + new McpSchema.Implementation("test-server", null, "1.0.0"), null), null)); }).expectError(McpError.class).verify(); } @@ -142,7 +145,7 @@ void shouldUseHighestVersionWhenMultipleSupported() { transport.simulateIncomingMessage(new McpSchema.JSONRPCResponse(McpSchema.JSONRPC_VERSION, request.id(), new McpSchema.InitializeResult(latestVersion, null, - new McpSchema.Implementation("test-server", "1.0.0"), null), + new McpSchema.Implementation("test-server", null, "1.0.0"), null), null)); }).assertNext(result -> { assertThat(result.protocolVersion()).isEqualTo(latestVersion); diff --git a/mcp/src/test/java/io/modelcontextprotocol/server/AbstractMcpAsyncServerTests.java b/mcp/src/test/java/io/modelcontextprotocol/server/AbstractMcpAsyncServerTests.java index dd9f65895..53c58bedb 100644 --- a/mcp/src/test/java/io/modelcontextprotocol/server/AbstractMcpAsyncServerTests.java +++ b/mcp/src/test/java/io/modelcontextprotocol/server/AbstractMcpAsyncServerTests.java @@ -77,14 +77,18 @@ void testConstructorWithInvalidArguments() { @Test void testGracefulShutdown() { - var mcpAsyncServer = McpServer.async(createMcpTransportProvider()).serverInfo("test-server", "1.0.0").build(); + var mcpAsyncServer = McpServer.async(createMcpTransportProvider()) + .serverInfo("test-server", null, "1.0.0") + .build(); StepVerifier.create(mcpAsyncServer.closeGracefully()).verifyComplete(); } @Test void testImmediateClose() { - var mcpAsyncServer = McpServer.async(createMcpTransportProvider()).serverInfo("test-server", "1.0.0").build(); + var mcpAsyncServer = McpServer.async(createMcpTransportProvider()) + .serverInfo("test-server", null, "1.0.0") + .build(); assertThatCode(() -> mcpAsyncServer.close()).doesNotThrowAnyException(); } @@ -104,7 +108,7 @@ void testImmediateClose() { void testAddTool() { Tool newTool = new McpSchema.Tool("new-tool", "New test tool", emptyJsonSchema); var mcpAsyncServer = McpServer.async(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .capabilities(ServerCapabilities.builder().tools(true).build()) .build(); @@ -120,7 +124,7 @@ void testAddDuplicateTool() { Tool duplicateTool = new McpSchema.Tool(TEST_TOOL_NAME, "Duplicate tool", emptyJsonSchema); var mcpAsyncServer = McpServer.async(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .capabilities(ServerCapabilities.builder().tools(true).build()) .tool(duplicateTool, (exchange, args) -> Mono.just(new CallToolResult(List.of(), false))) .build(); @@ -141,7 +145,7 @@ void testRemoveTool() { Tool too = new McpSchema.Tool(TEST_TOOL_NAME, "Duplicate tool", emptyJsonSchema); var mcpAsyncServer = McpServer.async(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .capabilities(ServerCapabilities.builder().tools(true).build()) .tool(too, (exchange, args) -> Mono.just(new CallToolResult(List.of(), false))) .build(); @@ -154,7 +158,7 @@ void testRemoveTool() { @Test void testRemoveNonexistentTool() { var mcpAsyncServer = McpServer.async(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .capabilities(ServerCapabilities.builder().tools(true).build()) .build(); @@ -170,7 +174,7 @@ void testNotifyToolsListChanged() { Tool too = new McpSchema.Tool(TEST_TOOL_NAME, "Duplicate tool", emptyJsonSchema); var mcpAsyncServer = McpServer.async(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .capabilities(ServerCapabilities.builder().tools(true).build()) .tool(too, (exchange, args) -> Mono.just(new CallToolResult(List.of(), false))) .build(); @@ -186,7 +190,9 @@ void testNotifyToolsListChanged() { @Test void testNotifyResourcesListChanged() { - var mcpAsyncServer = McpServer.async(createMcpTransportProvider()).serverInfo("test-server", "1.0.0").build(); + var mcpAsyncServer = McpServer.async(createMcpTransportProvider()) + .serverInfo("test-server", null, "1.0.0") + .build(); StepVerifier.create(mcpAsyncServer.notifyResourcesListChanged()).verifyComplete(); @@ -195,7 +201,9 @@ void testNotifyResourcesListChanged() { @Test void testNotifyResourcesUpdated() { - var mcpAsyncServer = McpServer.async(createMcpTransportProvider()).serverInfo("test-server", "1.0.0").build(); + var mcpAsyncServer = McpServer.async(createMcpTransportProvider()) + .serverInfo("test-server", null, "1.0.0") + .build(); StepVerifier .create(mcpAsyncServer @@ -208,7 +216,7 @@ void testNotifyResourcesUpdated() { @Test void testAddResource() { var mcpAsyncServer = McpServer.async(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .capabilities(ServerCapabilities.builder().resources(true, false).build()) .build(); @@ -225,7 +233,7 @@ void testAddResource() { @Test void testAddResourceWithNullSpecification() { var mcpAsyncServer = McpServer.async(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .capabilities(ServerCapabilities.builder().resources(true, false).build()) .build(); @@ -241,7 +249,7 @@ void testAddResourceWithNullSpecification() { void testAddResourceWithoutCapability() { // Create a server without resource capabilities McpAsyncServer serverWithoutResources = McpServer.async(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .build(); Resource resource = new Resource(TEST_RESOURCE_URI, "Test Resource", "text/plain", "Test resource description", @@ -259,7 +267,7 @@ void testAddResourceWithoutCapability() { void testRemoveResourceWithoutCapability() { // Create a server without resource capabilities McpAsyncServer serverWithoutResources = McpServer.async(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .build(); StepVerifier.create(serverWithoutResources.removeResource(TEST_RESOURCE_URI)).verifyErrorSatisfies(error -> { @@ -274,7 +282,9 @@ void testRemoveResourceWithoutCapability() { @Test void testNotifyPromptsListChanged() { - var mcpAsyncServer = McpServer.async(createMcpTransportProvider()).serverInfo("test-server", "1.0.0").build(); + var mcpAsyncServer = McpServer.async(createMcpTransportProvider()) + .serverInfo("test-server", null, "1.0.0") + .build(); StepVerifier.create(mcpAsyncServer.notifyPromptsListChanged()).verifyComplete(); @@ -284,7 +294,7 @@ void testNotifyPromptsListChanged() { @Test void testAddPromptWithNullSpecification() { var mcpAsyncServer = McpServer.async(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .capabilities(ServerCapabilities.builder().prompts(false).build()) .build(); @@ -298,7 +308,7 @@ void testAddPromptWithNullSpecification() { void testAddPromptWithoutCapability() { // Create a server without prompt capabilities McpAsyncServer serverWithoutPrompts = McpServer.async(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .build(); Prompt prompt = new Prompt(TEST_PROMPT_NAME, "Test Prompt", List.of()); @@ -316,7 +326,7 @@ void testAddPromptWithoutCapability() { void testRemovePromptWithoutCapability() { // Create a server without prompt capabilities McpAsyncServer serverWithoutPrompts = McpServer.async(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .build(); StepVerifier.create(serverWithoutPrompts.removePrompt(TEST_PROMPT_NAME)).verifyErrorSatisfies(error -> { @@ -335,7 +345,7 @@ void testRemovePrompt() { .of(new PromptMessage(McpSchema.Role.ASSISTANT, new McpSchema.TextContent("Test content")))))); var mcpAsyncServer = McpServer.async(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .capabilities(ServerCapabilities.builder().prompts(true).build()) .prompts(specification) .build(); @@ -348,7 +358,7 @@ void testRemovePrompt() { @Test void testRemoveNonexistentPrompt() { var mcpAsyncServer2 = McpServer.async(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .capabilities(ServerCapabilities.builder().prompts(true).build()) .build(); @@ -372,7 +382,7 @@ void testRootsChangeHandlers() { var consumerCalled = new boolean[1]; var singleConsumerServer = McpServer.async(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .rootsChangeHandlers(List.of((exchange, roots) -> Mono.fromRunnable(() -> { consumerCalled[0] = true; if (!roots.isEmpty()) { @@ -392,7 +402,7 @@ void testRootsChangeHandlers() { var rootsContent = new List[1]; var multipleConsumersServer = McpServer.async(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .rootsChangeHandlers(List.of((exchange, roots) -> Mono.fromRunnable(() -> { consumer1Called[0] = true; rootsContent[0] = roots; @@ -406,7 +416,7 @@ void testRootsChangeHandlers() { // Test error handling var errorHandlingServer = McpServer.async(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .rootsChangeHandlers(List.of((exchange, roots) -> { throw new RuntimeException("Test error"); })) @@ -419,7 +429,7 @@ void testRootsChangeHandlers() { // Test without consumers var noConsumersServer = McpServer.async(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .build(); assertThat(noConsumersServer).isNotNull(); diff --git a/mcp/src/test/java/io/modelcontextprotocol/server/AbstractMcpSyncServerTests.java b/mcp/src/test/java/io/modelcontextprotocol/server/AbstractMcpSyncServerTests.java index 6cbb8632c..398c8b844 100644 --- a/mcp/src/test/java/io/modelcontextprotocol/server/AbstractMcpSyncServerTests.java +++ b/mcp/src/test/java/io/modelcontextprotocol/server/AbstractMcpSyncServerTests.java @@ -74,21 +74,27 @@ void testConstructorWithInvalidArguments() { @Test void testGracefulShutdown() { - var mcpSyncServer = McpServer.sync(createMcpTransportProvider()).serverInfo("test-server", "1.0.0").build(); + var mcpSyncServer = McpServer.sync(createMcpTransportProvider()) + .serverInfo("test-server", null, "1.0.0") + .build(); assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException(); } @Test void testImmediateClose() { - var mcpSyncServer = McpServer.sync(createMcpTransportProvider()).serverInfo("test-server", "1.0.0").build(); + var mcpSyncServer = McpServer.sync(createMcpTransportProvider()) + .serverInfo("test-server", null, "1.0.0") + .build(); assertThatCode(() -> mcpSyncServer.close()).doesNotThrowAnyException(); } @Test void testGetAsyncServer() { - var mcpSyncServer = McpServer.sync(createMcpTransportProvider()).serverInfo("test-server", "1.0.0").build(); + var mcpSyncServer = McpServer.sync(createMcpTransportProvider()) + .serverInfo("test-server", null, "1.0.0") + .build(); assertThat(mcpSyncServer.getAsyncServer()).isNotNull(); @@ -110,7 +116,7 @@ void testGetAsyncServer() { @Test void testAddTool() { var mcpSyncServer = McpServer.sync(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .capabilities(ServerCapabilities.builder().tools(true).build()) .build(); @@ -127,7 +133,7 @@ void testAddDuplicateTool() { Tool duplicateTool = new McpSchema.Tool(TEST_TOOL_NAME, "Duplicate tool", emptyJsonSchema); var mcpSyncServer = McpServer.sync(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .capabilities(ServerCapabilities.builder().tools(true).build()) .tool(duplicateTool, (exchange, args) -> new CallToolResult(List.of(), false)) .build(); @@ -145,7 +151,7 @@ void testRemoveTool() { Tool tool = new McpSchema.Tool(TEST_TOOL_NAME, "Test tool", emptyJsonSchema); var mcpSyncServer = McpServer.sync(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .capabilities(ServerCapabilities.builder().tools(true).build()) .tool(tool, (exchange, args) -> new CallToolResult(List.of(), false)) .build(); @@ -158,7 +164,7 @@ void testRemoveTool() { @Test void testRemoveNonexistentTool() { var mcpSyncServer = McpServer.sync(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .capabilities(ServerCapabilities.builder().tools(true).build()) .build(); @@ -170,7 +176,9 @@ void testRemoveNonexistentTool() { @Test void testNotifyToolsListChanged() { - var mcpSyncServer = McpServer.sync(createMcpTransportProvider()).serverInfo("test-server", "1.0.0").build(); + var mcpSyncServer = McpServer.sync(createMcpTransportProvider()) + .serverInfo("test-server", null, "1.0.0") + .build(); assertThatCode(() -> mcpSyncServer.notifyToolsListChanged()).doesNotThrowAnyException(); @@ -183,7 +191,9 @@ void testNotifyToolsListChanged() { @Test void testNotifyResourcesListChanged() { - var mcpSyncServer = McpServer.sync(createMcpTransportProvider()).serverInfo("test-server", "1.0.0").build(); + var mcpSyncServer = McpServer.sync(createMcpTransportProvider()) + .serverInfo("test-server", null, "1.0.0") + .build(); assertThatCode(() -> mcpSyncServer.notifyResourcesListChanged()).doesNotThrowAnyException(); @@ -192,7 +202,9 @@ void testNotifyResourcesListChanged() { @Test void testNotifyResourcesUpdated() { - var mcpSyncServer = McpServer.sync(createMcpTransportProvider()).serverInfo("test-server", "1.0.0").build(); + var mcpSyncServer = McpServer.sync(createMcpTransportProvider()) + .serverInfo("test-server", null, "1.0.0") + .build(); assertThatCode(() -> mcpSyncServer .notifyResourcesUpdated(new McpSchema.ResourcesUpdatedNotification(TEST_RESOURCE_URI))) @@ -204,7 +216,7 @@ void testNotifyResourcesUpdated() { @Test void testAddResource() { var mcpSyncServer = McpServer.sync(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .capabilities(ServerCapabilities.builder().resources(true, false).build()) .build(); @@ -221,7 +233,7 @@ void testAddResource() { @Test void testAddResourceWithNullSpecification() { var mcpSyncServer = McpServer.sync(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .capabilities(ServerCapabilities.builder().resources(true, false).build()) .build(); @@ -235,7 +247,7 @@ void testAddResourceWithNullSpecification() { @Test void testAddResourceWithoutCapability() { var serverWithoutResources = McpServer.sync(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .build(); Resource resource = new Resource(TEST_RESOURCE_URI, "Test Resource", "text/plain", "Test resource description", @@ -250,7 +262,7 @@ void testAddResourceWithoutCapability() { @Test void testRemoveResourceWithoutCapability() { var serverWithoutResources = McpServer.sync(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .build(); assertThatThrownBy(() -> serverWithoutResources.removeResource(TEST_RESOURCE_URI)).isInstanceOf(McpError.class) @@ -263,7 +275,9 @@ void testRemoveResourceWithoutCapability() { @Test void testNotifyPromptsListChanged() { - var mcpSyncServer = McpServer.sync(createMcpTransportProvider()).serverInfo("test-server", "1.0.0").build(); + var mcpSyncServer = McpServer.sync(createMcpTransportProvider()) + .serverInfo("test-server", null, "1.0.0") + .build(); assertThatCode(() -> mcpSyncServer.notifyPromptsListChanged()).doesNotThrowAnyException(); @@ -273,7 +287,7 @@ void testNotifyPromptsListChanged() { @Test void testAddPromptWithNullSpecification() { var mcpSyncServer = McpServer.sync(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .capabilities(ServerCapabilities.builder().prompts(false).build()) .build(); @@ -285,7 +299,7 @@ void testAddPromptWithNullSpecification() { @Test void testAddPromptWithoutCapability() { var serverWithoutPrompts = McpServer.sync(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .build(); Prompt prompt = new Prompt(TEST_PROMPT_NAME, "Test Prompt", List.of()); @@ -300,7 +314,7 @@ void testAddPromptWithoutCapability() { @Test void testRemovePromptWithoutCapability() { var serverWithoutPrompts = McpServer.sync(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .build(); assertThatThrownBy(() -> serverWithoutPrompts.removePrompt(TEST_PROMPT_NAME)).isInstanceOf(McpError.class) @@ -315,7 +329,7 @@ void testRemovePrompt() { .of(new PromptMessage(McpSchema.Role.ASSISTANT, new McpSchema.TextContent("Test content"))))); var mcpSyncServer = McpServer.sync(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .capabilities(ServerCapabilities.builder().prompts(true).build()) .prompts(specification) .build(); @@ -328,7 +342,7 @@ void testRemovePrompt() { @Test void testRemoveNonexistentPrompt() { var mcpSyncServer = McpServer.sync(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .capabilities(ServerCapabilities.builder().prompts(true).build()) .build(); @@ -349,7 +363,7 @@ void testRootsChangeHandlers() { var consumerCalled = new boolean[1]; var singleConsumerServer = McpServer.sync(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .rootsChangeHandlers(List.of((exchange, roots) -> { consumerCalled[0] = true; if (!roots.isEmpty()) { @@ -368,7 +382,7 @@ void testRootsChangeHandlers() { var rootsContent = new List[1]; var multipleConsumersServer = McpServer.sync(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .rootsChangeHandlers(List.of((exchange, roots) -> { consumer1Called[0] = true; rootsContent[0] = roots; @@ -381,7 +395,7 @@ void testRootsChangeHandlers() { // Test error handling var errorHandlingServer = McpServer.sync(createMcpTransportProvider()) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .rootsChangeHandlers(List.of((exchange, roots) -> { throw new RuntimeException("Test error"); })) @@ -392,7 +406,9 @@ void testRootsChangeHandlers() { onClose(); // Test without consumers - var noConsumersServer = McpServer.sync(createMcpTransportProvider()).serverInfo("test-server", "1.0.0").build(); + var noConsumersServer = McpServer.sync(createMcpTransportProvider()) + .serverInfo("test-server", null, "1.0.0") + .build(); assertThat(noConsumersServer).isNotNull(); assertThatCode(() -> noConsumersServer.closeGracefully()).doesNotThrowAnyException(); diff --git a/mcp/src/test/java/io/modelcontextprotocol/server/McpServerProtocolVersionTests.java b/mcp/src/test/java/io/modelcontextprotocol/server/McpServerProtocolVersionTests.java index f643f1ba3..aed90d603 100644 --- a/mcp/src/test/java/io/modelcontextprotocol/server/McpServerProtocolVersionTests.java +++ b/mcp/src/test/java/io/modelcontextprotocol/server/McpServerProtocolVersionTests.java @@ -19,9 +19,11 @@ */ class McpServerProtocolVersionTests { - private static final McpSchema.Implementation SERVER_INFO = new McpSchema.Implementation("test-server", "1.0.0"); + private static final McpSchema.Implementation SERVER_INFO = new McpSchema.Implementation("test-server", null, + "1.0.0"); - private static final McpSchema.Implementation CLIENT_INFO = new McpSchema.Implementation("test-client", "1.0.0"); + private static final McpSchema.Implementation CLIENT_INFO = new McpSchema.Implementation("test-client", null, + "1.0.0"); private McpSchema.JSONRPCRequest jsonRpcInitializeRequest(String requestId, String protocolVersion) { return new McpSchema.JSONRPCRequest(McpSchema.JSONRPC_VERSION, McpSchema.METHOD_INITIALIZE, requestId, diff --git a/mcp/src/test/java/io/modelcontextprotocol/server/transport/HttpServletSseServerCustomContextPathTests.java b/mcp/src/test/java/io/modelcontextprotocol/server/transport/HttpServletSseServerCustomContextPathTests.java index 2cd62889a..7171863ce 100644 --- a/mcp/src/test/java/io/modelcontextprotocol/server/transport/HttpServletSseServerCustomContextPathTests.java +++ b/mcp/src/test/java/io/modelcontextprotocol/server/transport/HttpServletSseServerCustomContextPathTests.java @@ -78,9 +78,9 @@ public void after() { @Test void testCustomContextPath() { - var server = McpServer.async(mcpServerTransportProvider).serverInfo("test-server", "1.0.0").build(); + var server = McpServer.async(mcpServerTransportProvider).serverInfo("test-server", null, "1.0.0").build(); try (//@formatter:off - var client = clientBuilder.clientInfo(new McpSchema.Implementation("Sample " + "client", "0.0.0")) .build()) { //@formatter:on + var client = clientBuilder.clientInfo(new McpSchema.Implementation("Sample " + "client", null, "0.0.0")) .build()) { //@formatter:on assertThat(client.initialize()).isNotNull(); } diff --git a/mcp/src/test/java/io/modelcontextprotocol/server/transport/HttpServletSseServerTransportProviderIntegrationTests.java b/mcp/src/test/java/io/modelcontextprotocol/server/transport/HttpServletSseServerTransportProviderIntegrationTests.java index dc9d1cfab..110b6f524 100644 --- a/mcp/src/test/java/io/modelcontextprotocol/server/transport/HttpServletSseServerTransportProviderIntegrationTests.java +++ b/mcp/src/test/java/io/modelcontextprotocol/server/transport/HttpServletSseServerTransportProviderIntegrationTests.java @@ -117,11 +117,14 @@ void testCreateMessageWithoutSamplingCapabilities() { return Mono.just(mock(CallToolResult.class)); }); - var server = McpServer.async(mcpServerTransportProvider).serverInfo("test-server", "1.0.0").tools(tool).build(); + var server = McpServer.async(mcpServerTransportProvider) + .serverInfo("test-server", null, "1.0.0") + .tools(tool) + .build(); try ( // Create client without sampling capabilities - var client = clientBuilder.clientInfo(new McpSchema.Implementation("Sample " + "client", "0.0.0")) + var client = clientBuilder.clientInfo(new McpSchema.Implementation("Sample " + "client", null, "0.0.0")) .build()) { assertThat(client.initialize()).isNotNull(); @@ -178,11 +181,11 @@ void testCreateMessageSuccess() { }); var mcpServer = McpServer.async(mcpServerTransportProvider) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .tools(tool) .build(); - try (var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0")) + try (var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", null, "0.0.0")) .capabilities(ClientCapabilities.builder().sampling().build()) .sampling(samplingHandler) .build()) { @@ -216,7 +219,7 @@ void testCreateMessageWithRequestTimeoutSuccess() throws InterruptedException { CreateMessageResult.StopReason.STOP_SEQUENCE); }; - var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0")) + var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", null, "0.0.0")) .capabilities(ClientCapabilities.builder().sampling().build()) .sampling(samplingHandler) .build(); @@ -253,7 +256,7 @@ void testCreateMessageWithRequestTimeoutSuccess() throws InterruptedException { }); var mcpServer = McpServer.async(mcpServerTransportProvider) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .requestTimeout(Duration.ofSeconds(3)) .tools(tool) .build(); @@ -288,7 +291,7 @@ void testCreateMessageWithRequestTimeoutFail() throws InterruptedException { CreateMessageResult.StopReason.STOP_SEQUENCE); }; - var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0")) + var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", null, "0.0.0")) .capabilities(ClientCapabilities.builder().sampling().build()) .sampling(samplingHandler) .build(); @@ -325,7 +328,7 @@ void testCreateMessageWithRequestTimeoutFail() throws InterruptedException { }); var mcpServer = McpServer.async(mcpServerTransportProvider) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .requestTimeout(Duration.ofSeconds(1)) .tools(tool) .build(); @@ -356,11 +359,15 @@ void testCreateElicitationWithoutElicitationCapabilities() { return Mono.just(mock(CallToolResult.class)); }); - var server = McpServer.async(mcpServerTransportProvider).serverInfo("test-server", "1.0.0").tools(tool).build(); + var server = McpServer.async(mcpServerTransportProvider) + .serverInfo("test-server", null, "1.0.0") + .tools(tool) + .build(); try ( // Create client without elicitation capabilities - var client = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0")).build()) { + var client = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", null, "0.0.0")) + .build()) { assertThat(client.initialize()).isNotNull(); @@ -407,11 +414,11 @@ void testCreateElicitationSuccess() { }); var mcpServer = McpServer.async(mcpServerTransportProvider) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .tools(tool) .build(); - try (var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0")) + try (var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", null, "0.0.0")) .capabilities(ClientCapabilities.builder().elicitation().build()) .elicitation(elicitationHandler) .build()) { @@ -444,7 +451,7 @@ void testCreateElicitationWithRequestTimeoutSuccess() { return new ElicitResult(ElicitResult.Action.ACCEPT, Map.of("message", request.message())); }; - var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0")) + var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", null, "0.0.0")) .capabilities(ClientCapabilities.builder().elicitation().build()) .elicitation(elicitationHandler) .build(); @@ -473,7 +480,7 @@ void testCreateElicitationWithRequestTimeoutSuccess() { }); var mcpServer = McpServer.async(mcpServerTransportProvider) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .requestTimeout(Duration.ofSeconds(3)) .tools(tool) .build(); @@ -507,7 +514,7 @@ void testCreateElicitationWithRequestTimeoutFail() { return new ElicitResult(ElicitResult.Action.ACCEPT, Map.of("message", request.message())); }; - var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0")) + var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", null, "0.0.0")) .capabilities(ClientCapabilities.builder().elicitation().build()) .elicitation(elicitationHandler) .build(); @@ -536,7 +543,7 @@ void testCreateElicitationWithRequestTimeoutFail() { }); var mcpServer = McpServer.async(mcpServerTransportProvider) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .requestTimeout(Duration.ofSeconds(1)) .tools(tool) .build(); @@ -904,7 +911,7 @@ void testLoggingNotification() { }); var mcpServer = McpServer.async(mcpServerTransportProvider) - .serverInfo("test-server", "1.0.0") + .serverInfo("test-server", null, "1.0.0") .capabilities(ServerCapabilities.builder().logging().tools(true).build()) .tools(tool) .build(); diff --git a/mcp/src/test/java/io/modelcontextprotocol/spec/McpSchemaTests.java b/mcp/src/test/java/io/modelcontextprotocol/spec/McpSchemaTests.java index df8176a4b..88b416bc0 100644 --- a/mcp/src/test/java/io/modelcontextprotocol/spec/McpSchemaTests.java +++ b/mcp/src/test/java/io/modelcontextprotocol/spec/McpSchemaTests.java @@ -241,7 +241,7 @@ void testInitializeRequest() throws Exception { .sampling() .build(); - McpSchema.Implementation clientInfo = new McpSchema.Implementation("test-client", "1.0.0"); + McpSchema.Implementation clientInfo = new McpSchema.Implementation("test-client", null, "1.0.0"); McpSchema.InitializeRequest request = new McpSchema.InitializeRequest("2024-11-05", capabilities, clientInfo); @@ -263,7 +263,7 @@ void testInitializeResult() throws Exception { .tools(true) .build(); - McpSchema.Implementation serverInfo = new McpSchema.Implementation("test-server", "1.0.0"); + McpSchema.Implementation serverInfo = new McpSchema.Implementation("test-server", null, "1.0.0"); McpSchema.InitializeResult result = new McpSchema.InitializeResult("2024-11-05", capabilities, serverInfo, "Server initialized successfully");