diff --git a/mcp/README.md b/mcp/README.md index f0bf8a9..4c9c641 100644 --- a/mcp/README.md +++ b/mcp/README.md @@ -1,6 +1,6 @@ -# Spring AI MCP SDK +# Java MCP SDK -This SDK implements the Model Context Protocol, enabling seamless integration with language models and AI tools. +Java SDK implementation of the Model Context Protocol, enabling seamless integration with language models and AI tools. ## Features diff --git a/mcp/pom.xml b/mcp/pom.xml index c5c2d54..6bb5e13 100644 --- a/mcp/pom.xml +++ b/mcp/pom.xml @@ -11,7 +11,7 @@ mcp jar Java MCP SDK - Core Java implementation of the Model Context Protocol (MCP) specification, providing synchronous and asynchronous clients, server implementations (coming in 0.3.0), with support for tool discovery, resource management, and multiple transport implementations + Java SDK implementation of the Model Context Protocol, enabling seamless integration with language models and AI tools https://github.com/spring-projects-experimental/spring-ai-mcp diff --git a/mcp/src/main/java/org/springframework/ai/mcp/client/McpClient.java b/mcp/src/main/java/org/springframework/ai/mcp/client/McpClient.java index 3c4663a..9f49924 100644 --- a/mcp/src/main/java/org/springframework/ai/mcp/client/McpClient.java +++ b/mcp/src/main/java/org/springframework/ai/mcp/client/McpClient.java @@ -34,42 +34,90 @@ import org.springframework.ai.mcp.spec.McpTransport; import org.springframework.ai.mcp.util.Assert; /** - * Factory class providing static methods for creating Model Context Protocol (MCP) - * clients. This class serves as the main entry point for establishing connections with - * MCP servers, offering both synchronous and asynchronous client implementations. - * - *

- * The class provides factory methods to create either: + * Factory class for creating Model Context Protocol (MCP) clients. MCP is a protocol that enables + * AI models to interact with external tools and resources through a standardized interface. + * + *

This class serves as the main entry point for establishing connections with MCP servers, + * implementing the client-side of the MCP specification. The protocol follows a client-server + * architecture where: *

* - *

- * Use the builder pattern for flexible client configuration: + *

The class provides factory methods to create either: + *

* + *

Example of creating a basic client: *

{@code
  * McpClient.using(transport)
- * 		.requestTimeout(Duration.ofSeconds(5))
- * 		.sync(); // or .async()
+ *     .requestTimeout(Duration.ofSeconds(5))
+ *     .sync(); // or .async()
  * }
* + *

Example with advanced configuration: + *

{@code
+ * McpClient.using(transport)
+ *     .requestTimeout(Duration.ofSeconds(10))
+ *     .capabilities(new ClientCapabilities(...))
+ *     .clientInfo(new Implementation("My Client", "1.0.0"))
+ *     .roots(new Root("file://workspace", "Workspace Files"))
+ *     .toolsChangeConsumer(tools -> System.out.println("Tools updated: " + tools))
+ *     .async();
+ * }
+ * + *

The client supports: + *

+ * * @author Christian Tzolov * @author Dariusz Jędrzejczyk + * @see McpAsyncClient + * @see McpSyncClient + * @see McpTransport */ public interface McpClient { /** - * Start building an MCP client with the specified transport. - * @param transport The transport layer implementation for MCP communication - * @return A new builder instance + * Start building an MCP client with the specified transport layer. + * The transport layer handles the low-level communication between + * client and server using protocols like stdio or Server-Sent Events (SSE). + * + * @param transport The transport layer implementation for MCP communication. + * Common implementations include {@code StdioClientTransport} + * for stdio-based communication and {@code SseClientTransport} + * for SSE-based communication. + * @return A new builder instance for configuring the client + * @throws IllegalArgumentException if transport is null */ public static Builder using(McpTransport transport) { return new Builder(transport); } /** - * Builder class for creating MCP clients with custom configuration. + * Builder class for creating and configuring MCP clients. This class follows + * the builder pattern to provide a fluent API for setting up clients with + * custom configurations. + * + *

The builder supports configuration of: + *

*/ public static class Builder { @@ -79,7 +127,7 @@ public interface McpClient { private ClientCapabilities capabilities; - private Implementation clientInfo = new Implementation("Spring AI MCP Client", "0.3.0"); + private Implementation clientInfo = new Implementation("Spring AI MCP Client", "0.3.1"); private Map roots = new HashMap<>(); @@ -97,9 +145,14 @@ public interface McpClient { } /** - * Set the request timeout duration. - * @param requestTimeout The duration to wait before timing out requests - * @return This builder instance + * Sets the duration to wait for server responses before timing out requests. + * This timeout applies to all requests made through the client, including + * tool calls, resource access, and prompt operations. + * + * @param requestTimeout The duration to wait before timing out requests. + * Must not be null. + * @return This builder instance for method chaining + * @throws IllegalArgumentException if requestTimeout is null */ public Builder requestTimeout(Duration requestTimeout) { Assert.notNull(requestTimeout, "Request timeout must not be null"); @@ -107,18 +160,46 @@ public interface McpClient { return this; } + /** + * Sets the client capabilities that will be advertised to the server during + * connection initialization. Capabilities define what features the client supports, + * such as tool execution, resource access, and prompt handling. + * + * @param capabilities The client capabilities configuration. Must not be null. + * @return This builder instance for method chaining + * @throws IllegalArgumentException if capabilities is null + */ public Builder capabilities(ClientCapabilities capabilities) { Assert.notNull(capabilities, "Capabilities must not be null"); this.capabilities = capabilities; return this; } + /** + * Sets the client implementation information that will be shared with the server + * during connection initialization. This helps with version compatibility and + * debugging. + * + * @param clientInfo The client implementation details including name and version. + * Must not be null. + * @return This builder instance for method chaining + * @throws IllegalArgumentException if clientInfo is null + */ public Builder clientInfo(Implementation clientInfo) { Assert.notNull(clientInfo, "Client info must not be null"); this.clientInfo = clientInfo; return this; } + /** + * Sets the root URIs that this client can access. Roots define the base URIs + * for resources that the client can request from the server. For example, + * a root might be "file://workspace" for accessing workspace files. + * + * @param roots A list of root definitions. Must not be null. + * @return This builder instance for method chaining + * @throws IllegalArgumentException if roots is null + */ public Builder roots(List roots) { Assert.notNull(roots, "Roots must not be null"); for (Root root : roots) { @@ -127,6 +208,15 @@ public interface McpClient { return this; } + /** + * Sets the root URIs that this client can access, using a varargs parameter + * for convenience. This is an alternative to {@link #roots(List)}. + * + * @param roots An array of root definitions. Must not be null. + * @return This builder instance for method chaining + * @throws IllegalArgumentException if roots is null + * @see #roots(List) + */ public Builder roots(Root... roots) { Assert.notNull(roots, "Roots must not be null"); for (Root root : roots) { @@ -135,24 +225,64 @@ public interface McpClient { return this; } + /** + * Sets a custom sampling handler for processing message creation requests. + * The sampling handler can modify or validate messages before they are sent + * to the server, enabling custom processing logic. + * + * @param samplingHandler A function that processes message requests and returns + * results. Must not be null. + * @return This builder instance for method chaining + * @throws IllegalArgumentException if samplingHandler is null + */ public Builder sampling(Function samplingHandler) { Assert.notNull(samplingHandler, "Sampling handler must not be null"); this.samplingHandler = samplingHandler; return this; } + /** + * Adds a consumer to be notified when the available tools change. This allows + * the client to react to changes in the server's tool capabilities, such as + * tools being added or removed. + * + * @param toolsChangeConsumer A consumer that receives the updated list of + * available tools. Must not be null. + * @return This builder instance for method chaining + * @throws IllegalArgumentException if toolsChangeConsumer is null + */ public Builder toolsChangeConsumer(Consumer> toolsChangeConsumer) { Assert.notNull(toolsChangeConsumer, "Tools change consumer must not be null"); this.toolsChangeConsumers.add(toolsChangeConsumer); return this; } + /** + * Adds a consumer to be notified when the available resources change. This allows + * the client to react to changes in the server's resource availability, such as + * files being added or removed. + * + * @param resourcesChangeConsumer A consumer that receives the updated list of + * available resources. Must not be null. + * @return This builder instance for method chaining + * @throws IllegalArgumentException if resourcesChangeConsumer is null + */ public Builder resourcesChangeConsumer(Consumer> resourcesChangeConsumer) { Assert.notNull(resourcesChangeConsumer, "Resources change consumer must not be null"); this.resourcesChangeConsumers.add(resourcesChangeConsumer); return this; } + /** + * Adds a consumer to be notified when the available prompts change. This allows + * the client to react to changes in the server's prompt templates, such as + * new templates being added or existing ones being modified. + * + * @param promptsChangeConsumer A consumer that receives the updated list of + * available prompts. Must not be null. + * @return This builder instance for method chaining + * @throws IllegalArgumentException if promptsChangeConsumer is null + */ public Builder promptsChangeConsumer(Consumer> promptsChangeConsumer) { Assert.notNull(promptsChangeConsumer, "Prompts change consumer must not be null"); this.promptsChangeConsumers.add(promptsChangeConsumer); @@ -160,16 +290,25 @@ public interface McpClient { } /** - * Build a synchronous MCP client. - * @return A new instance of {@link McpSyncClient} + * Builds a synchronous MCP client that provides blocking operations. + * Synchronous clients wait for each operation to complete before returning, + * making them simpler to use but potentially less performant for + * concurrent operations. + * + * @return A new instance of {@link McpSyncClient} configured with this + * builder's settings */ public McpSyncClient sync() { return new McpSyncClient(async()); } /** - * Build an asynchronous MCP client. - * @return A new instance of {@link McpAsyncClient} + * Builds an asynchronous MCP client that provides non-blocking operations. + * Asynchronous clients return CompletableFuture objects immediately, + * allowing for concurrent operations and reactive programming patterns. + * + * @return A new instance of {@link McpAsyncClient} configured with this + * builder's settings */ public McpAsyncClient async() { return new McpAsyncClient(transport, requestTimeout, clientInfo, capabilities, roots, toolsChangeConsumers, diff --git a/mcp/src/main/java/org/springframework/ai/mcp/server/McpServer.java b/mcp/src/main/java/org/springframework/ai/mcp/server/McpServer.java index cbabff4..4cc051c 100644 --- a/mcp/src/main/java/org/springframework/ai/mcp/server/McpServer.java +++ b/mcp/src/main/java/org/springframework/ai/mcp/server/McpServer.java @@ -30,49 +30,162 @@ import org.springframework.ai.mcp.spec.McpTransport; import org.springframework.ai.mcp.util.Assert; /** - * Factory class providing static methods for creating Model Context Protocol (MCP) - * servers. This class serves as the main entry point for establishing MCP servers, - * offering both synchronous and asynchronous server implementations. + * Factory class for creating Model Context Protocol (MCP) servers. MCP servers expose + * tools, resources, and prompts to AI models through a standardized interface. * - *

- * The class provides factory methods to create either: + *

This class serves as the main entry point for implementing the server-side of + * the MCP specification. The server's responsibilities include: *

    - *
  • {@link McpAsyncServer} for non-blocking operations - *
  • {@link McpSyncServer} for blocking operations + *
  • Exposing tools that models can invoke to perform actions + *
  • Providing access to resources that give models context + *
  • Managing prompt templates for structured model interactions + *
  • Handling client connections and requests + *
  • Implementing capability negotiation *
* - *

- * Use the builder pattern for flexible server configuration: + *

The class provides factory methods to create either: + *

    + *
  • {@link McpAsyncServer} for non-blocking operations with CompletableFuture responses + *
  • {@link McpSyncServer} for blocking operations with direct responses + *
* + *

Example of creating a basic server: *

{@code
  * McpServer.using(transport)
- * 		.serverInfo(new McpSchema.Implementation("my-server", "1.0.0"))
- * 		.tool(new MyToolHandler())
- * 		.async(); // or .sync()
+ *     .info("my-server", "1.0.0")
+ *     .tool(new Tool("calculator", "Performs calculations", schema),
+ *           args -> new CallToolResult("Result: " + calculate(args)))
+ *     .sync(); // or .async()
+ * }
+ * + *

Example with comprehensive configuration: + *

{@code
+ * McpServer.using(transport)
+ *     .info("advanced-server", "2.0.0")
+ *     .capabilities(new ServerCapabilities(...))
+ *     // Register tools
+ *     .tools(
+ *         new ToolRegistration(calculatorTool, calculatorHandler),
+ *         new ToolRegistration(weatherTool, weatherHandler)
+ *     )
+ *     // Register resources
+ *     .resources(
+ *         new ResourceRegistration(fileResource, fileHandler),
+ *         new ResourceRegistration(dbResource, dbHandler)
+ *     )
+ *     // Add resource templates
+ *     .resourceTemplates(
+ *         new ResourceTemplate("file://{path}", "Access files"),
+ *         new ResourceTemplate("db://{table}", "Access database")
+ *     )
+ *     // Register prompts
+ *     .prompts(
+ *         new PromptRegistration(analysisPrompt, analysisHandler),
+ *         new PromptRegistration(summaryPrompt, summaryHandler)
+ *     )
+ *     .async();
  * }
* * @author Christian Tzolov + * @see McpAsyncServer + * @see McpSyncServer + * @see McpTransport */ public interface McpServer { /** - * Registration of a tool with its handler function. MCP allows servers to expose - * tools that can be invoked by language models. Tools enable models to interact with - * external systems, such as querying databases, calling APIs, or performing - * computations. Each tool is uniquely identified by a name and includes metadata - * describing its schema. + * Registration of a tool with its handler function. Tools are the primary way for + * MCP servers to expose functionality to AI models. Each tool represents a specific + * capability, such as: + *
    + *
  • Performing calculations + *
  • Accessing external APIs + *
  • Querying databases + *
  • Manipulating files + *
  • Executing system commands + *
* - * @param tool The tool definition - * @param call The function to handle tool execution + *

Example tool registration: + *

{@code
+	 * new ToolRegistration(
+	 *     new Tool(
+	 *         "calculator",
+	 *         "Performs mathematical calculations",
+	 *         new JsonSchemaObject()
+	 *             .required("expression")
+	 *             .property("expression", JsonSchemaType.STRING)
+	 *     ),
+	 *     args -> {
+	 *         String expr = (String) args.get("expression");
+	 *         return new CallToolResult("Result: " + evaluate(expr));
+	 *     }
+	 * )
+	 * }
+ * + * @param tool The tool definition including name, description, and parameter schema + * @param call The function that implements the tool's logic, receiving arguments + * and returning results */ public static record ToolRegistration(Tool tool, Function, CallToolResult> call) { - } + /** + * Registration of a resource with its handler function. Resources provide context + * to AI models by exposing data such as: + *
    + *
  • File contents + *
  • Database records + *
  • API responses + *
  • System information + *
  • Application state + *
+ * + *

Example resource registration: + *

{@code
+	 * new ResourceRegistration(
+	 *     new Resource("docs", "Documentation files", "text/markdown"),
+	 *     request -> {
+	 *         String content = readFile(request.getPath());
+	 *         return new ReadResourceResult(content);
+	 *     }
+	 * )
+	 * }
+ * + * @param resource The resource definition including name, description, and MIME type + * @param readHandler The function that handles resource read requests + */ public static record ResourceRegistration(McpSchema.Resource resource, Function readHandler) { } + /** + * Registration of a prompt template with its handler function. Prompts provide + * structured templates for AI model interactions, supporting: + *
    + *
  • Consistent message formatting + *
  • Parameter substitution + *
  • Context injection + *
  • Response formatting + *
  • Instruction templating + *
+ * + *

Example prompt registration: + *

{@code
+	 * new PromptRegistration(
+	 *     new Prompt("analyze", "Code analysis template"),
+	 *     request -> {
+	 *         String code = request.getArguments().get("code");
+	 *         return new GetPromptResult(
+	 *             "Analyze this code:\n\n" + code + "\n\nProvide feedback on:"
+	 *         );
+	 *     }
+	 * )
+	 * }
+ * + * @param prompt The prompt definition including name and description + * @param promptHandler The function that processes prompt requests and returns + * formatted templates + */ public static record PromptRegistration(McpSchema.Prompt propmpt, Function promptHandler) { } @@ -132,9 +245,14 @@ public interface McpServer { } /** - * Set the server implementation information. - * @param serverInfo The server implementation details - * @return This builder instance + * Sets the server implementation information that will be shared with clients + * during connection initialization. This helps with version compatibility, + * debugging, and server identification. + * + * @param serverInfo The server implementation details including name and version. + * Must not be null. + * @return This builder instance for method chaining + * @throws IllegalArgumentException if serverInfo is null */ public Builder info(McpSchema.Implementation serverInfo) { Assert.notNull(serverInfo, "Server info must not be null"); @@ -143,10 +261,14 @@ public interface McpServer { } /** - * Set the server implementation information using name and version. - * @param name The server name - * @param version The server version - * @return This builder instance + * Sets the server implementation information using name and version strings. + * This is a convenience method alternative to {@link #info(McpSchema.Implementation)}. + * + * @param name The server name. Must not 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 #info(McpSchema.Implementation) */ public Builder info(String name, String version) { Assert.hasText(name, "Name must not be null or empty"); @@ -156,9 +278,20 @@ public interface McpServer { } /** - * Set the server capabilities. - * @param serverCapabilities The server capabilities configuration - * @return This builder instance + * Sets the server capabilities that will be advertised to clients during + * connection initialization. Capabilities define what features the server + * supports, such as: + *
    + *
  • Tool execution + *
  • Resource access + *
  • Prompt handling + *
  • Streaming responses + *
  • Batch operations + *
+ * + * @param serverCapabilities The server capabilities configuration. Must not be null. + * @return This builder instance for method chaining + * @throws IllegalArgumentException if serverCapabilities is null */ public Builder capabilities(McpSchema.ServerCapabilities serverCapabilities) { this.serverCapabilities = serverCapabilities; @@ -166,10 +299,23 @@ public interface McpServer { } /** - * Add a tool with its handler function. - * @param tool The tool definition - * @param handler The function to handle tool execution - * @return This builder instance + * Adds a single tool with its implementation handler to the server. This is + * a convenience method for registering individual tools without creating a + * {@link ToolRegistration} explicitly. + * + *

Example usage: + *

{@code
+		 * .tool(
+		 *     new Tool("calculator", "Performs calculations", schema),
+		 *     args -> new CallToolResult("Result: " + calculate(args))
+		 * )
+		 * }
+ * + * @param tool The tool definition including name, description, and schema. + * Must not be null. + * @param handler The function that implements the tool's logic. Must not be null. + * @return This builder instance for method chaining + * @throws IllegalArgumentException if tool or handler is null */ public Builder tool(McpSchema.Tool tool, Function, McpSchema.CallToolResult> handler) { Assert.notNull(tool, "Tool must not be null"); @@ -181,9 +327,15 @@ public interface McpServer { } /** - * Add multiple tool handlers to the server. - * @param toolRegistrations The list of tool handlers to add - * @return This builder instance + * Adds multiple tools with their handlers to the server using a List. + * This method is useful when tools are dynamically generated or loaded + * from a configuration source. + * + * @param toolRegistrations The list of tool registrations to add. + * Must not be null. + * @return This builder instance for method chaining + * @throws IllegalArgumentException if toolRegistrations is null + * @see #tools(ToolRegistration...) */ public Builder tools(List toolRegistrations) { Assert.notNull(toolRegistrations, "Tool handlers list must not be null"); @@ -192,9 +344,22 @@ public interface McpServer { } /** - * Register tools with the server. - * @param toolRegistrations The map of tools to register - * @return This builder instance + * Adds multiple tools with their handlers to the server using varargs. + * This method provides a convenient way to register multiple tools inline. + * + *

Example usage: + *

{@code
+		 * .tools(
+		 *     new ToolRegistration(calculatorTool, calculatorHandler),
+		 *     new ToolRegistration(weatherTool, weatherHandler),
+		 *     new ToolRegistration(fileManagerTool, fileManagerHandler)
+		 * )
+		 * }
+ * + * @param toolRegistrations The tool registrations to add. Must not be null. + * @return This builder instance for method chaining + * @throws IllegalArgumentException if toolRegistrations is null + * @see #tools(List) */ public Builder tools(ToolRegistration... toolRegistrations) { for (ToolRegistration tool : toolRegistrations) { @@ -204,9 +369,15 @@ public interface McpServer { } /** - * Register resources with the server. - * @param resourceRegsitrations The map of resources to register - * @return This builder instance + * Registers multiple resources with their handlers using a Map. + * This method is useful when resources are dynamically generated + * or loaded from a configuration source. + * + * @param resourceRegsitrations Map of resource name to registration. + * Must not be null. + * @return This builder instance for method chaining + * @throws IllegalArgumentException if resourceRegsitrations is null + * @see #resources(ResourceRegistration...) */ public Builder resources(Map resourceRegsitrations) { Assert.notNull(resourceRegsitrations, "Resource handlers map must not be null"); @@ -215,9 +386,15 @@ public interface McpServer { } /** - * Register resources with the server. - * @param resourceRegsitrations The list of resources to register - * @return This builder instance + * Registers multiple resources with their handlers using a List. + * This method is useful when resources need to be added in bulk + * from a collection. + * + * @param resourceRegsitrations List of resource registrations. + * Must not be null. + * @return This builder instance for method chaining + * @throws IllegalArgumentException if resourceRegsitrations is null + * @see #resources(ResourceRegistration...) */ public Builder resources(List resourceRegsitrations) { Assert.notNull(resourceRegsitrations, "Resource handlers list must not be null"); @@ -228,9 +405,23 @@ public interface McpServer { } /** - * Register resources with the server. - * @param resourceRegistrations The list of resources to register - * @return This builder instance + * Registers multiple resources with their handlers using varargs. + * This method provides a convenient way to register multiple + * resources inline. + * + *

Example usage: + *

{@code
+		 * .resources(
+		 *     new ResourceRegistration(fileResource, fileHandler),
+		 *     new ResourceRegistration(dbResource, dbHandler),
+		 *     new ResourceRegistration(apiResource, apiHandler)
+		 * )
+		 * }
+ * + * @param resourceRegistrations The resource registrations to add. + * Must not be null. + * @return This builder instance for method chaining + * @throws IllegalArgumentException if resourceRegistrations is null */ public Builder resources(ResourceRegistration... resourceRegistrations) { Assert.notNull(resourceRegistrations, "Resource handlers list must not be null"); @@ -241,15 +432,36 @@ public interface McpServer { } /** - * Set the resource templates. - * @param resourceTemplates The list of resource templates - * @return This builder instance + * Sets the resource templates that define patterns for dynamic resource + * access. Templates use URI patterns with placeholders that can be + * filled at runtime. + * + *

Example usage: + *

{@code
+		 * .resourceTemplates(
+		 *     new ResourceTemplate("file://{path}", "Access files by path"),
+		 *     new ResourceTemplate("db://{table}/{id}", "Access database records")
+		 * )
+		 * }
+ * + * @param resourceTemplates List of resource templates. If null, clears + * existing templates. + * @return This builder instance for method chaining + * @see #resourceTemplates(ResourceTemplate...) */ public Builder resourceTemplates(List resourceTemplates) { this.resourceTemplates = resourceTemplates; return this; } + /** + * Sets the resource templates using varargs for convenience. + * This is an alternative to {@link #resourceTemplates(List)}. + * + * @param resourceTemplates The resource templates to set. + * @return This builder instance for method chaining + * @see #resourceTemplates(List) + */ public Builder resourceTemplates(ResourceTemplate... resourceTemplates) { for (ResourceTemplate resourceTemplate : resourceTemplates) { this.resourceTemplates.add(resourceTemplate); @@ -258,9 +470,23 @@ public interface McpServer { } /** - * Register prompts with the server. - * @param prompts The map of prompts to register - * @return This builder instance + * Registers multiple prompts with their handlers using a Map. + * This method is useful when prompts are dynamically generated + * or loaded from a configuration source. + * + *

Example usage: + *

{@code
+		 * Map prompts = new HashMap<>();
+		 * prompts.put("analysis", new PromptRegistration(
+		 *     new Prompt("analysis", "Code analysis template"),
+		 *     request -> new GetPromptResult(generateAnalysisPrompt(request))
+		 * ));
+		 * .prompts(prompts)
+		 * }
+ * + * @param prompts Map of prompt name to registration. Must not be null. + * @return This builder instance for method chaining + * @throws IllegalArgumentException if prompts is null */ public Builder prompts(Map prompts) { this.prompts.putAll(prompts); @@ -268,9 +494,14 @@ public interface McpServer { } /** - * Register prompts with the server. - * @param prompts The list of prompts to register - * @return This builder instance. + * Registers multiple prompts with their handlers using a List. + * This method is useful when prompts need to be added in bulk + * from a collection. + * + * @param prompts List of prompt registrations. Must not be null. + * @return This builder instance for method chaining + * @throws IllegalArgumentException if prompts is null + * @see #prompts(PromptRegistration...) */ public Builder prompts(List prompts) { for (PromptRegistration prompt : prompts) { @@ -280,9 +511,22 @@ public interface McpServer { } /** - * Register prompts with the server. - * @param prompts The list of prompts to register - * @return This builder instance + * Registers multiple prompts with their handlers using varargs. + * This method provides a convenient way to register multiple + * prompts inline. + * + *

Example usage: + *

{@code
+		 * .prompts(
+		 *     new PromptRegistration(analysisPrompt, analysisHandler),
+		 *     new PromptRegistration(summaryPrompt, summaryHandler),
+		 *     new PromptRegistration(reviewPrompt, reviewHandler)
+		 * )
+		 * }
+ * + * @param prompts The prompt registrations to add. Must not be null. + * @return This builder instance for method chaining + * @throws IllegalArgumentException if prompts is null */ public Builder prompts(PromptRegistration... prompts) { for (PromptRegistration prompt : prompts) { @@ -292,16 +536,26 @@ public interface McpServer { } /** - * Build a synchronous MCP server. - * @return A new instance of {@link McpSyncServer} + * Builds a synchronous MCP server that provides blocking operations. + * Synchronous servers process each request to completion before handling + * the next one, making them simpler to implement but potentially less + * performant for concurrent operations. + * + * @return A new instance of {@link McpSyncServer} configured with this + * builder's settings */ public McpSyncServer sync() { return new McpSyncServer(async()); } /** - * Build an asynchronous MCP server. - * @return A new instance of {@link McpAsyncServer} + * Builds an asynchronous MCP server that provides non-blocking operations. + * Asynchronous servers can handle multiple requests concurrently using + * CompletableFuture, making them more efficient for high-concurrency + * scenarios but more complex to implement. + * + * @return A new instance of {@link McpAsyncServer} configured with this + * builder's settings */ public McpAsyncServer async() { if (serverInfo == null) {