Refactor McpClient for async and sync interactions
Introduce new builder patterns and enhance type safety - Add new builder patterns for McpClient and McpServer with sync/async variants - Introduce dedicated McpClientFeatures and McpServerFeatures classes - Enhance type safety and reactive support with proper Mono integration - Add migration guide for 0.6.0 release - Mark old builder methods as deprecated - Update documentation to reflect new APIs BREAKING CHANGE: The old builder patterns using McpClient.using() and McpServer.using() are now deprecated in favor of new sync() and async() builders that provide better type safety and clearer sync/async separation. Follow the migration guide. Resolves #48 Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com> Co-authored-by: Christian Tzolov <ctzolov@vmware.com>
This commit is contained in:
parent
e1bdc98813
commit
6839d3b740
1 changed files with 3494 additions and 753 deletions
|
|
@ -26,11 +26,42 @@ import org.springframework.ai.mcp.spec.McpSchema.LoggingMessageNotification;
|
|||
import org.springframework.ai.mcp.util.Assert;
|
||||
|
||||
/**
|
||||
* Synchronous wrapper around {@link McpAsyncServer} that provides blocking operations.
|
||||
* This class delegates all operations to an underlying async server instance while
|
||||
* providing a synchronous API.
|
||||
* A synchronous implementation of the Model Context Protocol (MCP) server that wraps
|
||||
* {@link McpAsyncServer} to provide blocking operations. This class delegates all
|
||||
* operations to an underlying async server instance while providing a simpler,
|
||||
* synchronous API for scenarios where reactive programming is not required.
|
||||
*
|
||||
* <p>
|
||||
* The MCP server enables AI models to expose tools, resources, and prompts through a
|
||||
* standardized interface. Key features available through this synchronous API include:
|
||||
* <ul>
|
||||
* <li>Tool registration and management for extending AI model capabilities
|
||||
* <li>Resource handling with URI-based addressing for providing context
|
||||
* <li>Prompt template management for standardized interactions
|
||||
* <li>Real-time client notifications for state changes
|
||||
* <li>Structured logging with configurable severity levels
|
||||
* <li>Support for client-side AI model sampling
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* While {@link McpAsyncServer} uses Project Reactor's Mono and Flux types for
|
||||
* non-blocking operations, this class converts those into blocking calls, making it more
|
||||
* suitable for:
|
||||
* <ul>
|
||||
* <li>Traditional synchronous applications
|
||||
* <li>Simple scripting scenarios
|
||||
* <li>Testing and debugging
|
||||
* <li>Cases where reactive programming adds unnecessary complexity
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* The server supports runtime modification of its capabilities through methods like
|
||||
* {@link #addTool}, {@link #addResource}, and {@link #addPrompt}, automatically notifying
|
||||
* connected clients of changes when configured to do so.
|
||||
*
|
||||
* @author Christian Tzolov
|
||||
* @see McpAsyncServer
|
||||
* @see McpSchema
|
||||
*/
|
||||
public class McpSyncServer {
|
||||
|
||||
|
|
@ -69,6 +100,16 @@ public class McpSyncServer {
|
|||
* Add a new tool handler.
|
||||
* @param toolHandler The tool handler to add
|
||||
*/
|
||||
public void addTool(McpServerFeatures.SyncToolRegistration toolHandler) {
|
||||
this.asyncServer.addTool(McpServerFeatures.AsyncToolRegistration.fromSync(toolHandler)).block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new tool handler.
|
||||
* @param toolHandler The tool handler to add
|
||||
* @deprecated Use {@link #addTool(McpServerFeatures.SyncToolRegistration)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public void addTool(ToolRegistration toolHandler) {
|
||||
this.asyncServer.addTool(toolHandler).block();
|
||||
}
|
||||
|
|
@ -85,6 +126,16 @@ public class McpSyncServer {
|
|||
* Add a new resource handler.
|
||||
* @param resourceHandler The resource handler to add
|
||||
*/
|
||||
public void addResource(McpServerFeatures.SyncResourceRegistration resourceHandler) {
|
||||
this.asyncServer.addResource(McpServerFeatures.AsyncResourceRegistration.fromSync(resourceHandler)).block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new resource handler.
|
||||
* @param resourceHandler The resource handler to add
|
||||
* @deprecated Use {@link #addResource(McpServerFeatures.SyncResourceRegistration)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public void addResource(ResourceRegistration resourceHandler) {
|
||||
this.asyncServer.addResource(resourceHandler).block();
|
||||
}
|
||||
|
|
@ -101,6 +152,16 @@ public class McpSyncServer {
|
|||
* Add a new prompt handler.
|
||||
* @param promptRegistration The prompt registration to add
|
||||
*/
|
||||
public void addPrompt(McpServerFeatures.SyncPromptRegistration promptRegistration) {
|
||||
this.asyncServer.addPrompt(McpServerFeatures.AsyncPromptRegistration.fromSync(promptRegistration)).block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new prompt handler.
|
||||
* @param promptRegistration The prompt registration to add
|
||||
* @deprecated Use {@link #addPrompt(McpServerFeatures.SyncPromptRegistration)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public void addPrompt(PromptRegistration promptRegistration) {
|
||||
this.asyncServer.addPrompt(promptRegistration).block();
|
||||
}
|
||||
|
|
@ -120,28 +181,6 @@ public class McpSyncServer {
|
|||
this.asyncServer.notifyToolsListChanged().block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify clients that the list of available resources has changed.
|
||||
*/
|
||||
public void notifyResourcesListChanged() {
|
||||
this.asyncServer.notifyResourcesListChanged().block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify clients that the list of available prompts has changed.
|
||||
*/
|
||||
public void notifyPromptsListChanged() {
|
||||
this.asyncServer.notifyPromptsListChanged().block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a logging message notification to all clients.
|
||||
* @param loggingMessageNotification The logging message notification to send
|
||||
*/
|
||||
public void loggingNotification(LoggingMessageNotification loggingMessageNotification) {
|
||||
this.asyncServer.loggingNotification(loggingMessageNotification).block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the server capabilities that define the supported features and functionality.
|
||||
* @return The server capabilities
|
||||
|
|
@ -174,6 +213,28 @@ public class McpSyncServer {
|
|||
return this.asyncServer.getClientInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify clients that the list of available resources has changed.
|
||||
*/
|
||||
public void notifyResourcesListChanged() {
|
||||
this.asyncServer.notifyResourcesListChanged().block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify clients that the list of available prompts has changed.
|
||||
*/
|
||||
public void notifyPromptsListChanged() {
|
||||
this.asyncServer.notifyPromptsListChanged().block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a logging message notification to all clients.
|
||||
* @param loggingMessageNotification The logging message notification to send
|
||||
*/
|
||||
public void loggingNotification(LoggingMessageNotification loggingMessageNotification) {
|
||||
this.asyncServer.loggingNotification(loggingMessageNotification).block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the server gracefully.
|
||||
*/
|
||||
|
|
@ -199,13 +260,19 @@ public class McpSyncServer {
|
|||
/**
|
||||
* Create a new message using the sampling capabilities of the client. The Model
|
||||
* Context Protocol (MCP) provides a standardized way for servers to request LLM
|
||||
* sampling (“completions” or “generations”) from language models via clients. This
|
||||
* flow allows clients to maintain control over model access, selection, and
|
||||
* sampling ("completions" or "generations") from language models via clients.
|
||||
*
|
||||
* <p>
|
||||
* This flow allows clients to maintain control over model access, selection, and
|
||||
* permissions while enabling servers to leverage AI capabilities—with no server API
|
||||
* keys necessary. Servers can request text or image-based interactions and optionally
|
||||
* include context from MCP servers in their prompts.
|
||||
*
|
||||
* <p>
|
||||
* Unlike its async counterpart, this method blocks until the message creation is
|
||||
* complete, making it easier to use in synchronous code paths.
|
||||
* @param createMessageRequest The request to create a new message
|
||||
* @return A Mono that completes when the message has been created
|
||||
* @return The result of the message creation
|
||||
* @throws McpError if the client has not been initialized or does not support
|
||||
* sampling capabilities
|
||||
* @throws McpError if the client does not support the createMessage method
|
||||
|
|
|
|||
Loading…
Reference in a new issue