diff --git a/mcp-core/src/main/java/io/modelcontextprotocol/server/McpAsyncServer.java b/mcp-core/src/main/java/io/modelcontextprotocol/server/McpAsyncServer.java index ac4b36990..23285d514 100644 --- a/mcp-core/src/main/java/io/modelcontextprotocol/server/McpAsyncServer.java +++ b/mcp-core/src/main/java/io/modelcontextprotocol/server/McpAsyncServer.java @@ -24,7 +24,6 @@ import io.modelcontextprotocol.spec.McpSchema.CallToolResult; import io.modelcontextprotocol.spec.McpSchema.CompleteResult.CompleteCompletion; import io.modelcontextprotocol.spec.McpSchema.ErrorCodes; -import io.modelcontextprotocol.spec.McpSchema.JSONRPCResponse; import io.modelcontextprotocol.spec.McpSchema.LoggingLevel; import io.modelcontextprotocol.spec.McpSchema.LoggingMessageNotification; import io.modelcontextprotocol.spec.McpSchema.PromptReference; @@ -398,11 +397,12 @@ public Mono apply(McpAsyncServerExchange exchange, McpSchema.Cal // results that conform to this schema. // https://modelcontextprotocol.io/specification/2025-06-18/server/tools#output-schema if (result.structuredContent() == null) { - logger.warn( - "Response missing structured content which is expected when calling tool with non-empty outputSchema"); - return new CallToolResult( - "Response missing structured content which is expected when calling tool with non-empty outputSchema", - true); + String content = "Response missing structured content which is expected when calling tool with non-empty outputSchema"; + logger.warn(content); + return CallToolResult.builder() + .content(List.of(new McpSchema.TextContent(content))) + .isError(true) + .build(); } // Validate the result against the output schema @@ -410,7 +410,10 @@ public Mono apply(McpAsyncServerExchange exchange, McpSchema.Cal if (!validation.valid()) { logger.warn("Tool call result validation failed: {}", validation.errorMessage()); - return new CallToolResult(validation.errorMessage(), true); + return CallToolResult.builder() + .content(List.of(new McpSchema.TextContent(validation.errorMessage()))) + .isError(true) + .build(); } if (Utils.isEmpty(result.content())) { diff --git a/mcp-core/src/main/java/io/modelcontextprotocol/server/McpServer.java b/mcp-core/src/main/java/io/modelcontextprotocol/server/McpServer.java index 87c84ba1b..fe3125271 100644 --- a/mcp-core/src/main/java/io/modelcontextprotocol/server/McpServer.java +++ b/mcp-core/src/main/java/io/modelcontextprotocol/server/McpServer.java @@ -67,7 +67,10 @@ * McpServer.sync(transportProvider) * .serverInfo("my-server", "1.0.0") * .tool(Tool.builder().name("calculator").title("Performs calculations").inputSchema(schema).build(), - * (exchange, args) -> new CallToolResult("Result: " + calculate(args))) + * (exchange, args) -> CallToolResult.builder() + * .content(List.of(new McpSchema.TextContent("Result: " + calculate(args)))) + * .isError(false) + * .build()) * .build(); * } * @@ -76,7 +79,10 @@ * .serverInfo("my-server", "1.0.0") * .tool(Tool.builder().name("calculator").title("Performs calculations").inputSchema(schema).build(), * (exchange, args) -> Mono.fromSupplier(() -> calculate(args)) - * .map(result -> new CallToolResult("Result: " + result))) + * .map(result -> CallToolResult.builder() + * .content(List.of(new McpSchema.TextContent("Result: " + result))) + * .isError(false) + * .build())) * .build(); * } * @@ -90,12 +96,18 @@ * McpServerFeatures.AsyncToolSpecification.builder() * .tool(calculatorTool) * .callTool((exchange, args) -> Mono.fromSupplier(() -> calculate(args.arguments())) - * .map(result -> new CallToolResult("Result: " + result)))) + * .map(result -> CallToolResult.builder() + * .content(List.of(new McpSchema.TextContent("Result: " + result))) + * .isError(false) + * .build())) *. .build(), * McpServerFeatures.AsyncToolSpecification.builder() * .tool((weatherTool) * .callTool((exchange, args) -> Mono.fromSupplier(() -> getWeather(args.arguments())) - * .map(result -> new CallToolResult("Weather: " + result)))) + * .map(result -> CallToolResult.builder() + * .content(List.of(new McpSchema.TextContent("Weather: " + result))) + * .isError(false) + * .build())) * .build() * ) * // Register resources @@ -425,7 +437,10 @@ public AsyncSpecification capabilities(McpSchema.ServerCapabilities serverCap * .tool( * Tool.builder().name("calculator").title("Performs calculations").inputSchema(schema).build(), * (exchange, args) -> Mono.fromSupplier(() -> calculate(args)) - * .map(result -> new CallToolResult("Result: " + result)) + * .map(result -> CallToolResult.builder() + * .content(List.of(new McpSchema.TextContent("Result: " + result))) + * .isError(false) + * .build())) * ) * } * @param tool The tool definition including name, description, and schema. Must @@ -1022,7 +1037,10 @@ public SyncSpecification capabilities(McpSchema.ServerCapabilities serverCapa * Example usage:
{@code
 		 * .tool(
 		 *     Tool.builder().name("calculator").title("Performs calculations".inputSchema(schema).build(),
-		 *     (exchange, args) -> new CallToolResult("Result: " + calculate(args))
+		 *     (exchange, args) -> CallToolResult.builder()
+		 *                   .content(List.of(new McpSchema.TextContent("Result: " + calculate(args))))
+		 *                   .isError(false)
+		 *                   .build())
 		 * )
 		 * }
* @param tool The tool definition including name, description, and schema. Must diff --git a/mcp-core/src/main/java/io/modelcontextprotocol/server/McpServerFeatures.java b/mcp-core/src/main/java/io/modelcontextprotocol/server/McpServerFeatures.java index fc5bdfe4e..fe0608b1c 100644 --- a/mcp-core/src/main/java/io/modelcontextprotocol/server/McpServerFeatures.java +++ b/mcp-core/src/main/java/io/modelcontextprotocol/server/McpServerFeatures.java @@ -334,7 +334,13 @@ public static Builder builder() { * *
{@code
 	 * new McpServerFeatures.AsyncResourceSpecification(
-	 * 		new Resource("docs", "Documentation files", "text/markdown"),
+	 *     Resource.builder()
+	 *         .uri("docs")
+	 *         .name("Documentation files")
+	 * 		   .title("Documentation files")
+	 * 		   .mimeType("text/markdown")
+	 * 		   .description("Markdown documentation files")
+	 * 		   .build(),
 	 * 		(exchange, request) -> Mono.fromSupplier(() -> readFile(request.getPath()))
 	 * 				.map(ReadResourceResult::new))
 	 * }
@@ -508,7 +514,10 @@ static AsyncCompletionSpecification fromSync(SyncCompletionSpecification complet * .build() * .toolHandler((exchange, req) -> { * String expr = (String) req.arguments().get("expression"); - * return new CallToolResult("Result: " + evaluate(expr)); + * return CallToolResult.builder() + * .content(List.of(new McpSchema.TextContent("Result: " + evaluate(expr)))) + * .isError(false) + * .build(); * })) * .build(); * } @@ -604,7 +613,13 @@ public static Builder builder() { * *
{@code
 	 * new McpServerFeatures.SyncResourceSpecification(
-	 * 		new Resource("docs", "Documentation files", "text/markdown"),
+	 *     Resource.builder()
+	 *         .uri("docs")
+	 *         .name("Documentation files")
+	 * 		   .title("Documentation files")
+	 * 		   .mimeType("text/markdown")
+	 * 		   .description("Markdown documentation files")
+	 * 		   .build(),
 	 * 		(exchange, request) -> {
 	 * 			String content = readFile(request.getPath());
 	 * 			return new ReadResourceResult(content);
diff --git a/mcp-core/src/main/java/io/modelcontextprotocol/server/McpStatelessAsyncServer.java b/mcp-core/src/main/java/io/modelcontextprotocol/server/McpStatelessAsyncServer.java
index 997df7225..c7a1fd0d7 100644
--- a/mcp-core/src/main/java/io/modelcontextprotocol/server/McpStatelessAsyncServer.java
+++ b/mcp-core/src/main/java/io/modelcontextprotocol/server/McpStatelessAsyncServer.java
@@ -14,7 +14,6 @@
 import io.modelcontextprotocol.spec.McpSchema.CallToolResult;
 import io.modelcontextprotocol.spec.McpSchema.CompleteResult.CompleteCompletion;
 import io.modelcontextprotocol.spec.McpSchema.ErrorCodes;
-import io.modelcontextprotocol.spec.McpSchema.JSONRPCResponse;
 import io.modelcontextprotocol.spec.McpSchema.PromptReference;
 import io.modelcontextprotocol.spec.McpSchema.ResourceReference;
 import io.modelcontextprotocol.spec.McpSchema.Tool;
@@ -277,11 +276,12 @@ public Mono apply(McpTransportContext transportContext, McpSchem
 				// results that conform to this schema.
 				// https://modelcontextprotocol.io/specification/2025-06-18/server/tools#output-schema
 				if (result.structuredContent() == null) {
-					logger.warn(
-							"Response missing structured content which is expected when calling tool with non-empty outputSchema");
-					return new CallToolResult(
-							"Response missing structured content which is expected when calling tool with non-empty outputSchema",
-							true);
+					String content = "Response missing structured content which is expected when calling tool with non-empty outputSchema";
+					logger.warn(content);
+					return CallToolResult.builder()
+						.content(List.of(new McpSchema.TextContent(content)))
+						.isError(true)
+						.build();
 				}
 
 				// Validate the result against the output schema
@@ -289,7 +289,10 @@ public Mono apply(McpTransportContext transportContext, McpSchem
 
 				if (!validation.valid()) {
 					logger.warn("Tool call result validation failed: {}", validation.errorMessage());
-					return new CallToolResult(validation.errorMessage(), true);
+					return CallToolResult.builder()
+						.content(List.of(new McpSchema.TextContent(validation.errorMessage())))
+						.isError(true)
+						.build();
 				}
 
 				if (Utils.isEmpty(result.content())) {
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 342fc5347..734cff237 100644
--- a/mcp-core/src/main/java/io/modelcontextprotocol/spec/McpSchema.java
+++ b/mcp-core/src/main/java/io/modelcontextprotocol/spec/McpSchema.java
@@ -1562,6 +1562,7 @@ public CallToolResult(List content, Boolean isError, Map meta) {
 			 * @return a new CallToolResult instance
 			 */
 			public CallToolResult build() {
-				return new CallToolResult(content, isError, (Object) structuredContent, meta);
+				return new CallToolResult(content, isError, structuredContent, meta);
 			}
 
 		}
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 aa68203dd..090710248 100644
--- a/mcp-core/src/test/java/io/modelcontextprotocol/server/AbstractMcpAsyncServerTests.java
+++ b/mcp-core/src/test/java/io/modelcontextprotocol/server/AbstractMcpAsyncServerTests.java
@@ -7,7 +7,6 @@
 import java.time.Duration;
 import java.util.List;
 
-import io.modelcontextprotocol.spec.McpError;
 import io.modelcontextprotocol.spec.McpSchema;
 import io.modelcontextprotocol.spec.McpSchema.CallToolResult;
 import io.modelcontextprotocol.spec.McpSchema.GetPromptResult;
@@ -86,7 +85,7 @@ void testGracefulShutdown() {
 	void testImmediateClose() {
 		var mcpAsyncServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0").build();
 
-		assertThatCode(() -> mcpAsyncServer.close()).doesNotThrowAnyException();
+		assertThatCode(mcpAsyncServer::close).doesNotThrowAnyException();
 	}
 
 	// ---------------------------------------
@@ -104,8 +103,9 @@ void testAddTool() {
 			.capabilities(ServerCapabilities.builder().tools(true).build())
 			.build();
 
-		StepVerifier.create(mcpAsyncServer.addTool(new McpServerFeatures.AsyncToolSpecification(newTool,
-				(exchange, args) -> Mono.just(new CallToolResult(List.of(), false)))))
+		StepVerifier
+			.create(mcpAsyncServer.addTool(new McpServerFeatures.AsyncToolSpecification(newTool,
+					(exchange, args) -> Mono.just(CallToolResult.builder().content(List.of()).isError(false).build()))))
 			.verifyComplete();
 
 		assertThatCode(() -> mcpAsyncServer.closeGracefully().block(Duration.ofSeconds(10))).doesNotThrowAnyException();
@@ -125,7 +125,8 @@ void testAddToolCall() {
 
 		StepVerifier.create(mcpAsyncServer.addTool(McpServerFeatures.AsyncToolSpecification.builder()
 			.tool(newTool)
-			.callHandler((exchange, request) -> Mono.just(new CallToolResult(List.of(), false)))
+			.callHandler((exchange, request) -> Mono
+				.just(CallToolResult.builder().content(List.of()).isError(false).build()))
 			.build())).verifyComplete();
 
 		assertThatCode(() -> mcpAsyncServer.closeGracefully().block(Duration.ofSeconds(10))).doesNotThrowAnyException();
@@ -142,11 +143,13 @@ void testAddDuplicateTool() {
 
 		var mcpAsyncServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0")
 			.capabilities(ServerCapabilities.builder().tools(true).build())
-			.tool(duplicateTool, (exchange, args) -> Mono.just(new CallToolResult(List.of(), false)))
+			.tool(duplicateTool,
+					(exchange, args) -> Mono.just(CallToolResult.builder().content(List.of()).isError(false).build()))
 			.build();
 
-		StepVerifier.create(mcpAsyncServer.addTool(new McpServerFeatures.AsyncToolSpecification(duplicateTool,
-				(exchange, args) -> Mono.just(new CallToolResult(List.of(), false)))))
+		StepVerifier
+			.create(mcpAsyncServer.addTool(new McpServerFeatures.AsyncToolSpecification(duplicateTool,
+					(exchange, args) -> Mono.just(CallToolResult.builder().content(List.of()).isError(false).build()))))
 			.verifyComplete();
 
 		assertThatCode(() -> mcpAsyncServer.closeGracefully().block(Duration.ofSeconds(10))).doesNotThrowAnyException();
@@ -162,12 +165,15 @@ void testAddDuplicateToolCall() {
 
 		var mcpAsyncServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0")
 			.capabilities(ServerCapabilities.builder().tools(true).build())
-			.toolCall(duplicateTool, (exchange, request) -> Mono.just(new CallToolResult(List.of(), false)))
+			.toolCall(duplicateTool,
+					(exchange, request) -> Mono
+						.just(CallToolResult.builder().content(List.of()).isError(false).build()))
 			.build();
 
 		StepVerifier.create(mcpAsyncServer.addTool(McpServerFeatures.AsyncToolSpecification.builder()
 			.tool(duplicateTool)
-			.callHandler((exchange, request) -> Mono.just(new CallToolResult(List.of(), false)))
+			.callHandler((exchange, request) -> Mono
+				.just(CallToolResult.builder().content(List.of()).isError(false).build()))
 			.build())).verifyComplete();
 
 		assertThatCode(() -> mcpAsyncServer.closeGracefully().block(Duration.ofSeconds(10))).doesNotThrowAnyException();
@@ -183,8 +189,12 @@ void testDuplicateToolCallDuringBuilding() {
 
 		assertThatThrownBy(() -> prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0")
 			.capabilities(ServerCapabilities.builder().tools(true).build())
-			.toolCall(duplicateTool, (exchange, request) -> Mono.just(new CallToolResult(List.of(), false)))
-			.toolCall(duplicateTool, (exchange, request) -> Mono.just(new CallToolResult(List.of(), false))) // Duplicate!
+			.toolCall(duplicateTool,
+					(exchange, request) -> Mono
+						.just(CallToolResult.builder().content(List.of()).isError(false).build()))
+			.toolCall(duplicateTool,
+					(exchange, request) -> Mono
+						.just(CallToolResult.builder().content(List.of()).isError(false).build())) // Duplicate!
 			.build()).isInstanceOf(IllegalArgumentException.class)
 			.hasMessage("Tool with name 'duplicate-build-toolcall' is already registered.");
 	}
@@ -200,11 +210,13 @@ void testDuplicateToolsInBatchListRegistration() {
 		List specs = List.of(
 				McpServerFeatures.AsyncToolSpecification.builder()
 					.tool(duplicateTool)
-					.callHandler((exchange, request) -> Mono.just(new CallToolResult(List.of(), false)))
+					.callHandler((exchange, request) -> Mono
+						.just(CallToolResult.builder().content(List.of()).isError(false).build()))
 					.build(),
 				McpServerFeatures.AsyncToolSpecification.builder()
 					.tool(duplicateTool)
-					.callHandler((exchange, request) -> Mono.just(new CallToolResult(List.of(), false)))
+					.callHandler((exchange, request) -> Mono
+						.just(CallToolResult.builder().content(List.of()).isError(false).build()))
 					.build() // Duplicate!
 		);
 
@@ -227,11 +239,13 @@ void testDuplicateToolsInBatchVarargsRegistration() {
 			.capabilities(ServerCapabilities.builder().tools(true).build())
 			.tools(McpServerFeatures.AsyncToolSpecification.builder()
 				.tool(duplicateTool)
-				.callHandler((exchange, request) -> Mono.just(new CallToolResult(List.of(), false)))
+				.callHandler((exchange, request) -> Mono
+					.just(CallToolResult.builder().content(List.of()).isError(false).build()))
 				.build(),
 					McpServerFeatures.AsyncToolSpecification.builder()
 						.tool(duplicateTool)
-						.callHandler((exchange, request) -> Mono.just(new CallToolResult(List.of(), false)))
+						.callHandler((exchange, request) -> Mono
+							.just(CallToolResult.builder().content(List.of()).isError(false).build()))
 						.build() // Duplicate!
 			)
 			.build()).isInstanceOf(IllegalArgumentException.class)
@@ -248,7 +262,9 @@ void testRemoveTool() {
 
 		var mcpAsyncServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0")
 			.capabilities(ServerCapabilities.builder().tools(true).build())
-			.toolCall(too, (exchange, request) -> Mono.just(new CallToolResult(List.of(), false)))
+			.toolCall(too,
+					(exchange, request) -> Mono
+						.just(CallToolResult.builder().content(List.of()).isError(false).build()))
 			.build();
 
 		StepVerifier.create(mcpAsyncServer.removeTool(TEST_TOOL_NAME)).verifyComplete();
@@ -277,7 +293,8 @@ void testNotifyToolsListChanged() {
 
 		var mcpAsyncServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0")
 			.capabilities(ServerCapabilities.builder().tools(true).build())
-			.toolCall(too, (exchange, args) -> Mono.just(new CallToolResult(List.of(), false)))
+			.toolCall(too,
+					(exchange, args) -> Mono.just(CallToolResult.builder().content(List.of()).isError(false).build()))
 			.build();
 
 		StepVerifier.create(mcpAsyncServer.notifyToolsListChanged()).verifyComplete();
@@ -316,8 +333,13 @@ void testAddResource() {
 			.capabilities(ServerCapabilities.builder().resources(true, false).build())
 			.build();
 
-		Resource resource = new Resource(TEST_RESOURCE_URI, "Test Resource", "text/plain", "Test resource description",
-				null);
+		Resource resource = Resource.builder()
+			.uri(TEST_RESOURCE_URI)
+			.name("Test Resource")
+			.title("Test Resource")
+			.mimeType("text/plain")
+			.description("Test resource description")
+			.build();
 		McpServerFeatures.AsyncResourceSpecification specification = new McpServerFeatures.AsyncResourceSpecification(
 				resource, (exchange, req) -> Mono.just(new ReadResourceResult(List.of())));
 
@@ -345,8 +367,13 @@ void testAddResourceWithoutCapability() {
 		// Create a server without resource capabilities
 		McpAsyncServer serverWithoutResources = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0").build();
 
-		Resource resource = new Resource(TEST_RESOURCE_URI, "Test Resource", "text/plain", "Test resource description",
-				null);
+		Resource resource = Resource.builder()
+			.uri(TEST_RESOURCE_URI)
+			.name("Test Resource")
+			.title("Test Resource")
+			.mimeType("text/plain")
+			.description("Test resource description")
+			.build();
 		McpServerFeatures.AsyncResourceSpecification specification = new McpServerFeatures.AsyncResourceSpecification(
 				resource, (exchange, req) -> Mono.just(new ReadResourceResult(List.of())));
 
@@ -373,8 +400,13 @@ void testListResources() {
 			.capabilities(ServerCapabilities.builder().resources(true, false).build())
 			.build();
 
-		Resource resource = new Resource(TEST_RESOURCE_URI, "Test Resource", "text/plain", "Test resource description",
-				null);
+		Resource resource = Resource.builder()
+			.uri(TEST_RESOURCE_URI)
+			.name("Test Resource")
+			.title("Test Resource")
+			.mimeType("text/plain")
+			.description("Test resource description")
+			.build();
 		McpServerFeatures.AsyncResourceSpecification specification = new McpServerFeatures.AsyncResourceSpecification(
 				resource, (exchange, req) -> Mono.just(new ReadResourceResult(List.of())));
 
@@ -392,8 +424,13 @@ void testRemoveResource() {
 			.capabilities(ServerCapabilities.builder().resources(true, false).build())
 			.build();
 
-		Resource resource = new Resource(TEST_RESOURCE_URI, "Test Resource", "text/plain", "Test resource description",
-				null);
+		Resource resource = Resource.builder()
+			.uri(TEST_RESOURCE_URI)
+			.name("Test Resource")
+			.title("Test Resource")
+			.mimeType("text/plain")
+			.description("Test resource description")
+			.build();
 		McpServerFeatures.AsyncResourceSpecification specification = new McpServerFeatures.AsyncResourceSpecification(
 				resource, (exchange, req) -> Mono.just(new ReadResourceResult(List.of())));
 
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 603324631..1f5387f37 100644
--- a/mcp-core/src/test/java/io/modelcontextprotocol/server/AbstractMcpClientServerIntegrationTests.java
+++ b/mcp-core/src/test/java/io/modelcontextprotocol/server/AbstractMcpClientServerIntegrationTests.java
@@ -851,7 +851,7 @@ void testThrowingToolCallIsCaughtBeforeTimeout(String clientType) {
 
 	@ParameterizedTest(name = "{0} : {displayName} ")
 	@MethodSource("clientsForTesting")
-	void testToolCallSuccessWithTranportContextExtraction(String clientType) {
+	void testToolCallSuccessWithTransportContextExtraction(String clientType) {
 
 		var clientBuilder = clientBuilders.get(clientType);
 
@@ -1077,7 +1077,10 @@ void testLoggingNotification(String clientType) throws InterruptedException {
 								.logger("test-logger")
 								.data("Another error message")
 								.build()))
-					.thenReturn(new CallToolResult("Logging test completed", false));
+					.thenReturn(CallToolResult.builder()
+							.content(List.of(new McpSchema.TextContent("Logging test completed")))
+							.isError(false)
+							.build());
 					//@formatter:on
 			})
 			.build();
@@ -1172,7 +1175,10 @@ void testProgressNotification(String clientType) throws InterruptedException {
 									0.0, 1.0, "Another processing started")))
 					.then(exchange.progressNotification(
 							new McpSchema.ProgressNotification(progressToken, 1.0, 1.0, "Processing completed")))
-					.thenReturn(new CallToolResult(("Progress test completed"), false));
+					.thenReturn(CallToolResult.builder()
+						.content(List.of(new McpSchema.TextContent("Progress test completed")))
+						.isError(false)
+						.build());
 			})
 			.build();
 
@@ -1326,7 +1332,10 @@ void testPingSuccess(String clientType) {
 					assertThat(result).isNotNull();
 				}).then(Mono.fromCallable(() -> {
 					executionOrder.set(executionOrder.get() + "3");
-					return new CallToolResult("Async ping test completed", false);
+					return CallToolResult.builder()
+						.content(List.of(new McpSchema.TextContent("Async ping test completed")))
+						.isError(false)
+						.build();
 				}));
 			})
 			.build();
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 976eb8c2c..915c658e3 100644
--- a/mcp-core/src/test/java/io/modelcontextprotocol/server/AbstractMcpSyncServerTests.java
+++ b/mcp-core/src/test/java/io/modelcontextprotocol/server/AbstractMcpSyncServerTests.java
@@ -6,7 +6,6 @@
 
 import java.util.List;
 
-import io.modelcontextprotocol.spec.McpError;
 import io.modelcontextprotocol.spec.McpSchema;
 import io.modelcontextprotocol.spec.McpSchema.CallToolResult;
 import io.modelcontextprotocol.spec.McpSchema.GetPromptResult;
@@ -78,14 +77,14 @@ void testConstructorWithInvalidArguments() {
 	void testGracefulShutdown() {
 		var mcpSyncServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0").build();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
 	void testImmediateClose() {
 		var mcpSyncServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0").build();
 
-		assertThatCode(() -> mcpSyncServer.close()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::close).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -94,7 +93,7 @@ void testGetAsyncServer() {
 
 		assertThat(mcpSyncServer.getAsyncServer()).isNotNull();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	// ---------------------------------------
@@ -114,10 +113,10 @@ void testAddTool() {
 			.inputSchema(EMPTY_JSON_SCHEMA)
 			.build();
 		assertThatCode(() -> mcpSyncServer.addTool(new McpServerFeatures.SyncToolSpecification(newTool,
-				(exchange, args) -> new CallToolResult(List.of(), false))))
+				(exchange, args) -> CallToolResult.builder().content(List.of()).isError(false).build())))
 			.doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -134,10 +133,10 @@ void testAddToolCall() {
 
 		assertThatCode(() -> mcpSyncServer.addTool(McpServerFeatures.SyncToolSpecification.builder()
 			.tool(newTool)
-			.callHandler((exchange, request) -> new CallToolResult(List.of(), false))
+			.callHandler((exchange, request) -> CallToolResult.builder().content(List.of()).isError(false).build())
 			.build())).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -151,14 +150,14 @@ void testAddDuplicateTool() {
 
 		var mcpSyncServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0")
 			.capabilities(ServerCapabilities.builder().tools(true).build())
-			.tool(duplicateTool, (exchange, args) -> new CallToolResult(List.of(), false))
+			.tool(duplicateTool, (exchange, args) -> CallToolResult.builder().content(List.of()).isError(false).build())
 			.build();
 
 		assertThatCode(() -> mcpSyncServer.addTool(new McpServerFeatures.SyncToolSpecification(duplicateTool,
-				(exchange, args) -> new CallToolResult(List.of(), false))))
+				(exchange, args) -> CallToolResult.builder().content(List.of()).isError(false).build())))
 			.doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -171,15 +170,16 @@ void testAddDuplicateToolCall() {
 
 		var mcpSyncServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0")
 			.capabilities(ServerCapabilities.builder().tools(true).build())
-			.toolCall(duplicateTool, (exchange, request) -> new CallToolResult(List.of(), false))
+			.toolCall(duplicateTool,
+					(exchange, request) -> CallToolResult.builder().content(List.of()).isError(false).build())
 			.build();
 
 		assertThatCode(() -> mcpSyncServer.addTool(McpServerFeatures.SyncToolSpecification.builder()
 			.tool(duplicateTool)
-			.callHandler((exchange, request) -> new CallToolResult(List.of(), false))
+			.callHandler((exchange, request) -> CallToolResult.builder().content(List.of()).isError(false).build())
 			.build())).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -192,8 +192,10 @@ void testDuplicateToolCallDuringBuilding() {
 
 		assertThatThrownBy(() -> prepareSyncServerBuilder().serverInfo("test-server", "1.0.0")
 			.capabilities(ServerCapabilities.builder().tools(true).build())
-			.toolCall(duplicateTool, (exchange, request) -> new CallToolResult(List.of(), false))
-			.toolCall(duplicateTool, (exchange, request) -> new CallToolResult(List.of(), false)) // Duplicate!
+			.toolCall(duplicateTool,
+					(exchange, request) -> CallToolResult.builder().content(List.of()).isError(false).build())
+			.toolCall(duplicateTool,
+					(exchange, request) -> CallToolResult.builder().content(List.of()).isError(false).build()) // Duplicate!
 			.build()).isInstanceOf(IllegalArgumentException.class)
 			.hasMessage("Tool with name 'duplicate-build-toolcall' is already registered.");
 	}
@@ -208,11 +210,13 @@ void testDuplicateToolsInBatchListRegistration() {
 		List specs = List.of(
 				McpServerFeatures.SyncToolSpecification.builder()
 					.tool(duplicateTool)
-					.callHandler((exchange, request) -> new CallToolResult(List.of(), false))
+					.callHandler(
+							(exchange, request) -> CallToolResult.builder().content(List.of()).isError(false).build())
 					.build(),
 				McpServerFeatures.SyncToolSpecification.builder()
 					.tool(duplicateTool)
-					.callHandler((exchange, request) -> new CallToolResult(List.of(), false))
+					.callHandler(
+							(exchange, request) -> CallToolResult.builder().content(List.of()).isError(false).build())
 					.build() // Duplicate!
 		);
 
@@ -235,11 +239,12 @@ void testDuplicateToolsInBatchVarargsRegistration() {
 			.capabilities(ServerCapabilities.builder().tools(true).build())
 			.tools(McpServerFeatures.SyncToolSpecification.builder()
 				.tool(duplicateTool)
-				.callHandler((exchange, request) -> new CallToolResult(List.of(), false))
+				.callHandler((exchange, request) -> CallToolResult.builder().content(List.of()).isError(false).build())
 				.build(),
 					McpServerFeatures.SyncToolSpecification.builder()
 						.tool(duplicateTool)
-						.callHandler((exchange, request) -> new CallToolResult(List.of(), false))
+						.callHandler((exchange,
+								request) -> CallToolResult.builder().content(List.of()).isError(false).build())
 						.build() // Duplicate!
 			)
 			.build()).isInstanceOf(IllegalArgumentException.class)
@@ -256,12 +261,12 @@ void testRemoveTool() {
 
 		var mcpSyncServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0")
 			.capabilities(ServerCapabilities.builder().tools(true).build())
-			.toolCall(tool, (exchange, args) -> new CallToolResult(List.of(), false))
+			.toolCall(tool, (exchange, args) -> CallToolResult.builder().content(List.of()).isError(false).build())
 			.build();
 
 		assertThatCode(() -> mcpSyncServer.removeTool(TEST_TOOL_NAME)).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -272,16 +277,16 @@ void testRemoveNonexistentTool() {
 
 		assertThatCode(() -> mcpSyncServer.removeTool("nonexistent-tool")).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
 	void testNotifyToolsListChanged() {
 		var mcpSyncServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0").build();
 
-		assertThatCode(() -> mcpSyncServer.notifyToolsListChanged()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::notifyToolsListChanged).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	// ---------------------------------------
@@ -292,9 +297,9 @@ void testNotifyToolsListChanged() {
 	void testNotifyResourcesListChanged() {
 		var mcpSyncServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0").build();
 
-		assertThatCode(() -> mcpSyncServer.notifyResourcesListChanged()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::notifyResourcesListChanged).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -305,7 +310,7 @@ void testNotifyResourcesUpdated() {
 			.notifyResourcesUpdated(new McpSchema.ResourcesUpdatedNotification(TEST_RESOURCE_URI)))
 			.doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -314,14 +319,18 @@ void testAddResource() {
 			.capabilities(ServerCapabilities.builder().resources(true, false).build())
 			.build();
 
-		Resource resource = new Resource(TEST_RESOURCE_URI, "Test Resource", "text/plain", "Test resource description",
-				null);
+		Resource resource = Resource.builder()
+			.uri(TEST_RESOURCE_URI)
+			.name("Test Resource")
+			.mimeType("text/plain")
+			.description("Test resource description")
+			.build();
 		McpServerFeatures.SyncResourceSpecification specification = new McpServerFeatures.SyncResourceSpecification(
 				resource, (exchange, req) -> new ReadResourceResult(List.of()));
 
 		assertThatCode(() -> mcpSyncServer.addResource(specification)).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -334,15 +343,19 @@ void testAddResourceWithNullSpecification() {
 			.isInstanceOf(IllegalArgumentException.class)
 			.hasMessage("Resource must not be null");
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
 	void testAddResourceWithoutCapability() {
 		var serverWithoutResources = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0").build();
 
-		Resource resource = new Resource(TEST_RESOURCE_URI, "Test Resource", "text/plain", "Test resource description",
-				null);
+		Resource resource = Resource.builder()
+			.uri(TEST_RESOURCE_URI)
+			.name("Test Resource")
+			.mimeType("text/plain")
+			.description("Test resource description")
+			.build();
 		McpServerFeatures.SyncResourceSpecification specification = new McpServerFeatures.SyncResourceSpecification(
 				resource, (exchange, req) -> new ReadResourceResult(List.of()));
 
@@ -366,8 +379,12 @@ void testListResources() {
 			.capabilities(ServerCapabilities.builder().resources(true, false).build())
 			.build();
 
-		Resource resource = new Resource(TEST_RESOURCE_URI, "Test Resource", "text/plain", "Test resource description",
-				null);
+		Resource resource = Resource.builder()
+			.uri(TEST_RESOURCE_URI)
+			.name("Test Resource")
+			.mimeType("text/plain")
+			.description("Test resource description")
+			.build();
 		McpServerFeatures.SyncResourceSpecification specification = new McpServerFeatures.SyncResourceSpecification(
 				resource, (exchange, req) -> new ReadResourceResult(List.of()));
 
@@ -377,7 +394,7 @@ void testListResources() {
 		assertThat(resources).hasSize(1);
 		assertThat(resources.get(0).uri()).isEqualTo(TEST_RESOURCE_URI);
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -386,15 +403,19 @@ void testRemoveResource() {
 			.capabilities(ServerCapabilities.builder().resources(true, false).build())
 			.build();
 
-		Resource resource = new Resource(TEST_RESOURCE_URI, "Test Resource", "text/plain", "Test resource description",
-				null);
+		Resource resource = Resource.builder()
+			.uri(TEST_RESOURCE_URI)
+			.name("Test Resource")
+			.mimeType("text/plain")
+			.description("Test resource description")
+			.build();
 		McpServerFeatures.SyncResourceSpecification specification = new McpServerFeatures.SyncResourceSpecification(
 				resource, (exchange, req) -> new ReadResourceResult(List.of()));
 
 		mcpSyncServer.addResource(specification);
 		assertThatCode(() -> mcpSyncServer.removeResource(TEST_RESOURCE_URI)).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -407,7 +428,7 @@ void testRemoveNonexistentResource() {
 		// as per the new implementation that just logs a warning
 		assertThatCode(() -> mcpSyncServer.removeResource("nonexistent://resource")).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	// ---------------------------------------
@@ -432,7 +453,7 @@ void testAddResourceTemplate() {
 
 		assertThatCode(() -> mcpSyncServer.addResourceTemplate(specification)).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -474,7 +495,7 @@ void testRemoveResourceTemplate() {
 
 		assertThatCode(() -> mcpSyncServer.removeResourceTemplate("test://template/{id}")).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -496,7 +517,7 @@ void testRemoveNonexistentResourceTemplate() {
 		assertThatCode(() -> mcpSyncServer.removeResourceTemplate("nonexistent://template/{id}"))
 			.doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -520,7 +541,7 @@ void testListResourceTemplates() {
 
 		assertThat(templates).isNotNull();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	// ---------------------------------------
@@ -531,9 +552,9 @@ void testListResourceTemplates() {
 	void testNotifyPromptsListChanged() {
 		var mcpSyncServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0").build();
 
-		assertThatCode(() -> mcpSyncServer.notifyPromptsListChanged()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::notifyPromptsListChanged).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -584,7 +605,7 @@ void testRemovePrompt() {
 
 		assertThatCode(() -> mcpSyncServer.removePrompt(TEST_PROMPT_NAME)).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -595,7 +616,7 @@ void testRemoveNonexistentPrompt() {
 
 		assertThatCode(() -> mcpSyncServer.removePrompt("nonexistent://template/{id}")).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	// ---------------------------------------
@@ -617,7 +638,7 @@ void testRootsChangeHandlers() {
 			}))
 			.build();
 		assertThat(singleConsumerServer).isNotNull();
-		assertThatCode(() -> singleConsumerServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(singleConsumerServer::closeGracefully).doesNotThrowAnyException();
 		onClose();
 
 		// Test with multiple consumers
@@ -633,7 +654,7 @@ void testRootsChangeHandlers() {
 			.build();
 
 		assertThat(multipleConsumersServer).isNotNull();
-		assertThatCode(() -> multipleConsumersServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(multipleConsumersServer::closeGracefully).doesNotThrowAnyException();
 		onClose();
 
 		// Test error handling
@@ -644,14 +665,14 @@ void testRootsChangeHandlers() {
 			.build();
 
 		assertThat(errorHandlingServer).isNotNull();
-		assertThatCode(() -> errorHandlingServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(errorHandlingServer::closeGracefully).doesNotThrowAnyException();
 		onClose();
 
 		// Test without consumers
 		var noConsumersServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0").build();
 
 		assertThat(noConsumersServer).isNotNull();
-		assertThatCode(() -> noConsumersServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(noConsumersServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 }
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 8fe8e6fb0..62332fcdb 100644
--- a/mcp-core/src/test/java/io/modelcontextprotocol/server/AsyncToolSpecificationBuilderTest.java
+++ b/mcp-core/src/test/java/io/modelcontextprotocol/server/AsyncToolSpecificationBuilderTest.java
@@ -40,7 +40,7 @@ void builderShouldCreateValidAsyncToolSpecification() {
 		McpServerFeatures.AsyncToolSpecification specification = McpServerFeatures.AsyncToolSpecification.builder()
 			.tool(tool)
 			.callHandler((exchange, request) -> Mono
-				.just(new CallToolResult(List.of(new TextContent("Test result")), false)))
+				.just(CallToolResult.builder().content(List.of(new TextContent("Test result"))).isError(false).build()))
 			.build();
 
 		assertThat(specification).isNotNull();
@@ -52,7 +52,8 @@ void builderShouldCreateValidAsyncToolSpecification() {
 	@Test
 	void builderShouldThrowExceptionWhenToolIsNull() {
 		assertThatThrownBy(() -> McpServerFeatures.AsyncToolSpecification.builder()
-			.callHandler((exchange, request) -> Mono.just(new CallToolResult(List.of(), false)))
+			.callHandler((exchange, request) -> Mono
+				.just(CallToolResult.builder().content(List.of()).isError(false).build()))
 			.build()).isInstanceOf(IllegalArgumentException.class).hasMessage("Tool must not be null");
 	}
 
@@ -80,7 +81,8 @@ void builderShouldAllowMethodChaining() {
 
 		// Then - verify method chaining returns the same builder instance
 		assertThat(builder.tool(tool)).isSameAs(builder);
-		assertThat(builder.callHandler((exchange, request) -> Mono.just(new CallToolResult(List.of(), false))))
+		assertThat(builder.callHandler(
+				(exchange, request) -> Mono.just(CallToolResult.builder().content(List.of()).isError(false).build())))
 			.isSameAs(builder);
 	}
 
@@ -96,7 +98,10 @@ void builtSpecificationShouldExecuteCallToolCorrectly() {
 		McpServerFeatures.AsyncToolSpecification specification = McpServerFeatures.AsyncToolSpecification.builder()
 			.tool(tool)
 			.callHandler((exchange, request) -> {
-				return Mono.just(new CallToolResult(List.of(new TextContent(expectedResult)), false));
+				return Mono.just(CallToolResult.builder()
+					.content(List.of(new TextContent(expectedResult)))
+					.isError(false)
+					.build());
 			})
 			.build();
 
@@ -124,8 +129,11 @@ void deprecatedConstructorShouldWorkCorrectly() {
 
 		// Test the deprecated constructor that takes a 'call' function
 		McpServerFeatures.AsyncToolSpecification specification = new McpServerFeatures.AsyncToolSpecification(tool,
-				(exchange, arguments) -> Mono
-					.just(new CallToolResult(List.of(new TextContent(expectedResult)), false)));
+				(exchange,
+						arguments) -> Mono.just(CallToolResult.builder()
+							.content(List.of(new TextContent(expectedResult)))
+							.isError(false)
+							.build()));
 
 		assertThat(specification).isNotNull();
 		assertThat(specification.tool()).isEqualTo(tool);
@@ -169,7 +177,10 @@ void fromSyncShouldConvertSyncToolSpecificationCorrectly() {
 		// Create a sync tool specification
 		McpServerFeatures.SyncToolSpecification syncSpec = McpServerFeatures.SyncToolSpecification.builder()
 			.tool(tool)
-			.callHandler((exchange, request) -> new CallToolResult(List.of(new TextContent(expectedResult)), false))
+			.callHandler((exchange, request) -> CallToolResult.builder()
+				.content(List.of(new TextContent(expectedResult)))
+				.isError(false)
+				.build())
 			.build();
 
 		// Convert to async using fromSync
@@ -209,7 +220,10 @@ void fromSyncShouldConvertSyncToolSpecificationWithDeprecatedCallCorrectly() {
 
 		// Create a sync tool specification using the deprecated constructor
 		McpServerFeatures.SyncToolSpecification syncSpec = new McpServerFeatures.SyncToolSpecification(tool,
-				(exchange, arguments) -> new CallToolResult(List.of(new TextContent(expectedResult)), false));
+				(exchange, arguments) -> CallToolResult.builder()
+					.content(List.of(new TextContent(expectedResult)))
+					.isError(false)
+					.build());
 
 		// Convert to async using fromSync
 		McpServerFeatures.AsyncToolSpecification asyncSpec = McpServerFeatures.AsyncToolSpecification
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 de74bafc1..491c2d4ed 100644
--- a/mcp-core/src/test/java/io/modelcontextprotocol/server/HttpServletStatelessIntegrationTests.java
+++ b/mcp-core/src/test/java/io/modelcontextprotocol/server/HttpServletStatelessIntegrationTests.java
@@ -114,7 +114,10 @@ void testToolCallSuccess(String clientType) {
 
 		var clientBuilder = clientBuilders.get(clientType);
 
-		var callResponse = new CallToolResult(List.of(new McpSchema.TextContent("CALL RESPONSE")), null);
+		var callResponse = CallToolResult.builder()
+			.content(List.of(new McpSchema.TextContent("CALL RESPONSE")))
+			.isError(false)
+			.build();
 		McpStatelessServerFeatures.SyncToolSpecification tool1 = new McpStatelessServerFeatures.SyncToolSpecification(
 				Tool.builder().name("tool1").title("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build(),
 				(transportContext, request) -> {
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 cd643c600..9bcd2bc84 100644
--- a/mcp-core/src/test/java/io/modelcontextprotocol/server/SyncToolSpecificationBuilderTest.java
+++ b/mcp-core/src/test/java/io/modelcontextprotocol/server/SyncToolSpecificationBuilderTest.java
@@ -32,7 +32,10 @@ void builderShouldCreateValidSyncToolSpecification() {
 
 		McpServerFeatures.SyncToolSpecification specification = McpServerFeatures.SyncToolSpecification.builder()
 			.tool(tool)
-			.callHandler((exchange, request) -> new CallToolResult(List.of(new TextContent("Test result")), false))
+			.callHandler((exchange, request) -> CallToolResult.builder()
+				.content(List.of(new TextContent("Test result")))
+				.isError(false)
+				.build())
 			.build();
 
 		assertThat(specification).isNotNull();
@@ -44,7 +47,7 @@ void builderShouldCreateValidSyncToolSpecification() {
 	@Test
 	void builderShouldThrowExceptionWhenToolIsNull() {
 		assertThatThrownBy(() -> McpServerFeatures.SyncToolSpecification.builder()
-			.callHandler((exchange, request) -> new CallToolResult(List.of(), false))
+			.callHandler((exchange, request) -> CallToolResult.builder().content(List.of()).isError(false).build())
 			.build()).isInstanceOf(IllegalArgumentException.class).hasMessage("Tool must not be null");
 	}
 
@@ -64,7 +67,9 @@ void builderShouldAllowMethodChaining() {
 
 		// Then - verify method chaining returns the same builder instance
 		assertThat(builder.tool(tool)).isSameAs(builder);
-		assertThat(builder.callHandler((exchange, request) -> new CallToolResult(List.of(), false))).isSameAs(builder);
+		assertThat(builder
+			.callHandler((exchange, request) -> CallToolResult.builder().content(List.of()).isError(false).build()))
+			.isSameAs(builder);
 	}
 
 	@Test
@@ -80,7 +85,10 @@ void builtSpecificationShouldExecuteCallToolCorrectly() {
 			.tool(tool)
 			.callHandler((exchange, request) -> {
 				// Simple test implementation
-				return new CallToolResult(List.of(new TextContent(expectedResult)), false);
+				return CallToolResult.builder()
+					.content(List.of(new TextContent(expectedResult)))
+					.isError(false)
+					.build();
 			})
 			.build();
 
diff --git a/mcp-test/src/main/java/io/modelcontextprotocol/AbstractMcpClientServerIntegrationTests.java b/mcp-test/src/main/java/io/modelcontextprotocol/AbstractMcpClientServerIntegrationTests.java
index 37a1ef31d..270bc4308 100644
--- a/mcp-test/src/main/java/io/modelcontextprotocol/AbstractMcpClientServerIntegrationTests.java
+++ b/mcp-test/src/main/java/io/modelcontextprotocol/AbstractMcpClientServerIntegrationTests.java
@@ -1081,7 +1081,10 @@ void testLoggingNotification(String clientType) throws InterruptedException {
 								.logger("test-logger")
 								.data("Another error message")
 								.build()))
-					.thenReturn(new CallToolResult("Logging test completed", false));
+					.thenReturn(CallToolResult.builder()
+						.content(List.of(new McpSchema.TextContent("Logging test completed")))
+						.isError(false)
+						.build());
 					//@formatter:on
 			})
 			.build();
@@ -1176,7 +1179,10 @@ void testProgressNotification(String clientType) throws InterruptedException {
 									0.0, 1.0, "Another processing started")))
 					.then(exchange.progressNotification(
 							new McpSchema.ProgressNotification(progressToken, 1.0, 1.0, "Processing completed")))
-					.thenReturn(new CallToolResult(("Progress test completed"), false));
+					.thenReturn(CallToolResult.builder()
+						.content(List.of(new McpSchema.TextContent("Progress test completed")))
+						.isError(false)
+						.build());
 			})
 			.build();
 
@@ -1330,7 +1336,10 @@ void testPingSuccess(String clientType) {
 					assertThat(result).isNotNull();
 				}).then(Mono.fromCallable(() -> {
 					executionOrder.set(executionOrder.get() + "3");
-					return new CallToolResult("Async ping test completed", false);
+					return CallToolResult.builder()
+						.content(List.of(new McpSchema.TextContent("Async ping test completed")))
+						.isError(false)
+						.build();
 				}));
 			})
 			.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 c24bcd622..d6677ec9a 100644
--- a/mcp-test/src/main/java/io/modelcontextprotocol/server/AbstractMcpAsyncServerTests.java
+++ b/mcp-test/src/main/java/io/modelcontextprotocol/server/AbstractMcpAsyncServerTests.java
@@ -7,7 +7,6 @@
 import java.time.Duration;
 import java.util.List;
 
-import io.modelcontextprotocol.spec.McpError;
 import io.modelcontextprotocol.spec.McpSchema;
 import io.modelcontextprotocol.spec.McpSchema.CallToolResult;
 import io.modelcontextprotocol.spec.McpSchema.GetPromptResult;
@@ -90,7 +89,7 @@ void testGracefulShutdown() {
 	void testImmediateClose() {
 		var mcpAsyncServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0").build();
 
-		assertThatCode(() -> mcpAsyncServer.close()).doesNotThrowAnyException();
+		assertThatCode(mcpAsyncServer::close).doesNotThrowAnyException();
 	}
 
 	// ---------------------------------------
@@ -108,8 +107,9 @@ void testAddTool() {
 			.capabilities(ServerCapabilities.builder().tools(true).build())
 			.build();
 
-		StepVerifier.create(mcpAsyncServer.addTool(new McpServerFeatures.AsyncToolSpecification(newTool,
-				(exchange, args) -> Mono.just(new CallToolResult(List.of(), false)))))
+		StepVerifier
+			.create(mcpAsyncServer.addTool(new McpServerFeatures.AsyncToolSpecification(newTool,
+					(exchange, args) -> Mono.just(CallToolResult.builder().content(List.of()).isError(false).build()))))
 			.verifyComplete();
 
 		assertThatCode(() -> mcpAsyncServer.closeGracefully().block(Duration.ofSeconds(10))).doesNotThrowAnyException();
@@ -129,7 +129,8 @@ void testAddToolCall() {
 
 		StepVerifier.create(mcpAsyncServer.addTool(McpServerFeatures.AsyncToolSpecification.builder()
 			.tool(newTool)
-			.callHandler((exchange, request) -> Mono.just(new CallToolResult(List.of(), false)))
+			.callHandler((exchange, request) -> Mono
+				.just(CallToolResult.builder().content(List.of()).isError(false).build()))
 			.build())).verifyComplete();
 
 		assertThatCode(() -> mcpAsyncServer.closeGracefully().block(Duration.ofSeconds(10))).doesNotThrowAnyException();
@@ -146,11 +147,13 @@ void testAddDuplicateTool() {
 
 		var mcpAsyncServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0")
 			.capabilities(ServerCapabilities.builder().tools(true).build())
-			.tool(duplicateTool, (exchange, args) -> Mono.just(new CallToolResult(List.of(), false)))
+			.tool(duplicateTool,
+					(exchange, args) -> Mono.just(CallToolResult.builder().content(List.of()).isError(false).build()))
 			.build();
 
-		StepVerifier.create(mcpAsyncServer.addTool(new McpServerFeatures.AsyncToolSpecification(duplicateTool,
-				(exchange, args) -> Mono.just(new CallToolResult(List.of(), false)))))
+		StepVerifier
+			.create(mcpAsyncServer.addTool(new McpServerFeatures.AsyncToolSpecification(duplicateTool,
+					(exchange, args) -> Mono.just(CallToolResult.builder().content(List.of()).isError(false).build()))))
 			.verifyComplete();
 
 		assertThatCode(() -> mcpAsyncServer.closeGracefully().block(Duration.ofSeconds(10))).doesNotThrowAnyException();
@@ -166,12 +169,15 @@ void testAddDuplicateToolCall() {
 
 		var mcpAsyncServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0")
 			.capabilities(ServerCapabilities.builder().tools(true).build())
-			.toolCall(duplicateTool, (exchange, request) -> Mono.just(new CallToolResult(List.of(), false)))
+			.toolCall(duplicateTool,
+					(exchange, request) -> Mono
+						.just(CallToolResult.builder().content(List.of()).isError(false).build()))
 			.build();
 
 		StepVerifier.create(mcpAsyncServer.addTool(McpServerFeatures.AsyncToolSpecification.builder()
 			.tool(duplicateTool)
-			.callHandler((exchange, request) -> Mono.just(new CallToolResult(List.of(), false)))
+			.callHandler((exchange, request) -> Mono
+				.just(CallToolResult.builder().content(List.of()).isError(false).build()))
 			.build())).verifyComplete();
 
 		assertThatCode(() -> mcpAsyncServer.closeGracefully().block(Duration.ofSeconds(10))).doesNotThrowAnyException();
@@ -187,8 +193,12 @@ void testDuplicateToolCallDuringBuilding() {
 
 		assertThatThrownBy(() -> prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0")
 			.capabilities(ServerCapabilities.builder().tools(true).build())
-			.toolCall(duplicateTool, (exchange, request) -> Mono.just(new CallToolResult(List.of(), false)))
-			.toolCall(duplicateTool, (exchange, request) -> Mono.just(new CallToolResult(List.of(), false))) // Duplicate!
+			.toolCall(duplicateTool,
+					(exchange, request) -> Mono
+						.just(CallToolResult.builder().content(List.of()).isError(false).build()))
+			.toolCall(duplicateTool,
+					(exchange, request) -> Mono
+						.just(CallToolResult.builder().content(List.of()).isError(false).build())) // Duplicate!
 			.build()).isInstanceOf(IllegalArgumentException.class)
 			.hasMessage("Tool with name 'duplicate-build-toolcall' is already registered.");
 	}
@@ -204,11 +214,13 @@ void testDuplicateToolsInBatchListRegistration() {
 		List specs = List.of(
 				McpServerFeatures.AsyncToolSpecification.builder()
 					.tool(duplicateTool)
-					.callHandler((exchange, request) -> Mono.just(new CallToolResult(List.of(), false)))
+					.callHandler((exchange, request) -> Mono
+						.just(CallToolResult.builder().content(List.of()).isError(false).build()))
 					.build(),
 				McpServerFeatures.AsyncToolSpecification.builder()
 					.tool(duplicateTool)
-					.callHandler((exchange, request) -> Mono.just(new CallToolResult(List.of(), false)))
+					.callHandler((exchange, request) -> Mono
+						.just(CallToolResult.builder().content(List.of()).isError(false).build()))
 					.build() // Duplicate!
 		);
 
@@ -231,11 +243,13 @@ void testDuplicateToolsInBatchVarargsRegistration() {
 			.capabilities(ServerCapabilities.builder().tools(true).build())
 			.tools(McpServerFeatures.AsyncToolSpecification.builder()
 				.tool(duplicateTool)
-				.callHandler((exchange, request) -> Mono.just(new CallToolResult(List.of(), false)))
+				.callHandler((exchange, request) -> Mono
+					.just(CallToolResult.builder().content(List.of()).isError(false).build()))
 				.build(),
 					McpServerFeatures.AsyncToolSpecification.builder()
 						.tool(duplicateTool)
-						.callHandler((exchange, request) -> Mono.just(new CallToolResult(List.of(), false)))
+						.callHandler((exchange, request) -> Mono
+							.just(CallToolResult.builder().content(List.of()).isError(false).build()))
 						.build() // Duplicate!
 			)
 			.build()).isInstanceOf(IllegalArgumentException.class)
@@ -252,7 +266,9 @@ void testRemoveTool() {
 
 		var mcpAsyncServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0")
 			.capabilities(ServerCapabilities.builder().tools(true).build())
-			.toolCall(too, (exchange, request) -> Mono.just(new CallToolResult(List.of(), false)))
+			.toolCall(too,
+					(exchange, request) -> Mono
+						.just(CallToolResult.builder().content(List.of()).isError(false).build()))
 			.build();
 
 		StepVerifier.create(mcpAsyncServer.removeTool(TEST_TOOL_NAME)).verifyComplete();
@@ -281,7 +297,8 @@ void testNotifyToolsListChanged() {
 
 		var mcpAsyncServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0")
 			.capabilities(ServerCapabilities.builder().tools(true).build())
-			.toolCall(too, (exchange, args) -> Mono.just(new CallToolResult(List.of(), false)))
+			.toolCall(too,
+					(exchange, args) -> Mono.just(CallToolResult.builder().content(List.of()).isError(false).build()))
 			.build();
 
 		StepVerifier.create(mcpAsyncServer.notifyToolsListChanged()).verifyComplete();
@@ -320,8 +337,13 @@ void testAddResource() {
 			.capabilities(ServerCapabilities.builder().resources(true, false).build())
 			.build();
 
-		Resource resource = new Resource(TEST_RESOURCE_URI, "Test Resource", "text/plain", "Test resource description",
-				null);
+		Resource resource = Resource.builder()
+			.uri(TEST_RESOURCE_URI)
+			.name("Test Resource")
+			.title("Test Resource")
+			.mimeType("text/plain")
+			.description("Test resource description")
+			.build();
 		McpServerFeatures.AsyncResourceSpecification specification = new McpServerFeatures.AsyncResourceSpecification(
 				resource, (exchange, req) -> Mono.just(new ReadResourceResult(List.of())));
 
@@ -349,8 +371,13 @@ void testAddResourceWithoutCapability() {
 		// Create a server without resource capabilities
 		McpAsyncServer serverWithoutResources = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0").build();
 
-		Resource resource = new Resource(TEST_RESOURCE_URI, "Test Resource", "text/plain", "Test resource description",
-				null);
+		Resource resource = Resource.builder()
+			.uri(TEST_RESOURCE_URI)
+			.name("Test Resource")
+			.title("Test Resource")
+			.mimeType("text/plain")
+			.description("Test resource description")
+			.build();
 		McpServerFeatures.AsyncResourceSpecification specification = new McpServerFeatures.AsyncResourceSpecification(
 				resource, (exchange, req) -> Mono.just(new ReadResourceResult(List.of())));
 
@@ -377,8 +404,13 @@ void testListResources() {
 			.capabilities(ServerCapabilities.builder().resources(true, false).build())
 			.build();
 
-		Resource resource = new Resource(TEST_RESOURCE_URI, "Test Resource", "text/plain", "Test resource description",
-				null);
+		Resource resource = Resource.builder()
+			.uri(TEST_RESOURCE_URI)
+			.name("Test Resource")
+			.title("Test Resource")
+			.mimeType("text/plain")
+			.description("Test resource description")
+			.build();
 		McpServerFeatures.AsyncResourceSpecification specification = new McpServerFeatures.AsyncResourceSpecification(
 				resource, (exchange, req) -> Mono.just(new ReadResourceResult(List.of())));
 
@@ -396,8 +428,13 @@ void testRemoveResource() {
 			.capabilities(ServerCapabilities.builder().resources(true, false).build())
 			.build();
 
-		Resource resource = new Resource(TEST_RESOURCE_URI, "Test Resource", "text/plain", "Test resource description",
-				null);
+		Resource resource = Resource.builder()
+			.uri(TEST_RESOURCE_URI)
+			.name("Test Resource")
+			.title("Test Resource")
+			.mimeType("text/plain")
+			.description("Test resource description")
+			.build();
 		McpServerFeatures.AsyncResourceSpecification specification = new McpServerFeatures.AsyncResourceSpecification(
 				resource, (exchange, req) -> Mono.just(new ReadResourceResult(List.of())));
 
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 591f750cb..0a59d0aae 100644
--- a/mcp-test/src/main/java/io/modelcontextprotocol/server/AbstractMcpSyncServerTests.java
+++ b/mcp-test/src/main/java/io/modelcontextprotocol/server/AbstractMcpSyncServerTests.java
@@ -6,7 +6,6 @@
 
 import java.util.List;
 
-import io.modelcontextprotocol.spec.McpError;
 import io.modelcontextprotocol.spec.McpSchema;
 import io.modelcontextprotocol.spec.McpSchema.CallToolResult;
 import io.modelcontextprotocol.spec.McpSchema.GetPromptResult;
@@ -77,14 +76,14 @@ void testConstructorWithInvalidArguments() {
 	void testGracefulShutdown() {
 		var mcpSyncServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0").build();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
 	void testImmediateClose() {
 		var mcpSyncServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0").build();
 
-		assertThatCode(() -> mcpSyncServer.close()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::close).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -93,7 +92,7 @@ void testGetAsyncServer() {
 
 		assertThat(mcpSyncServer.getAsyncServer()).isNotNull();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	// ---------------------------------------
@@ -113,10 +112,10 @@ void testAddTool() {
 			.inputSchema(EMPTY_JSON_SCHEMA)
 			.build();
 		assertThatCode(() -> mcpSyncServer.addTool(new McpServerFeatures.SyncToolSpecification(newTool,
-				(exchange, args) -> new CallToolResult(List.of(), false))))
+				(exchange, args) -> CallToolResult.builder().content(List.of()).isError(false).build())))
 			.doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -133,10 +132,10 @@ void testAddToolCall() {
 
 		assertThatCode(() -> mcpSyncServer.addTool(McpServerFeatures.SyncToolSpecification.builder()
 			.tool(newTool)
-			.callHandler((exchange, request) -> new CallToolResult(List.of(), false))
+			.callHandler((exchange, request) -> CallToolResult.builder().content(List.of()).isError(false).build())
 			.build())).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -150,14 +149,14 @@ void testAddDuplicateTool() {
 
 		var mcpSyncServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0")
 			.capabilities(ServerCapabilities.builder().tools(true).build())
-			.tool(duplicateTool, (exchange, args) -> new CallToolResult(List.of(), false))
+			.tool(duplicateTool, (exchange, args) -> CallToolResult.builder().content(List.of()).isError(false).build())
 			.build();
 
 		assertThatCode(() -> mcpSyncServer.addTool(new McpServerFeatures.SyncToolSpecification(duplicateTool,
-				(exchange, args) -> new CallToolResult(List.of(), false))))
+				(exchange, args) -> CallToolResult.builder().content(List.of()).isError(false).build())))
 			.doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -170,15 +169,16 @@ void testAddDuplicateToolCall() {
 
 		var mcpSyncServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0")
 			.capabilities(ServerCapabilities.builder().tools(true).build())
-			.toolCall(duplicateTool, (exchange, request) -> new CallToolResult(List.of(), false))
+			.toolCall(duplicateTool,
+					(exchange, request) -> CallToolResult.builder().content(List.of()).isError(false).build())
 			.build();
 
 		assertThatCode(() -> mcpSyncServer.addTool(McpServerFeatures.SyncToolSpecification.builder()
 			.tool(duplicateTool)
-			.callHandler((exchange, request) -> new CallToolResult(List.of(), false))
+			.callHandler((exchange, request) -> CallToolResult.builder().content(List.of()).isError(false).build())
 			.build())).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -191,8 +191,10 @@ void testDuplicateToolCallDuringBuilding() {
 
 		assertThatThrownBy(() -> prepareSyncServerBuilder().serverInfo("test-server", "1.0.0")
 			.capabilities(ServerCapabilities.builder().tools(true).build())
-			.toolCall(duplicateTool, (exchange, request) -> new CallToolResult(List.of(), false))
-			.toolCall(duplicateTool, (exchange, request) -> new CallToolResult(List.of(), false)) // Duplicate!
+			.toolCall(duplicateTool,
+					(exchange, request) -> CallToolResult.builder().content(List.of()).isError(false).build())
+			.toolCall(duplicateTool,
+					(exchange, request) -> CallToolResult.builder().content(List.of()).isError(false).build()) // Duplicate!
 			.build()).isInstanceOf(IllegalArgumentException.class)
 			.hasMessage("Tool with name 'duplicate-build-toolcall' is already registered.");
 	}
@@ -207,11 +209,13 @@ void testDuplicateToolsInBatchListRegistration() {
 		List specs = List.of(
 				McpServerFeatures.SyncToolSpecification.builder()
 					.tool(duplicateTool)
-					.callHandler((exchange, request) -> new CallToolResult(List.of(), false))
+					.callHandler(
+							(exchange, request) -> CallToolResult.builder().content(List.of()).isError(false).build())
 					.build(),
 				McpServerFeatures.SyncToolSpecification.builder()
 					.tool(duplicateTool)
-					.callHandler((exchange, request) -> new CallToolResult(List.of(), false))
+					.callHandler(
+							(exchange, request) -> CallToolResult.builder().content(List.of()).isError(false).build())
 					.build() // Duplicate!
 		);
 
@@ -234,11 +238,12 @@ void testDuplicateToolsInBatchVarargsRegistration() {
 			.capabilities(ServerCapabilities.builder().tools(true).build())
 			.tools(McpServerFeatures.SyncToolSpecification.builder()
 				.tool(duplicateTool)
-				.callHandler((exchange, request) -> new CallToolResult(List.of(), false))
+				.callHandler((exchange, request) -> CallToolResult.builder().content(List.of()).isError(false).build())
 				.build(),
 					McpServerFeatures.SyncToolSpecification.builder()
 						.tool(duplicateTool)
-						.callHandler((exchange, request) -> new CallToolResult(List.of(), false))
+						.callHandler((exchange,
+								request) -> CallToolResult.builder().content(List.of()).isError(false).build())
 						.build() // Duplicate!
 			)
 			.build()).isInstanceOf(IllegalArgumentException.class)
@@ -255,12 +260,12 @@ void testRemoveTool() {
 
 		var mcpSyncServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0")
 			.capabilities(ServerCapabilities.builder().tools(true).build())
-			.toolCall(tool, (exchange, args) -> new CallToolResult(List.of(), false))
+			.toolCall(tool, (exchange, args) -> CallToolResult.builder().content(List.of()).isError(false).build())
 			.build();
 
 		assertThatCode(() -> mcpSyncServer.removeTool(TEST_TOOL_NAME)).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -271,16 +276,16 @@ void testRemoveNonexistentTool() {
 
 		assertThatCode(() -> mcpSyncServer.removeTool("nonexistent-tool")).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
 	void testNotifyToolsListChanged() {
 		var mcpSyncServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0").build();
 
-		assertThatCode(() -> mcpSyncServer.notifyToolsListChanged()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::notifyToolsListChanged).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	// ---------------------------------------
@@ -291,9 +296,9 @@ void testNotifyToolsListChanged() {
 	void testNotifyResourcesListChanged() {
 		var mcpSyncServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0").build();
 
-		assertThatCode(() -> mcpSyncServer.notifyResourcesListChanged()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::notifyResourcesListChanged).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -304,7 +309,7 @@ void testNotifyResourcesUpdated() {
 			.notifyResourcesUpdated(new McpSchema.ResourcesUpdatedNotification(TEST_RESOURCE_URI)))
 			.doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -313,14 +318,19 @@ void testAddResource() {
 			.capabilities(ServerCapabilities.builder().resources(true, false).build())
 			.build();
 
-		Resource resource = new Resource(TEST_RESOURCE_URI, "Test Resource", "text/plain", "Test resource description",
-				null);
+		Resource resource = Resource.builder()
+			.uri(TEST_RESOURCE_URI)
+			.name("Test Resource")
+			.title("Test Resource")
+			.mimeType("text/plain")
+			.description("Test resource description")
+			.build();
 		McpServerFeatures.SyncResourceSpecification specification = new McpServerFeatures.SyncResourceSpecification(
 				resource, (exchange, req) -> new ReadResourceResult(List.of()));
 
 		assertThatCode(() -> mcpSyncServer.addResource(specification)).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -333,15 +343,20 @@ void testAddResourceWithNullSpecification() {
 			.isInstanceOf(IllegalArgumentException.class)
 			.hasMessage("Resource must not be null");
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
 	void testAddResourceWithoutCapability() {
 		var serverWithoutResources = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0").build();
 
-		Resource resource = new Resource(TEST_RESOURCE_URI, "Test Resource", "text/plain", "Test resource description",
-				null);
+		Resource resource = Resource.builder()
+			.uri(TEST_RESOURCE_URI)
+			.name("Test Resource")
+			.title("Test Resource")
+			.mimeType("text/plain")
+			.description("Test resource description")
+			.build();
 		McpServerFeatures.SyncResourceSpecification specification = new McpServerFeatures.SyncResourceSpecification(
 				resource, (exchange, req) -> new ReadResourceResult(List.of()));
 
@@ -365,8 +380,13 @@ void testListResources() {
 			.capabilities(ServerCapabilities.builder().resources(true, false).build())
 			.build();
 
-		Resource resource = new Resource(TEST_RESOURCE_URI, "Test Resource", "text/plain", "Test resource description",
-				null);
+		Resource resource = Resource.builder()
+			.uri(TEST_RESOURCE_URI)
+			.name("Test Resource")
+			.title("Test Resource")
+			.mimeType("text/plain")
+			.description("Test resource description")
+			.build();
 		McpServerFeatures.SyncResourceSpecification specification = new McpServerFeatures.SyncResourceSpecification(
 				resource, (exchange, req) -> new ReadResourceResult(List.of()));
 
@@ -376,7 +396,7 @@ void testListResources() {
 		assertThat(resources).hasSize(1);
 		assertThat(resources.get(0).uri()).isEqualTo(TEST_RESOURCE_URI);
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -385,15 +405,20 @@ void testRemoveResource() {
 			.capabilities(ServerCapabilities.builder().resources(true, false).build())
 			.build();
 
-		Resource resource = new Resource(TEST_RESOURCE_URI, "Test Resource", "text/plain", "Test resource description",
-				null);
+		Resource resource = Resource.builder()
+			.uri(TEST_RESOURCE_URI)
+			.name("Test Resource")
+			.title("Test Resource")
+			.mimeType("text/plain")
+			.description("Test resource description")
+			.build();
 		McpServerFeatures.SyncResourceSpecification specification = new McpServerFeatures.SyncResourceSpecification(
 				resource, (exchange, req) -> new ReadResourceResult(List.of()));
 
 		mcpSyncServer.addResource(specification);
 		assertThatCode(() -> mcpSyncServer.removeResource(TEST_RESOURCE_URI)).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -406,7 +431,7 @@ void testRemoveNonexistentResource() {
 		// as per the new implementation that just logs a warning
 		assertThatCode(() -> mcpSyncServer.removeResource("nonexistent://resource")).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	// ---------------------------------------
@@ -431,7 +456,7 @@ void testAddResourceTemplate() {
 
 		assertThatCode(() -> mcpSyncServer.addResourceTemplate(specification)).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -473,7 +498,7 @@ void testRemoveResourceTemplate() {
 
 		assertThatCode(() -> mcpSyncServer.removeResourceTemplate("test://template/{id}")).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -495,7 +520,7 @@ void testRemoveNonexistentResourceTemplate() {
 		assertThatCode(() -> mcpSyncServer.removeResourceTemplate("nonexistent://template/{id}"))
 			.doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -519,7 +544,7 @@ void testListResourceTemplates() {
 
 		assertThat(templates).isNotNull();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	// ---------------------------------------
@@ -530,9 +555,9 @@ void testListResourceTemplates() {
 	void testNotifyPromptsListChanged() {
 		var mcpSyncServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0").build();
 
-		assertThatCode(() -> mcpSyncServer.notifyPromptsListChanged()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::notifyPromptsListChanged).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -583,7 +608,7 @@ void testRemovePrompt() {
 
 		assertThatCode(() -> mcpSyncServer.removePrompt(TEST_PROMPT_NAME)).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	@Test
@@ -594,7 +619,7 @@ void testRemoveNonexistentPrompt() {
 
 		assertThatCode(() -> mcpSyncServer.removePrompt("nonexistent://template/{id}")).doesNotThrowAnyException();
 
-		assertThatCode(() -> mcpSyncServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(mcpSyncServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 	// ---------------------------------------
@@ -616,7 +641,7 @@ void testRootsChangeHandlers() {
 			}))
 			.build();
 		assertThat(singleConsumerServer).isNotNull();
-		assertThatCode(() -> singleConsumerServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(singleConsumerServer::closeGracefully).doesNotThrowAnyException();
 		onClose();
 
 		// Test with multiple consumers
@@ -632,7 +657,7 @@ void testRootsChangeHandlers() {
 			.build();
 
 		assertThat(multipleConsumersServer).isNotNull();
-		assertThatCode(() -> multipleConsumersServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(multipleConsumersServer::closeGracefully).doesNotThrowAnyException();
 		onClose();
 
 		// Test error handling
@@ -643,14 +668,14 @@ void testRootsChangeHandlers() {
 			.build();
 
 		assertThat(errorHandlingServer).isNotNull();
-		assertThatCode(() -> errorHandlingServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(errorHandlingServer::closeGracefully).doesNotThrowAnyException();
 		onClose();
 
 		// Test without consumers
 		var noConsumersServer = prepareSyncServerBuilder().serverInfo("test-server", "1.0.0").build();
 
 		assertThat(noConsumersServer).isNotNull();
-		assertThatCode(() -> noConsumersServer.closeGracefully()).doesNotThrowAnyException();
+		assertThatCode(noConsumersServer::closeGracefully).doesNotThrowAnyException();
 	}
 
 }