This repository was archived by the owner on Feb 14, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 <[email protected]> Co-authored-by: Christian Tzolov <[email protected]>
- Loading branch information
Showing
25 changed files
with
3,494 additions
and
753 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,258 @@ | ||
# Spring AI MCP 0.5.0 Migration Guide | ||
|
||
This guide outlines the steps required to migrate your code to Spring AI MCP 0.6.0. | ||
|
||
## Key Changes | ||
|
||
- New builder patterns for `McpClient` and `McpServer` | ||
- Introduction of dedicated feature classes for sync/async operations | ||
- Enhanced type safety and reactive support | ||
- Deprecated methods and classes marked for removal | ||
|
||
## Client Migration | ||
|
||
### Creating Clients | ||
|
||
Before: | ||
```java | ||
// Sync client | ||
McpClient.using(transport) | ||
.requestTimeout(Duration.ofSeconds(5)) | ||
.sync(); | ||
|
||
// Async client | ||
McpClient.using(transport) | ||
.requestTimeout(Duration.ofSeconds(5)) | ||
.async(); | ||
``` | ||
|
||
After: | ||
```java | ||
// Sync client | ||
McpClient.sync(transport) | ||
.requestTimeout(Duration.ofSeconds(5)) | ||
.build(); | ||
|
||
// Async client | ||
McpClient.async(transport) | ||
.requestTimeout(Duration.ofSeconds(5)) | ||
.build(); | ||
``` | ||
|
||
### Change Consumers | ||
|
||
Before: | ||
```java | ||
// Sync client | ||
McpClient.using(transport) | ||
.toolsChangeConsumer(tools -> handleTools(tools)) | ||
.resourcesChangeConsumer(resources -> handleResources(resources)) | ||
.promptsChangeConsumer(prompts -> handlePrompts(prompts)) | ||
.sync(); | ||
|
||
// Async client | ||
McpClient.using(transport) | ||
.toolsChangeConsumer(tools -> handleTools(tools)) | ||
.resourcesChangeConsumer(resources -> handleResources(resources)) | ||
.promptsChangeConsumer(prompts -> handlePrompts(prompts)) | ||
.async(); | ||
``` | ||
|
||
After: | ||
```java | ||
// Sync client | ||
McpClient.sync(transport) | ||
.toolsChangeConsumer(tools -> handleTools(tools)) | ||
.resourcesChangeConsumer(resources -> handleResources(resources)) | ||
.promptsChangeConsumer(prompts -> handlePrompts(prompts)) | ||
.build(); | ||
|
||
// Async client | ||
McpClient.async(transport) | ||
.toolsChangeConsumer(tools -> Mono.fromRunnable(() -> handleTools(tools))) | ||
.resourcesChangeConsumer(resources -> Mono.fromRunnable(() -> handleResources(resources))) | ||
.promptsChangeConsumer(prompts -> Mono.fromRunnable(() -> handlePrompts(prompts))) | ||
.build(); | ||
``` | ||
|
||
### Sampling Handlers | ||
|
||
Before: | ||
```java | ||
// Sync client | ||
McpClient.using(transport) | ||
.sampling(request -> new CreateMessageResult("response")) | ||
.sync(); | ||
|
||
// Async client | ||
McpClient.using(transport) | ||
.sampling(request -> new CreateMessageResult("response")) | ||
.async(); | ||
``` | ||
|
||
After: | ||
```java | ||
// Sync client | ||
McpClient.sync(transport) | ||
.sampling(request -> new CreateMessageResult("response")) | ||
.build(); | ||
|
||
// Async client | ||
McpClient.async(transport) | ||
.sampling(request -> Mono.just(new CreateMessageResult("response"))) | ||
.build(); | ||
``` | ||
|
||
## Server Migration | ||
|
||
### Creating Servers | ||
|
||
Before: | ||
```java | ||
// Sync server | ||
McpServer.using(transport) | ||
.serverInfo("test-server", "1.0.0") | ||
.sync(); | ||
|
||
// Async server | ||
McpServer.using(transport) | ||
.serverInfo("test-server", "1.0.0") | ||
.async(); | ||
``` | ||
|
||
After: | ||
```java | ||
// Sync server | ||
McpServer.sync(transport) | ||
.serverInfo("test-server", "1.0.0") | ||
.build(); | ||
|
||
// Async server | ||
McpServer.async(transport) | ||
.serverInfo("test-server", "1.0.0") | ||
.build(); | ||
``` | ||
|
||
### Tool Registration | ||
|
||
Before: | ||
```java | ||
// Using ToolRegistration record | ||
new ToolRegistration( | ||
new Tool("calculator", "Performs calculations", schema), | ||
args -> new CallToolResult("result") | ||
); | ||
``` | ||
|
||
After: | ||
```java | ||
// Sync server | ||
new McpServerFeatures.SyncToolRegistration( | ||
new Tool("calculator", "Performs calculations", schema), | ||
args -> new CallToolResult("result") | ||
); | ||
|
||
// Async server | ||
new McpServerFeatures.AsyncToolRegistration( | ||
new Tool("calculator", "Performs calculations", schema), | ||
args -> Mono.just(new CallToolResult("result")) | ||
); | ||
``` | ||
|
||
### Resource Registration | ||
|
||
Before: | ||
```java | ||
// Using ResourceRegistration record | ||
new ResourceRegistration( | ||
new Resource("docs", "Documentation", "text/markdown"), | ||
request -> new ReadResourceResult(content) | ||
); | ||
``` | ||
|
||
After: | ||
```java | ||
// Sync server | ||
new McpServerFeatures.SyncResourceRegistration( | ||
new Resource("docs", "Documentation", "text/markdown"), | ||
request -> new ReadResourceResult(content) | ||
); | ||
|
||
// Async server | ||
new McpServerFeatures.AsyncResourceRegistration( | ||
new Resource("docs", "Documentation", "text/markdown"), | ||
request -> Mono.just(new ReadResourceResult(content)) | ||
); | ||
``` | ||
|
||
### Prompt Registration | ||
|
||
Before: | ||
```java | ||
// Using PromptRegistration record | ||
new PromptRegistration( | ||
new Prompt("analyze", "Code analysis"), | ||
request -> new GetPromptResult("result") | ||
); | ||
``` | ||
|
||
After: | ||
```java | ||
// Sync server | ||
new McpServerFeatures.SyncPromptRegistration( | ||
new Prompt("analyze", "Code analysis"), | ||
request -> new GetPromptResult("result") | ||
); | ||
|
||
// Async server | ||
new McpServerFeatures.AsyncPromptRegistration( | ||
new Prompt("analyze", "Code analysis"), | ||
request -> Mono.just(new GetPromptResult("result")) | ||
); | ||
``` | ||
|
||
## Spring Integration Changes | ||
|
||
### Tool Helper Changes | ||
|
||
Before: | ||
```java | ||
ToolHelper.toToolRegistration(functionCallback); | ||
ToolHelper.toToolRegistration(functionCallbacks); | ||
``` | ||
|
||
After: | ||
```java | ||
ToolHelper.toSyncToolRegistration(functionCallback); | ||
ToolHelper.toSyncToolRegistration(functionCallbacks); | ||
``` | ||
|
||
## Deprecated APIs | ||
|
||
The following APIs are deprecated and will be removed in a future release: | ||
|
||
- `McpClient.using()` - Use `McpClient.sync()` or `McpClient.async()` instead | ||
- `McpServer.using()` - Use `McpServer.sync()` or `McpServer.async()` instead | ||
- `McpServer.ToolRegistration` - Use `McpServerFeatures.SyncToolRegistration` or `McpServerFeatures.AsyncToolRegistration` instead | ||
- `McpServer.ResourceRegistration` - Use `McpServerFeatures.SyncResourceRegistration` or `McpServerFeatures.AsyncResourceRegistration` instead | ||
- `McpServer.PromptRegistration` - Use `McpServerFeatures.SyncPromptRegistration` or `McpServerFeatures.AsyncPromptRegistration` instead | ||
- `ToolHelper.toToolRegistration()` - Use `ToolHelper.toSyncToolRegistration()` instead | ||
|
||
## Benefits of Migration | ||
|
||
1. **Improved Type Safety**: The new builder patterns and feature classes provide better compile-time type checking. | ||
|
||
2. **Clear Async/Sync Separation**: Distinct builders and features for sync and async operations make the code intent clearer. | ||
|
||
3. **Enhanced Reactive Support**: Async operations now properly integrate with Project Reactor's `Mono` type. | ||
|
||
4. **Better Error Handling**: More consistent error handling across sync and async operations. | ||
|
||
5. **Simplified Configuration**: Builder patterns provide a more intuitive way to configure clients and servers. | ||
|
||
## Additional Notes | ||
|
||
- The migration primarily focuses on builder patterns and feature organization | ||
- Functional behavior remains the same after migration | ||
- Async operations now properly integrate with Project Reactor | ||
- All deprecated APIs will continue to work but will be removed in a future release |
Oops, something went wrong.