Skip to content
This repository was archived by the owner on Feb 14, 2025. It is now read-only.

Commit 6839d3b

Browse files
chemicLtzolov
andcommitted
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]>
1 parent e1bdc98 commit 6839d3b

File tree

25 files changed

+3494
-753
lines changed

25 files changed

+3494
-753
lines changed

mcp-docs/0.6.0-MIGRATION-GUIDE.md

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
# Spring AI MCP 0.5.0 Migration Guide
2+
3+
This guide outlines the steps required to migrate your code to Spring AI MCP 0.6.0.
4+
5+
## Key Changes
6+
7+
- New builder patterns for `McpClient` and `McpServer`
8+
- Introduction of dedicated feature classes for sync/async operations
9+
- Enhanced type safety and reactive support
10+
- Deprecated methods and classes marked for removal
11+
12+
## Client Migration
13+
14+
### Creating Clients
15+
16+
Before:
17+
```java
18+
// Sync client
19+
McpClient.using(transport)
20+
.requestTimeout(Duration.ofSeconds(5))
21+
.sync();
22+
23+
// Async client
24+
McpClient.using(transport)
25+
.requestTimeout(Duration.ofSeconds(5))
26+
.async();
27+
```
28+
29+
After:
30+
```java
31+
// Sync client
32+
McpClient.sync(transport)
33+
.requestTimeout(Duration.ofSeconds(5))
34+
.build();
35+
36+
// Async client
37+
McpClient.async(transport)
38+
.requestTimeout(Duration.ofSeconds(5))
39+
.build();
40+
```
41+
42+
### Change Consumers
43+
44+
Before:
45+
```java
46+
// Sync client
47+
McpClient.using(transport)
48+
.toolsChangeConsumer(tools -> handleTools(tools))
49+
.resourcesChangeConsumer(resources -> handleResources(resources))
50+
.promptsChangeConsumer(prompts -> handlePrompts(prompts))
51+
.sync();
52+
53+
// Async client
54+
McpClient.using(transport)
55+
.toolsChangeConsumer(tools -> handleTools(tools))
56+
.resourcesChangeConsumer(resources -> handleResources(resources))
57+
.promptsChangeConsumer(prompts -> handlePrompts(prompts))
58+
.async();
59+
```
60+
61+
After:
62+
```java
63+
// Sync client
64+
McpClient.sync(transport)
65+
.toolsChangeConsumer(tools -> handleTools(tools))
66+
.resourcesChangeConsumer(resources -> handleResources(resources))
67+
.promptsChangeConsumer(prompts -> handlePrompts(prompts))
68+
.build();
69+
70+
// Async client
71+
McpClient.async(transport)
72+
.toolsChangeConsumer(tools -> Mono.fromRunnable(() -> handleTools(tools)))
73+
.resourcesChangeConsumer(resources -> Mono.fromRunnable(() -> handleResources(resources)))
74+
.promptsChangeConsumer(prompts -> Mono.fromRunnable(() -> handlePrompts(prompts)))
75+
.build();
76+
```
77+
78+
### Sampling Handlers
79+
80+
Before:
81+
```java
82+
// Sync client
83+
McpClient.using(transport)
84+
.sampling(request -> new CreateMessageResult("response"))
85+
.sync();
86+
87+
// Async client
88+
McpClient.using(transport)
89+
.sampling(request -> new CreateMessageResult("response"))
90+
.async();
91+
```
92+
93+
After:
94+
```java
95+
// Sync client
96+
McpClient.sync(transport)
97+
.sampling(request -> new CreateMessageResult("response"))
98+
.build();
99+
100+
// Async client
101+
McpClient.async(transport)
102+
.sampling(request -> Mono.just(new CreateMessageResult("response")))
103+
.build();
104+
```
105+
106+
## Server Migration
107+
108+
### Creating Servers
109+
110+
Before:
111+
```java
112+
// Sync server
113+
McpServer.using(transport)
114+
.serverInfo("test-server", "1.0.0")
115+
.sync();
116+
117+
// Async server
118+
McpServer.using(transport)
119+
.serverInfo("test-server", "1.0.0")
120+
.async();
121+
```
122+
123+
After:
124+
```java
125+
// Sync server
126+
McpServer.sync(transport)
127+
.serverInfo("test-server", "1.0.0")
128+
.build();
129+
130+
// Async server
131+
McpServer.async(transport)
132+
.serverInfo("test-server", "1.0.0")
133+
.build();
134+
```
135+
136+
### Tool Registration
137+
138+
Before:
139+
```java
140+
// Using ToolRegistration record
141+
new ToolRegistration(
142+
new Tool("calculator", "Performs calculations", schema),
143+
args -> new CallToolResult("result")
144+
);
145+
```
146+
147+
After:
148+
```java
149+
// Sync server
150+
new McpServerFeatures.SyncToolRegistration(
151+
new Tool("calculator", "Performs calculations", schema),
152+
args -> new CallToolResult("result")
153+
);
154+
155+
// Async server
156+
new McpServerFeatures.AsyncToolRegistration(
157+
new Tool("calculator", "Performs calculations", schema),
158+
args -> Mono.just(new CallToolResult("result"))
159+
);
160+
```
161+
162+
### Resource Registration
163+
164+
Before:
165+
```java
166+
// Using ResourceRegistration record
167+
new ResourceRegistration(
168+
new Resource("docs", "Documentation", "text/markdown"),
169+
request -> new ReadResourceResult(content)
170+
);
171+
```
172+
173+
After:
174+
```java
175+
// Sync server
176+
new McpServerFeatures.SyncResourceRegistration(
177+
new Resource("docs", "Documentation", "text/markdown"),
178+
request -> new ReadResourceResult(content)
179+
);
180+
181+
// Async server
182+
new McpServerFeatures.AsyncResourceRegistration(
183+
new Resource("docs", "Documentation", "text/markdown"),
184+
request -> Mono.just(new ReadResourceResult(content))
185+
);
186+
```
187+
188+
### Prompt Registration
189+
190+
Before:
191+
```java
192+
// Using PromptRegistration record
193+
new PromptRegistration(
194+
new Prompt("analyze", "Code analysis"),
195+
request -> new GetPromptResult("result")
196+
);
197+
```
198+
199+
After:
200+
```java
201+
// Sync server
202+
new McpServerFeatures.SyncPromptRegistration(
203+
new Prompt("analyze", "Code analysis"),
204+
request -> new GetPromptResult("result")
205+
);
206+
207+
// Async server
208+
new McpServerFeatures.AsyncPromptRegistration(
209+
new Prompt("analyze", "Code analysis"),
210+
request -> Mono.just(new GetPromptResult("result"))
211+
);
212+
```
213+
214+
## Spring Integration Changes
215+
216+
### Tool Helper Changes
217+
218+
Before:
219+
```java
220+
ToolHelper.toToolRegistration(functionCallback);
221+
ToolHelper.toToolRegistration(functionCallbacks);
222+
```
223+
224+
After:
225+
```java
226+
ToolHelper.toSyncToolRegistration(functionCallback);
227+
ToolHelper.toSyncToolRegistration(functionCallbacks);
228+
```
229+
230+
## Deprecated APIs
231+
232+
The following APIs are deprecated and will be removed in a future release:
233+
234+
- `McpClient.using()` - Use `McpClient.sync()` or `McpClient.async()` instead
235+
- `McpServer.using()` - Use `McpServer.sync()` or `McpServer.async()` instead
236+
- `McpServer.ToolRegistration` - Use `McpServerFeatures.SyncToolRegistration` or `McpServerFeatures.AsyncToolRegistration` instead
237+
- `McpServer.ResourceRegistration` - Use `McpServerFeatures.SyncResourceRegistration` or `McpServerFeatures.AsyncResourceRegistration` instead
238+
- `McpServer.PromptRegistration` - Use `McpServerFeatures.SyncPromptRegistration` or `McpServerFeatures.AsyncPromptRegistration` instead
239+
- `ToolHelper.toToolRegistration()` - Use `ToolHelper.toSyncToolRegistration()` instead
240+
241+
## Benefits of Migration
242+
243+
1. **Improved Type Safety**: The new builder patterns and feature classes provide better compile-time type checking.
244+
245+
2. **Clear Async/Sync Separation**: Distinct builders and features for sync and async operations make the code intent clearer.
246+
247+
3. **Enhanced Reactive Support**: Async operations now properly integrate with Project Reactor's `Mono` type.
248+
249+
4. **Better Error Handling**: More consistent error handling across sync and async operations.
250+
251+
5. **Simplified Configuration**: Builder patterns provide a more intuitive way to configure clients and servers.
252+
253+
## Additional Notes
254+
255+
- The migration primarily focuses on builder patterns and feature organization
256+
- Functional behavior remains the same after migration
257+
- Async operations now properly integrate with Project Reactor
258+
- All deprecated APIs will continue to work but will be removed in a future release

0 commit comments

Comments
 (0)