Skip to content

Commit 97ff64d

Browse files
committed
Decompose McpSchema nested types into top-level feature packages
- Extracts most domain types from the McpSchema god-class into dedicated top-level classes under spec.schema.resource/prompt/ tool/sample/elicit. - Extracts the JSON-RPC types from the McpSchema god-class into dedicated top-level classes under spec.jsonrpc - Moves JSONRPC_VERSION and deserializeJsonRpcMessage to a new JSONRPC utility class. Request, Result, and Notification are no longer sealed. - Adds mcp-migrate module with OpenRewrite recipes for automated user-side migration, and MIGRATION-1.1.md documenting every breaking change. Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
1 parent 6e4ce1c commit 97ff64d

File tree

117 files changed

+4150
-2963
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

117 files changed

+4150
-2963
lines changed

MIGRATION-1.1.md

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
# MCP Java SDK Migration Guide: 1.0 → 1.1
2+
3+
This document covers the breaking changes in **1.1.0** of the MCP Java SDK.
4+
5+
Most changes are mechanical import updates caused by the decomposition of the `McpSchema` god-class. An [OpenRewrite](https://docs.openrewrite.org/) recipe module (`mcp-migrate`) is provided to automate these changes. See [mcp-migrate/README.md](mcp-migrate/README.md) for usage instructions.
6+
7+
---
8+
9+
## Table of contents
10+
11+
1. [McpSchema decomposition — nested types moved to dedicated packages](#1-mcpschema-decomposition)
12+
2. [sealed interfaces opened](#2-sealed-interfaces-opened)
13+
3. [JSONRPC_VERSION constant relocated](#3-jsonrpc_version-constant-relocated)
14+
4. [deserializeJsonRpcMessage method relocated](#4-deserializejsonrpcmessage-method-relocated)
15+
5. [Automated migration with OpenRewrite](#5-automated-migration-with-openrewrite)
16+
6. [Manual migration reference table](#6-manual-migration-reference-table)
17+
18+
---
19+
20+
## 1. McpSchema decomposition
21+
22+
The `McpSchema` class previously held every domain type in the MCP specification as a nested class or record. In 1.1 those types are top-level classes organised in feature-specific sub-packages.
23+
24+
**Before (pre-1.1):**
25+
```java
26+
import io.modelcontextprotocol.spec.McpSchema;
27+
import io.modelcontextprotocol.spec.McpSchema.Tool;
28+
import io.modelcontextprotocol.spec.McpSchema.CallToolResult;
29+
30+
Tool tool = Tool.builder().name("my-tool").description("...").build();
31+
```
32+
33+
**After (1.1):**
34+
```java
35+
import io.modelcontextprotocol.spec.schema.tool.Tool;
36+
import io.modelcontextprotocol.spec.schema.tool.CallToolResult;
37+
38+
Tool tool = Tool.builder().name("my-tool").description("...").build();
39+
```
40+
41+
The new package hierarchy is:
42+
43+
```
44+
io.modelcontextprotocol.spec
45+
├── jsonrpc/ JSON-RPC 2.0 protocol types
46+
└── schema/
47+
├── resource/ Resource, template, read/subscribe requests & results
48+
├── prompt/ Prompt definitions and get/list requests & results
49+
├── tool/ Tool definition, call requests & results
50+
├── sample/ LLM sampling messages, preferences, and create request/result
51+
└── elicit/ Elicitation request and result
52+
```
53+
54+
### Types that remain in McpSchema
55+
56+
The following types were **not** moved and are still accessed as `McpSchema.*`:
57+
58+
| Type | Purpose |
59+
|---|---|
60+
| `Meta` | Base interface for `_meta` fields |
61+
| `Request` | Marker interface for request objects |
62+
| `Result` | Marker interface for result objects |
63+
| `Notification` | Marker interface for notification objects |
64+
| `ErrorCodes` | Standard JSON-RPC error code constants |
65+
| `InitializeRequest` / `InitializeResult` | Lifecycle handshake |
66+
| `ClientCapabilities` / `ServerCapabilities` | Capability negotiation |
67+
| `Implementation` | Server/client implementation descriptor |
68+
| `Role` | Enum: `USER` / `ASSISTANT` |
69+
| `Annotations` | Optional client annotations |
70+
| `Content` / `TextContent` / `ImageContent` / `AudioContent` | Content union type and variants |
71+
| `EmbeddedResource` / `ResourceLink` | Embedded resource in content |
72+
| `PaginatedRequest` / `PaginatedResult` | Cursor-based pagination |
73+
| `ProgressNotification` / `ResourcesUpdatedNotification` / `LoggingMessageNotification` | Server-sent notifications |
74+
| `LoggingLevel` / `SetLevelRequest` | Logging control |
75+
| `CompleteReference` / `PromptReference` / `ResourceReference` / `CompleteRequest` / `CompleteResult` | Argument completion |
76+
| `Root` / `ListRootsResult` | Client roots |
77+
78+
---
79+
80+
## 2. sealed interfaces opened
81+
82+
`Request`, `Result`, `Notification`, and `CompleteReference` were previously `sealed` with an explicit `permits` list. They are now plain interfaces.
83+
84+
**Before:**
85+
```java
86+
public sealed interface Request extends Meta
87+
permits InitializeRequest, CallToolRequest, CreateMessageRequest, ... { }
88+
```
89+
90+
**After:**
91+
```java
92+
public interface Request extends Meta { }
93+
```
94+
95+
**Impact on user code:** Code that used exhaustive `switch` or `instanceof` chains relying on the sealed hierarchy will no longer receive a compile-time guarantee that all cases are covered. Review any such patterns and add a default/fallback case if needed.
96+
97+
---
98+
99+
## 3. JSONRPC_VERSION constant relocated
100+
101+
The version string constant `"2.0"` moved from `McpSchema` to the new `JSONRPC` utility class.
102+
103+
**Before:**
104+
```java
105+
import io.modelcontextprotocol.spec.McpSchema;
106+
107+
String version = McpSchema.JSONRPC_VERSION;
108+
```
109+
110+
**After:**
111+
```java
112+
import io.modelcontextprotocol.spec.jsonrpc.JSONRPC;
113+
114+
String version = JSONRPC.JSONRPC_VERSION;
115+
```
116+
117+
---
118+
119+
## 4. deserializeJsonRpcMessage method relocated
120+
121+
The static helper for deserializing raw JSON into a `JSONRPCMessage` moved from `McpSchema` to the `JSONRPC` utility class.
122+
123+
**Before:**
124+
```java
125+
JSONRPCMessage msg = McpSchema.deserializeJsonRpcMessage(jsonMapper, rawJson);
126+
```
127+
128+
**After:**
129+
```java
130+
import io.modelcontextprotocol.spec.jsonrpc.JSONRPC;
131+
132+
JSONRPCMessage msg = JSONRPC.deserializeJsonRpcMessage(jsonMapper, rawJson);
133+
```
134+
135+
---
136+
137+
## 5. Automated migration with OpenRewrite
138+
139+
The `mcp-migrate` artifact ships OpenRewrite recipes that automate all of the import and type-reference changes described in this document.
140+
141+
**Maven:**
142+
```bash
143+
mvn org.openrewrite.maven:rewrite-maven-plugin:run \
144+
-Drewrite.recipeArtifactCoordinates=io.modelcontextprotocol.sdk:mcp-migrate:1.1.0 \
145+
-Drewrite.activeRecipes=io.modelcontextprotocol.sdk.migrations.McpSchemaMigration
146+
```
147+
148+
**Gradle:**
149+
```kotlin
150+
rewrite {
151+
activeRecipe("io.modelcontextprotocol.sdk.migrations.McpSchemaMigration")
152+
setRecipeArtifactCoordinates("io.modelcontextprotocol.sdk:mcp-migrate:1.1.0")
153+
}
154+
```
155+
156+
See [mcp-migrate/README.md](mcp-migrate/README.md) for full setup instructions, dry-run mode, and per-domain sub-recipes.
157+
158+
---
159+
160+
## 6. Manual migration reference table
161+
162+
Use this table if you prefer to update imports by hand or if OpenRewrite cannot resolve a reference (e.g. inside generated sources).
163+
164+
### JSON-RPC types → `io.modelcontextprotocol.spec.jsonrpc`
165+
166+
| Old (`McpSchema.*`) | New fully-qualified name |
167+
|---|---|
168+
| `McpSchema.JSONRPCMessage` | `io.modelcontextprotocol.spec.jsonrpc.JSONRPCMessage` |
169+
| `McpSchema.JSONRPCRequest` | `io.modelcontextprotocol.spec.jsonrpc.JSONRPCRequest` |
170+
| `McpSchema.JSONRPCNotification` | `io.modelcontextprotocol.spec.jsonrpc.JSONRPCNotification` |
171+
| `McpSchema.JSONRPCResponse` | `io.modelcontextprotocol.spec.jsonrpc.JSONRPCResponse` |
172+
| `McpSchema.JSONRPCResponse.JSONRPCError` | `io.modelcontextprotocol.spec.jsonrpc.JSONRPCResponse.JSONRPCError` |
173+
174+
### Resource types → `io.modelcontextprotocol.spec.schema.resource`
175+
176+
| Old (`McpSchema.*`) | New fully-qualified name |
177+
|---|---|
178+
| `McpSchema.Annotated` | `io.modelcontextprotocol.spec.schema.resource.Annotated` |
179+
| `McpSchema.Identifier` | `io.modelcontextprotocol.spec.schema.resource.Identifier` |
180+
| `McpSchema.ResourceContent` | `io.modelcontextprotocol.spec.schema.resource.ResourceContent` |
181+
| `McpSchema.ResourceContents` | `io.modelcontextprotocol.spec.schema.resource.ResourceContents` |
182+
| `McpSchema.TextResourceContents` | `io.modelcontextprotocol.spec.schema.resource.TextResourceContents` |
183+
| `McpSchema.BlobResourceContents` | `io.modelcontextprotocol.spec.schema.resource.BlobResourceContents` |
184+
| `McpSchema.Resource` | `io.modelcontextprotocol.spec.schema.resource.Resource` |
185+
| `McpSchema.ResourceTemplate` | `io.modelcontextprotocol.spec.schema.resource.ResourceTemplate` |
186+
| `McpSchema.ListResourcesResult` | `io.modelcontextprotocol.spec.schema.resource.ListResourcesResult` |
187+
| `McpSchema.ListResourceTemplatesResult` | `io.modelcontextprotocol.spec.schema.resource.ListResourceTemplatesResult` |
188+
| `McpSchema.ReadResourceRequest` | `io.modelcontextprotocol.spec.schema.resource.ReadResourceRequest` |
189+
| `McpSchema.ReadResourceResult` | `io.modelcontextprotocol.spec.schema.resource.ReadResourceResult` |
190+
| `McpSchema.SubscribeRequest` | `io.modelcontextprotocol.spec.schema.resource.SubscribeRequest` |
191+
| `McpSchema.UnsubscribeRequest` | `io.modelcontextprotocol.spec.schema.resource.UnsubscribeRequest` |
192+
193+
### Prompt types → `io.modelcontextprotocol.spec.schema.prompt`
194+
195+
| Old (`McpSchema.*`) | New fully-qualified name |
196+
|---|---|
197+
| `McpSchema.Prompt` | `io.modelcontextprotocol.spec.schema.prompt.Prompt` |
198+
| `McpSchema.PromptArgument` | `io.modelcontextprotocol.spec.schema.prompt.PromptArgument` |
199+
| `McpSchema.PromptMessage` | `io.modelcontextprotocol.spec.schema.prompt.PromptMessage` |
200+
| `McpSchema.ListPromptsResult` | `io.modelcontextprotocol.spec.schema.prompt.ListPromptsResult` |
201+
| `McpSchema.GetPromptRequest` | `io.modelcontextprotocol.spec.schema.prompt.GetPromptRequest` |
202+
| `McpSchema.GetPromptResult` | `io.modelcontextprotocol.spec.schema.prompt.GetPromptResult` |
203+
204+
### Tool types → `io.modelcontextprotocol.spec.schema.tool`
205+
206+
| Old (`McpSchema.*`) | New fully-qualified name |
207+
|---|---|
208+
| `McpSchema.JsonSchema` | `io.modelcontextprotocol.spec.schema.tool.JsonSchema` |
209+
| `McpSchema.ToolAnnotations` | `io.modelcontextprotocol.spec.schema.tool.ToolAnnotations` |
210+
| `McpSchema.Tool` | `io.modelcontextprotocol.spec.schema.tool.Tool` |
211+
| `McpSchema.ListToolsResult` | `io.modelcontextprotocol.spec.schema.tool.ListToolsResult` |
212+
| `McpSchema.CallToolRequest` | `io.modelcontextprotocol.spec.schema.tool.CallToolRequest` |
213+
| `McpSchema.CallToolResult` | `io.modelcontextprotocol.spec.schema.tool.CallToolResult` |
214+
215+
### Sampling types → `io.modelcontextprotocol.spec.schema.sample`
216+
217+
| Old (`McpSchema.*`) | New fully-qualified name |
218+
|---|---|
219+
| `McpSchema.SamplingMessage` | `io.modelcontextprotocol.spec.schema.sample.SamplingMessage` |
220+
| `McpSchema.ModelPreferences` | `io.modelcontextprotocol.spec.schema.sample.ModelPreferences` |
221+
| `McpSchema.ModelHint` | `io.modelcontextprotocol.spec.schema.sample.ModelHint` |
222+
| `McpSchema.CreateMessageRequest` | `io.modelcontextprotocol.spec.schema.sample.CreateMessageRequest` |
223+
| `McpSchema.CreateMessageRequest.ContextInclusionStrategy` | `io.modelcontextprotocol.spec.schema.sample.CreateMessageRequest.ContextInclusionStrategy` |
224+
| `McpSchema.CreateMessageResult` | `io.modelcontextprotocol.spec.schema.sample.CreateMessageResult` |
225+
226+
### Elicitation types → `io.modelcontextprotocol.spec.schema.elicit`
227+
228+
| Old (`McpSchema.*`) | New fully-qualified name |
229+
|---|---|
230+
| `McpSchema.ElicitRequest` | `io.modelcontextprotocol.spec.schema.elicit.ElicitRequest` |
231+
| `McpSchema.ElicitResult` | `io.modelcontextprotocol.spec.schema.elicit.ElicitResult` |
232+
233+
### Static members → `io.modelcontextprotocol.spec.jsonrpc.JSONRPC`
234+
235+
| Old | New |
236+
|---|---|
237+
| `McpSchema.JSONRPC_VERSION` | `JSONRPC.JSONRPC_VERSION` |
238+
| `McpSchema.deserializeJsonRpcMessage(mapper, json)` | `JSONRPC.deserializeJsonRpcMessage(mapper, json)` |

conformance-tests/client-jdk-http-client/src/main/java/io/modelcontextprotocol/conformance/client/ConformanceJdkClientMcpClient.java

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
import io.modelcontextprotocol.client.McpSyncClient;
77
import io.modelcontextprotocol.client.transport.HttpClientStreamableHttpTransport;
88
import io.modelcontextprotocol.spec.McpSchema;
9+
import io.modelcontextprotocol.spec.schema.tool.Tool;
10+
import io.modelcontextprotocol.spec.schema.elicit.ElicitResult;
11+
import io.modelcontextprotocol.spec.schema.tool.CallToolRequest;
12+
import io.modelcontextprotocol.spec.schema.tool.CallToolResult;
13+
import io.modelcontextprotocol.spec.schema.tool.ListToolsResult;
914

1015
/**
1116
* MCP Conformance Test Client - JDK HTTP Client Implementation
@@ -120,7 +125,7 @@ private static McpSyncClient createClientWithElicitation(String serverUrl) {
120125
}
121126

122127
// Return accept action with the defaults applied
123-
return new McpSchema.ElicitResult(McpSchema.ElicitResult.Action.ACCEPT, content, null);
128+
return new ElicitResult(ElicitResult.Action.ACCEPT, content, null);
124129
})
125130
.build();
126131
}
@@ -161,20 +166,19 @@ private static void runToolsCallScenario(String serverUrl) throws Exception {
161166
System.out.println("Successfully connected to MCP server");
162167

163168
// List available tools
164-
McpSchema.ListToolsResult toolsResult = client.listTools();
169+
ListToolsResult toolsResult = client.listTools();
165170
System.out.println("Successfully listed tools");
166171

167172
// Call the add_numbers tool if it exists
168173
if (toolsResult != null && toolsResult.tools() != null) {
169-
for (McpSchema.Tool tool : toolsResult.tools()) {
174+
for (Tool tool : toolsResult.tools()) {
170175
if ("add_numbers".equals(tool.name())) {
171176
// Call the add_numbers tool with test arguments
172177
var arguments = new java.util.HashMap<String, Object>();
173178
arguments.put("a", 5);
174179
arguments.put("b", 3);
175180

176-
McpSchema.CallToolResult result = client
177-
.callTool(new McpSchema.CallToolRequest("add_numbers", arguments));
181+
CallToolResult result = client.callTool(new CallToolRequest("add_numbers", arguments));
178182

179183
System.out.println("Successfully called add_numbers tool");
180184
if (result != null && result.content() != null) {
@@ -208,18 +212,18 @@ private static void runElicitationDefaultsScenario(String serverUrl) throws Exce
208212
System.out.println("Successfully connected to MCP server");
209213

210214
// List available tools
211-
McpSchema.ListToolsResult toolsResult = client.listTools();
215+
ListToolsResult toolsResult = client.listTools();
212216
System.out.println("Successfully listed tools");
213217

214218
// Call the test_client_elicitation_defaults tool if it exists
215219
if (toolsResult != null && toolsResult.tools() != null) {
216-
for (McpSchema.Tool tool : toolsResult.tools()) {
220+
for (Tool tool : toolsResult.tools()) {
217221
if ("test_client_elicitation_defaults".equals(tool.name())) {
218222
// Call the tool which will trigger an elicitation request
219223
var arguments = new java.util.HashMap<String, Object>();
220224

221-
McpSchema.CallToolResult result = client
222-
.callTool(new McpSchema.CallToolRequest("test_client_elicitation_defaults", arguments));
225+
CallToolResult result = client
226+
.callTool(new CallToolRequest("test_client_elicitation_defaults", arguments));
223227

224228
System.out.println("Successfully called test_client_elicitation_defaults tool");
225229
if (result != null && result.content() != null) {
@@ -253,19 +257,18 @@ private static void runSSERetryScenario(String serverUrl) throws Exception {
253257
System.out.println("Successfully connected to MCP server");
254258

255259
// List available tools
256-
McpSchema.ListToolsResult toolsResult = client.listTools();
260+
ListToolsResult toolsResult = client.listTools();
257261
System.out.println("Successfully listed tools");
258262

259263
// Call the test_reconnection tool if it exists
260264
if (toolsResult != null && toolsResult.tools() != null) {
261-
for (McpSchema.Tool tool : toolsResult.tools()) {
265+
for (Tool tool : toolsResult.tools()) {
262266
if ("test_reconnection".equals(tool.name())) {
263267
// Call the tool which will trigger SSE stream closure and
264268
// reconnection
265269
var arguments = new java.util.HashMap<String, Object>();
266270

267-
McpSchema.CallToolResult result = client
268-
.callTool(new McpSchema.CallToolRequest("test_reconnection", arguments));
271+
CallToolResult result = client.callTool(new CallToolRequest("test_reconnection", arguments));
269272

270273
System.out.println("Successfully called test_reconnection tool");
271274
if (result != null && result.content() != null) {

conformance-tests/server-servlet/src/main/java/io/modelcontextprotocol/conformance/server/ConformanceServlet.java

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,33 @@
1010
import io.modelcontextprotocol.server.transport.DefaultServerTransportSecurityValidator;
1111
import io.modelcontextprotocol.server.transport.HttpServletStreamableServerTransportProvider;
1212
import io.modelcontextprotocol.spec.McpSchema.AudioContent;
13-
import io.modelcontextprotocol.spec.McpSchema.BlobResourceContents;
14-
import io.modelcontextprotocol.spec.McpSchema.CallToolResult;
1513
import io.modelcontextprotocol.spec.McpSchema.CompleteResult;
16-
import io.modelcontextprotocol.spec.McpSchema.CreateMessageRequest;
17-
import io.modelcontextprotocol.spec.McpSchema.CreateMessageResult;
18-
import io.modelcontextprotocol.spec.McpSchema.ElicitRequest;
19-
import io.modelcontextprotocol.spec.McpSchema.ElicitResult;
2014
import io.modelcontextprotocol.spec.McpSchema.EmbeddedResource;
21-
import io.modelcontextprotocol.spec.McpSchema.GetPromptResult;
2215
import io.modelcontextprotocol.spec.McpSchema.ImageContent;
23-
import io.modelcontextprotocol.spec.McpSchema.JsonSchema;
2416
import io.modelcontextprotocol.spec.McpSchema.LoggingLevel;
2517
import io.modelcontextprotocol.spec.McpSchema.LoggingMessageNotification;
2618
import io.modelcontextprotocol.spec.McpSchema.ProgressNotification;
27-
import io.modelcontextprotocol.spec.McpSchema.Prompt;
28-
import io.modelcontextprotocol.spec.McpSchema.PromptArgument;
29-
import io.modelcontextprotocol.spec.McpSchema.PromptMessage;
3019
import io.modelcontextprotocol.spec.McpSchema.PromptReference;
31-
import io.modelcontextprotocol.spec.McpSchema.ReadResourceResult;
32-
import io.modelcontextprotocol.spec.McpSchema.Resource;
33-
import io.modelcontextprotocol.spec.McpSchema.ResourceTemplate;
3420
import io.modelcontextprotocol.spec.McpSchema.Role;
35-
import io.modelcontextprotocol.spec.McpSchema.SamplingMessage;
3621
import io.modelcontextprotocol.spec.McpSchema.ServerCapabilities;
3722
import io.modelcontextprotocol.spec.McpSchema.TextContent;
38-
import io.modelcontextprotocol.spec.McpSchema.TextResourceContents;
39-
import io.modelcontextprotocol.spec.McpSchema.Tool;
23+
import io.modelcontextprotocol.spec.schema.tool.Tool;
24+
import io.modelcontextprotocol.spec.schema.elicit.ElicitRequest;
25+
import io.modelcontextprotocol.spec.schema.elicit.ElicitResult;
26+
import io.modelcontextprotocol.spec.schema.prompt.GetPromptResult;
27+
import io.modelcontextprotocol.spec.schema.prompt.Prompt;
28+
import io.modelcontextprotocol.spec.schema.prompt.PromptArgument;
29+
import io.modelcontextprotocol.spec.schema.prompt.PromptMessage;
30+
import io.modelcontextprotocol.spec.schema.resource.BlobResourceContents;
31+
import io.modelcontextprotocol.spec.schema.resource.ReadResourceResult;
32+
import io.modelcontextprotocol.spec.schema.resource.Resource;
33+
import io.modelcontextprotocol.spec.schema.resource.ResourceTemplate;
34+
import io.modelcontextprotocol.spec.schema.resource.TextResourceContents;
35+
import io.modelcontextprotocol.spec.schema.sample.CreateMessageRequest;
36+
import io.modelcontextprotocol.spec.schema.sample.CreateMessageResult;
37+
import io.modelcontextprotocol.spec.schema.sample.SamplingMessage;
38+
import io.modelcontextprotocol.spec.schema.tool.CallToolResult;
39+
import io.modelcontextprotocol.spec.schema.tool.JsonSchema;
4040
import org.apache.catalina.Context;
4141
import org.apache.catalina.LifecycleException;
4242
import org.apache.catalina.startup.Tomcat;

0 commit comments

Comments
 (0)