Skip to content

Commit ac6cafb

Browse files
committed
Add migration guide markdown
Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
1 parent 3daab08 commit ac6cafb

File tree

1 file changed

+326
-0
lines changed

1 file changed

+326
-0
lines changed

migration-0.8.0.md

Lines changed: 326 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,326 @@
1+
# MCP Java SDK Migration Guide: 0.7.0 to 0.8.0
2+
3+
This document outlines the breaking changes and provides guidance on how to migrate your code from version 0.7.0 to 0.8.0.
4+
5+
The 0.8.0 refactoring introduces a robust session-based architecture for server-side MCP implementations, to improve the SDK's ability to handle multiple concurrent client connections and provide a more consistent API. The main changes include:
6+
7+
1. Introduction of a session-based architecture
8+
2. New transport provider abstraction
9+
3. Exchange objects for client interaction
10+
4. Renamed and reorganized interfaces
11+
5. Updated handler signatures
12+
13+
## Breaking Changes
14+
15+
### 1. Interface Renaming
16+
17+
Several interfaces have been renamed to better reflect their roles:
18+
19+
| 0.7.0 (Old) | 0.8.0 (New) |
20+
|-------------|-------------|
21+
| `ClientMcpTransport` | `McpClientTransport` |
22+
| `ServerMcpTransport` | `McpServerTransport` |
23+
| `DefaultMcpSession` | `McpClientSession`, `McpServerSession` |
24+
25+
### 2. New Server Transport Architecture
26+
27+
The most significant change is the introduction of the `McpServerTransportProvider` interface, which replaces direct usage of `ServerMcpTransport` when creating servers. This new pattern separates the concerns of:
28+
29+
1. **Transport Provider**: Manages connections with clients and creates individual transports for each connection
30+
2. **Server Transport**: Handles communication with a specific client connection
31+
32+
| 0.7.0 (Old) | 0.8.0 (New) |
33+
|-------------|-------------|
34+
| `ServerMcpTransport` | `McpServerTransportProvider` + `McpServerTransport` |
35+
| Direct transport usage | Session-based transport usage |
36+
37+
#### Before (0.7.0):
38+
39+
```java
40+
// Create a transport
41+
ServerMcpTransport transport = new WebFluxSseServerTransport(objectMapper, "/mcp/message");
42+
43+
// Create a server with the transport
44+
McpServer.sync(transport)
45+
.serverInfo("my-server", "1.0.0")
46+
.build();
47+
```
48+
49+
#### After (0.8.0):
50+
51+
```java
52+
// Create a transport provider
53+
McpServerTransportProvider transportProvider = new WebFluxSseServerTransportProvider(objectMapper, "/mcp/message");
54+
55+
// Create a server with the transport provider
56+
McpServer.sync(transportProvider)
57+
.serverInfo("my-server", "1.0.0")
58+
.build();
59+
```
60+
61+
### 3. Handler Method Signature Changes
62+
63+
Tool, resource, and prompt handlers now receive an additional `exchange` parameter that provides access to client capabilities and methods to interact with the client:
64+
65+
| 0.7.0 (Old) | 0.8.0 (New) |
66+
|-------------|-------------|
67+
| `(args) -> result` | `(exchange, args) -> result` |
68+
69+
The exchange objects (`McpAsyncServerExchange` and `McpSyncServerExchange`) provide context for the current session and access to session-specific operations.
70+
71+
#### Before (0.7.0):
72+
73+
```java
74+
// Tool handler
75+
.tool(calculatorTool, args -> new CallToolResult("Result: " + calculate(args)))
76+
77+
// Resource handler
78+
.resource(fileResource, req -> new ReadResourceResult(readFile(req)))
79+
80+
// Prompt handler
81+
.prompt(analysisPrompt, req -> new GetPromptResult("Analysis prompt"))
82+
```
83+
84+
#### After (0.8.0):
85+
86+
```java
87+
// Tool handler
88+
.tool(calculatorTool, (exchange, args) -> new CallToolResult("Result: " + calculate(args)))
89+
90+
// Resource handler
91+
.resource(fileResource, (exchange, req) -> new ReadResourceResult(readFile(req)))
92+
93+
// Prompt handler
94+
.prompt(analysisPrompt, (exchange, req) -> new GetPromptResult("Analysis prompt"))
95+
```
96+
97+
### 4. Registration vs. Specification
98+
99+
The naming convention for handlers has changed from "Registration" to "Specification":
100+
101+
| 0.7.0 (Old) | 0.8.0 (New) |
102+
|-------------|-------------|
103+
| `AsyncToolRegistration` | `AsyncToolSpecification` |
104+
| `SyncToolRegistration` | `SyncToolSpecification` |
105+
| `AsyncResourceRegistration` | `AsyncResourceSpecification` |
106+
| `SyncResourceRegistration` | `SyncResourceSpecification` |
107+
| `AsyncPromptRegistration` | `AsyncPromptSpecification` |
108+
| `SyncPromptRegistration` | `SyncPromptSpecification` |
109+
110+
### 5. Roots Change Handler Updates
111+
112+
The roots change handlers now receive an exchange parameter:
113+
114+
#### Before (0.7.0):
115+
116+
```java
117+
.rootsChangeConsumers(List.of(
118+
roots -> {
119+
// Process roots
120+
}
121+
))
122+
```
123+
124+
#### After (0.8.0):
125+
126+
```java
127+
.rootsChangeHandlers(List.of(
128+
(exchange, roots) -> {
129+
// Process roots with access to exchange
130+
}
131+
))
132+
```
133+
134+
### 6. Server Creation Method Changes
135+
136+
The `McpServer` factory methods now accept `McpServerTransportProvider` instead of `ServerMcpTransport`:
137+
138+
| 0.7.0 (Old) | 0.8.0 (New) |
139+
|-------------|-------------|
140+
| `McpServer.async(ServerMcpTransport)` | `McpServer.async(McpServerTransportProvider)` |
141+
| `McpServer.sync(ServerMcpTransport)` | `McpServer.sync(McpServerTransportProvider)` |
142+
143+
The method names for creating servers have been updated:
144+
145+
Root change handlers now receive an exchange object:
146+
147+
| 0.7.0 (Old) | 0.8.0 (New) |
148+
|-------------|-------------|
149+
| `rootsChangeConsumers(List<Consumer<List<Root>>>)` | `rootsChangeHandlers(List<BiConsumer<McpSyncServerExchange, List<Root>>>)` |
150+
| `rootsChangeConsumer(Consumer<List<Root>>)` | `rootsChangeHandler(BiConsumer<McpSyncServerExchange, List<Root>>)` |
151+
152+
### 7. Direct Server Methods Moving to Exchange
153+
154+
Several methods that were previously available directly on the server are now accessed through the exchange object:
155+
156+
| 0.7.0 (Old) | 0.8.0 (New) |
157+
|-------------|-------------|
158+
| `server.listRoots()` | `exchange.listRoots()` |
159+
| `server.createMessage()` | `exchange.createMessage()` |
160+
| `server.getClientCapabilities()` | `exchange.getClientCapabilities()` |
161+
| `server.getClientInfo()` | `exchange.getClientInfo()` |
162+
163+
The direct methods are deprecated and will be removed in 0.9.0:
164+
165+
- `McpSyncServer.listRoots()`
166+
- `McpSyncServer.getClientCapabilities()`
167+
- `McpSyncServer.getClientInfo()`
168+
- `McpSyncServer.createMessage()`
169+
- `McpAsyncServer.listRoots()`
170+
- `McpAsyncServer.getClientCapabilities()`
171+
- `McpAsyncServer.getClientInfo()`
172+
- `McpAsyncServer.createMessage()`
173+
174+
## Deprecation Notices
175+
176+
The following components are deprecated in 0.8.0 and will be removed in 0.9.0:
177+
178+
- `ClientMcpTransport` interface (use `McpClientTransport` instead)
179+
- `ServerMcpTransport` interface (use `McpServerTransport` instead)
180+
- `DefaultMcpSession` class (use `McpClientSession` instead)
181+
- `WebFluxSseServerTransport` class (use `WebFluxSseServerTransportProvider` instead)
182+
- `WebMvcSseServerTransport` class (use `WebMvcSseServerTransportProvider` instead)
183+
- `StdioServerTransport` class (use `StdioServerTransportProvider` instead)
184+
- All `*Registration` classes (use corresponding `*Specification` classes instead)
185+
- Direct server methods for client interaction (use exchange object instead)
186+
187+
## Migration Examples
188+
189+
### Example 1: Creating a Server
190+
191+
#### Before (0.7.0):
192+
193+
```java
194+
// Create a transport
195+
ServerMcpTransport transport = new WebFluxSseServerTransport(objectMapper, "/mcp/message");
196+
197+
// Create a server with the transport
198+
var server = McpServer.sync(transport)
199+
.serverInfo("my-server", "1.0.0")
200+
.tool(calculatorTool, args -> new CallToolResult("Result: " + calculate(args)))
201+
.rootsChangeConsumers(List.of(
202+
roots -> System.out.println("Roots changed: " + roots)
203+
))
204+
.build();
205+
206+
// Get client capabilities directly from server
207+
ClientCapabilities capabilities = server.getClientCapabilities();
208+
```
209+
210+
#### After (0.8.0):
211+
212+
```java
213+
// Create a transport provider
214+
McpServerTransportProvider transportProvider = new WebFluxSseServerTransportProvider(objectMapper, "/mcp/message");
215+
216+
// Create a server with the transport provider
217+
var server = McpServer.sync(transportProvider)
218+
.serverInfo("my-server", "1.0.0")
219+
.tool(calculatorTool, (exchange, args) -> {
220+
// Get client capabilities from exchange
221+
ClientCapabilities capabilities = exchange.getClientCapabilities();
222+
return new CallToolResult("Result: " + calculate(args));
223+
})
224+
.rootsChangeHandlers(List.of(
225+
(exchange, roots) -> System.out.println("Roots changed: " + roots)
226+
))
227+
.build();
228+
```
229+
230+
### Example 2: Implementing a Tool with Client Interaction
231+
232+
#### Before (0.7.0):
233+
234+
```java
235+
McpServerFeatures.SyncToolRegistration tool = new McpServerFeatures.SyncToolRegistration(
236+
new Tool("weather", "Get weather information", schema),
237+
args -> {
238+
String location = (String) args.get("location");
239+
// Cannot interact with client from here
240+
return new CallToolResult("Weather for " + location + ": Sunny");
241+
}
242+
);
243+
244+
var server = McpServer.sync(transport)
245+
.tools(tool)
246+
.build();
247+
248+
// Separate call to create a message
249+
CreateMessageResult result = server.createMessage(new CreateMessageRequest(...));
250+
```
251+
252+
#### After (0.8.0):
253+
254+
```java
255+
McpServerFeatures.SyncToolSpecification tool = new McpServerFeatures.SyncToolSpecification(
256+
new Tool("weather", "Get weather information", schema),
257+
(exchange, args) -> {
258+
String location = (String) args.get("location");
259+
260+
// Can interact with client directly from the tool handler
261+
CreateMessageResult result = exchange.createMessage(new CreateMessageRequest(...));
262+
263+
return new CallToolResult("Weather for " + location + ": " + result.content());
264+
}
265+
);
266+
267+
var server = McpServer.sync(transportProvider)
268+
.tools(tool)
269+
.build();
270+
```
271+
272+
### Example 3: Converting Existing Registration Classes
273+
274+
If you have custom implementations of the registration classes, you can convert them to the new specification classes:
275+
276+
#### Before (0.7.0):
277+
278+
```java
279+
McpServerFeatures.AsyncToolRegistration toolReg = new McpServerFeatures.AsyncToolRegistration(
280+
tool,
281+
args -> Mono.just(new CallToolResult("Result"))
282+
);
283+
284+
McpServerFeatures.AsyncResourceRegistration resourceReg = new McpServerFeatures.AsyncResourceRegistration(
285+
resource,
286+
req -> Mono.just(new ReadResourceResult(List.of()))
287+
);
288+
```
289+
290+
#### After (0.8.0):
291+
292+
```java
293+
// Option 1: Create new specification directly
294+
McpServerFeatures.AsyncToolSpecification toolSpec = new McpServerFeatures.AsyncToolSpecification(
295+
tool,
296+
(exchange, args) -> Mono.just(new CallToolResult("Result"))
297+
);
298+
299+
// Option 2: Convert from existing registration (during transition)
300+
McpServerFeatures.AsyncToolRegistration oldToolReg = /* existing registration */;
301+
McpServerFeatures.AsyncToolSpecification toolSpec = oldToolReg.toSpecification();
302+
303+
// Similarly for resources
304+
McpServerFeatures.AsyncResourceSpecification resourceSpec = new McpServerFeatures.AsyncResourceSpecification(
305+
resource,
306+
(exchange, req) -> Mono.just(new ReadResourceResult(List.of()))
307+
);
308+
```
309+
310+
## Architecture Changes
311+
312+
### Session-Based Architecture
313+
314+
In 0.8.0, the MCP Java SDK introduces a session-based architecture where each client connection has its own session. This allows for better isolation between clients and more efficient resource management.
315+
316+
The `McpServerTransportProvider` is responsible for creating `McpServerTransport` instances for each session, and the `McpServerSession` manages the communication with a specific client.
317+
318+
### Exchange Objects
319+
320+
The new exchange objects (`McpAsyncServerExchange` and `McpSyncServerExchange`) provide access to client-specific information and methods. They are passed to handler functions as the first parameter, allowing handlers to interact with the specific client that made the request.
321+
322+
## Conclusion
323+
324+
The changes in version 0.8.0 represent a significant architectural improvement to the MCP Java SDK. While they require some code changes, the new design provides a more flexible and maintainable foundation for building MCP applications.
325+
326+
For assistance with migration or to report issues, please open an issue on the GitHub repository.

0 commit comments

Comments
 (0)