Skip to content

Commit 0d09a91

Browse files
committed
Upgrade to MCP SDK v0.14.0
1 parent 8ddd0f1 commit 0d09a91

16 files changed

+73
-135
lines changed

build.gradle

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ sourceSets {
7979

8080
configurations {
8181
integrationTestImplementation.extendsFrom testImplementation
82-
83-
// Force Jackson 2.17.0 to be compatible with MCP SDK v0.11.1
82+
83+
// Force Jackson 2.19.2 to be compatible with MCP SDK v0.14.0
8484
all {
8585
resolutionStrategy {
8686
force 'com.fasterxml.jackson.core:jackson-core:2.19.2'
@@ -108,16 +108,17 @@ repositories {
108108
dependencies {
109109
// Any external dependencies added here will automatically be copied to the lib/ directory when
110110
// this extension is built.
111-
implementation platform("io.modelcontextprotocol.sdk:mcp-bom:0.12.1")
111+
implementation platform("io.modelcontextprotocol.sdk:mcp-bom:0.14.0")
112112
implementation "io.modelcontextprotocol.sdk:mcp"
113+
implementation "io.modelcontextprotocol.sdk:mcp-json-jackson2"
113114
implementation "jakarta.servlet:jakarta.servlet-api:6.1.0"
114115
// Add Jetty for embedded servlet support
115116
implementation "org.eclipse.jetty:jetty-server:11.0.26"
116117
implementation "org.eclipse.jetty:jetty-servlet:11.0.26"
117-
118-
// Force Jackson 2.17.0 to be compatible with MCP SDK v0.11.1
118+
119+
// Force Jackson 2.19.2 to be compatible with MCP SDK v0.14.0
119120
implementation "com.fasterxml.jackson.core:jackson-core:2.19.2"
120-
implementation "com.fasterxml.jackson.core:jackson-databind:2.19.2"
121+
implementation "com.fasterxml.jackson.core:jackson-databind:2.19.2"
121122
implementation "com.fasterxml.jackson.core:jackson-annotations:2.19.2"
122123

123124
// Testing dependencies

src/main/java/reva/server/McpServerManager.java

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
3030
import java.util.EnumSet;
3131
import jakarta.servlet.DispatcherType;
3232

33-
import com.fasterxml.jackson.databind.ObjectMapper;
34-
3533
import generic.concurrent.GThreadPool;
3634
import ghidra.framework.plugintool.PluginTool;
3735
import ghidra.program.model.listing.Program;
@@ -40,7 +38,6 @@
4038
import io.modelcontextprotocol.server.McpServer;
4139
import io.modelcontextprotocol.server.McpSyncServer;
4240
import io.modelcontextprotocol.server.transport.HttpServletStreamableServerTransportProvider;
43-
import io.modelcontextprotocol.spec.McpError;
4441
import io.modelcontextprotocol.spec.McpSchema;
4542
import reva.plugin.ConfigManager;
4643
import reva.plugin.ConfigChangeListener;
@@ -69,7 +66,6 @@
6966
* the same server instance and coordinates program lifecycle events across tools.
7067
*/
7168
public class McpServerManager implements RevaMcpService, ConfigChangeListener {
72-
private static final ObjectMapper JSON = new ObjectMapper();
7369
private static final String MCP_MSG_ENDPOINT = "/mcp/message";
7470
private static final String MCP_SERVER_NAME = "ReVa";
7571
private static final String MCP_SERVER_VERSION = "1.0.0";
@@ -163,12 +159,9 @@ private void initializeToolProviders() {
163159
toolProviders.add(new BookmarkToolProvider(server));
164160

165161
// Register all tools with the server
162+
// Note: As of MCP SDK v0.14.0, tool registration is idempotent and replaces duplicates
166163
for (ToolProvider provider : toolProviders) {
167-
try {
168-
provider.registerTools();
169-
} catch (McpError e) {
170-
Msg.error(this, "Failed to register tools for provider: " + provider.getClass().getSimpleName(), e);
171-
}
164+
provider.registerTools();
172165
}
173166
}
174167

@@ -403,8 +396,8 @@ private void recreateTransportProvider() {
403396
String baseUrl = "http://" + serverHost + ":" + serverPort;
404397

405398
// Create new transport provider with updated configuration
399+
// Note: As of MCP SDK v0.14.0, the builder uses McpJsonMapper.getDefault() automatically
406400
currentTransportProvider = HttpServletStreamableServerTransportProvider.builder()
407-
.objectMapper(JSON)
408401
.mcpEndpoint(MCP_MSG_ENDPOINT)
409402
.keepAliveInterval(java.time.Duration.ofSeconds(30))
410403
.build();

src/main/java/reva/tools/AbstractToolProvider.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
import reva.plugin.RevaProgramManager;
3737
import reva.util.ProgramLookupUtil;
3838
import io.modelcontextprotocol.server.McpSyncServer;
39-
import io.modelcontextprotocol.spec.McpError;
4039
import io.modelcontextprotocol.spec.McpSchema;
4140
import io.modelcontextprotocol.spec.McpSchema.Content;
4241
import io.modelcontextprotocol.spec.McpSchema.TextContent;
@@ -134,9 +133,8 @@ protected McpSchema.CallToolResult createMultiJsonResult(List<Object> dataList)
134133
* Register a tool with the MCP server
135134
* @param tool The tool to register
136135
* @param handler The handler function for the tool
137-
* @throws McpError if there's an error registering the tool
138136
*/
139-
protected void registerTool(Tool tool, java.util.function.BiFunction<io.modelcontextprotocol.server.McpSyncServerExchange, CallToolRequest, McpSchema.CallToolResult> handler) throws McpError {
137+
protected void registerTool(Tool tool, java.util.function.BiFunction<io.modelcontextprotocol.server.McpSyncServerExchange, CallToolRequest, McpSchema.CallToolResult> handler) {
140138
// Wrap the handler with safe execution
141139
java.util.function.BiFunction<io.modelcontextprotocol.server.McpSyncServerExchange, CallToolRequest, McpSchema.CallToolResult> safeHandler =
142140
(exchange, request) -> {

src/main/java/reva/tools/ToolProvider.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
package reva.tools;
1717

1818
import ghidra.program.model.listing.Program;
19-
import io.modelcontextprotocol.spec.McpError;
2019

2120
/**
2221
* Interface for MCP tool providers.
@@ -26,9 +25,8 @@
2625
public interface ToolProvider {
2726
/**
2827
* Register all tools with the MCP server
29-
* @throws McpError if there's an error registering the tools
3028
*/
31-
void registerTools() throws McpError;
29+
void registerTools();
3230

3331
/**
3432
* Notify the provider that a program has been opened

src/main/java/reva/tools/bookmarks/BookmarkToolProvider.java

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import ghidra.program.model.listing.BookmarkManager;
2929
import ghidra.program.model.listing.Program;
3030
import io.modelcontextprotocol.server.McpSyncServer;
31-
import io.modelcontextprotocol.spec.McpError;
3231
import io.modelcontextprotocol.spec.McpSchema;
3332
import reva.tools.AbstractToolProvider;
3433
import reva.util.SchemaUtil;
@@ -48,7 +47,7 @@ public BookmarkToolProvider(McpSyncServer server) {
4847
}
4948

5049
@Override
51-
public void registerTools() throws McpError {
50+
public void registerTools() {
5251
registerSetBookmarkTool();
5352
registerGetBookmarksTool();
5453
registerRemoveBookmarkTool();
@@ -58,9 +57,8 @@ public void registerTools() throws McpError {
5857

5958
/**
6059
* Register a tool to set or update a bookmark at an address
61-
* @throws McpError if there's an error registering the tool
6260
*/
63-
private void registerSetBookmarkTool() throws McpError {
61+
private void registerSetBookmarkTool() {
6462
Map<String, Object> properties = new HashMap<>();
6563
properties.put("programPath", SchemaUtil.stringProperty("Path to the program in the Ghidra Project"));
6664
properties.put("addressOrSymbol", SchemaUtil.stringProperty("Address or symbol name where to set the bookmark"));
@@ -122,9 +120,8 @@ private void registerSetBookmarkTool() throws McpError {
122120

123121
/**
124122
* Register a tool to get bookmarks at an address or range
125-
* @throws McpError if there's an error registering the tool
126123
*/
127-
private void registerGetBookmarksTool() throws McpError {
124+
private void registerGetBookmarksTool() {
128125
Map<String, Object> properties = new HashMap<>();
129126
properties.put("programPath", SchemaUtil.stringProperty("Path to the program in the Ghidra Project"));
130127
properties.put("addressOrSymbol", SchemaUtil.stringProperty("Address or symbol name to get bookmarks from (optional if using addressRange)"));
@@ -222,9 +219,8 @@ private void registerGetBookmarksTool() throws McpError {
222219

223220
/**
224221
* Register a tool to remove a bookmark
225-
* @throws McpError if there's an error registering the tool
226222
*/
227-
private void registerRemoveBookmarkTool() throws McpError {
223+
private void registerRemoveBookmarkTool() {
228224
Map<String, Object> properties = new HashMap<>();
229225
properties.put("programPath", SchemaUtil.stringProperty("Path to the program in the Ghidra Project"));
230226
properties.put("addressOrSymbol", SchemaUtil.stringProperty("Address or symbol name of the bookmark"));
@@ -281,9 +277,8 @@ private void registerRemoveBookmarkTool() throws McpError {
281277

282278
/**
283279
* Register a tool to search bookmarks
284-
* @throws McpError if there's an error registering the tool
285280
*/
286-
private void registerSearchBookmarksTool() throws McpError {
281+
private void registerSearchBookmarksTool() {
287282
Map<String, Object> properties = new HashMap<>();
288283
properties.put("programPath", SchemaUtil.stringProperty("Path to the program in the Ghidra Project"));
289284
properties.put("searchText", SchemaUtil.stringProperty("Text to search for in bookmark comments (optional)"));
@@ -387,9 +382,8 @@ private void registerSearchBookmarksTool() throws McpError {
387382

388383
/**
389384
* Register a tool to list bookmark categories for a type
390-
* @throws McpError if there's an error registering the tool
391385
*/
392-
private void registerListBookmarkCategoriesTool() throws McpError {
386+
private void registerListBookmarkCategoriesTool() {
393387
Map<String, Object> properties = new HashMap<>();
394388
properties.put("programPath", SchemaUtil.stringProperty("Path to the program in the Ghidra Project"));
395389
properties.put("type", SchemaUtil.stringProperty("Bookmark type to get categories for"));

src/main/java/reva/tools/comments/CommentToolProvider.java

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import ghidra.program.model.listing.Listing;
3030
import ghidra.program.model.listing.CodeUnitIterator;
3131
import io.modelcontextprotocol.server.McpSyncServer;
32-
import io.modelcontextprotocol.spec.McpError;
3332
import io.modelcontextprotocol.spec.McpSchema;
3433
import reva.tools.AbstractToolProvider;
3534
import reva.util.AddressUtil;
@@ -58,7 +57,7 @@ public CommentToolProvider(McpSyncServer server) {
5857
}
5958

6059
@Override
61-
public void registerTools() throws McpError {
60+
public void registerTools() {
6261
registerSetCommentTool();
6362
registerGetCommentsTool();
6463
registerRemoveCommentTool();
@@ -67,9 +66,8 @@ public void registerTools() throws McpError {
6766

6867
/**
6968
* Register a tool to set or update a comment at an address
70-
* @throws McpError if there's an error registering the tool
7169
*/
72-
private void registerSetCommentTool() throws McpError {
70+
private void registerSetCommentTool() {
7371
Map<String, Object> properties = new HashMap<>();
7472
properties.put("programPath", SchemaUtil.stringProperty("Path to the program in the Ghidra Project"));
7573
properties.put("addressOrSymbol", SchemaUtil.stringProperty("Address or symbol name where to set the comment"));
@@ -126,9 +124,8 @@ private void registerSetCommentTool() throws McpError {
126124

127125
/**
128126
* Register a tool to get comments at an address or range
129-
* @throws McpError if there's an error registering the tool
130127
*/
131-
private void registerGetCommentsTool() throws McpError {
128+
private void registerGetCommentsTool() {
132129
Map<String, Object> properties = new HashMap<>();
133130
properties.put("programPath", SchemaUtil.stringProperty("Path to the program in the Ghidra Project"));
134131
properties.put("addressOrSymbol", SchemaUtil.stringProperty("Address or symbol name to get comments from (optional if using addressRange)"));
@@ -230,9 +227,8 @@ private void registerGetCommentsTool() throws McpError {
230227

231228
/**
232229
* Register a tool to remove a comment at an address
233-
* @throws McpError if there's an error registering the tool
234230
*/
235-
private void registerRemoveCommentTool() throws McpError {
231+
private void registerRemoveCommentTool() {
236232
Map<String, Object> properties = new HashMap<>();
237233
properties.put("programPath", SchemaUtil.stringProperty("Path to the program in the Ghidra Project"));
238234
properties.put("addressOrSymbol", SchemaUtil.stringProperty("Address or symbol name where to remove the comment"));
@@ -286,9 +282,8 @@ private void registerRemoveCommentTool() throws McpError {
286282

287283
/**
288284
* Register a tool to search for comments containing text
289-
* @throws McpError if there's an error registering the tool
290285
*/
291-
private void registerSearchCommentsTool() throws McpError {
286+
private void registerSearchCommentsTool() {
292287
Map<String, Object> properties = new HashMap<>();
293288
properties.put("programPath", SchemaUtil.stringProperty("Path to the program in the Ghidra Project"));
294289
properties.put("searchText", SchemaUtil.stringProperty("Text to search for in comments"));

src/main/java/reva/tools/data/DataToolProvider.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import ghidra.program.model.mem.MemoryAccessException;
3131
import ghidra.program.model.symbol.Symbol;
3232
import ghidra.program.model.symbol.SymbolTable;
33-
import io.modelcontextprotocol.spec.McpError;
3433
import io.modelcontextprotocol.server.McpSyncServer;
3534
import io.modelcontextprotocol.spec.McpSchema;
3635
import io.modelcontextprotocol.spec.McpSchema.CallToolResult;
@@ -54,17 +53,16 @@ public DataToolProvider(McpSyncServer server) {
5453
}
5554

5655
@Override
57-
public void registerTools() throws McpError {
56+
public void registerTools() {
5857
registerGetDataTool();
5958
registerApplyDataTypeTool();
6059
registerCreateLabelTool();
6160
}
6261

6362
/**
6463
* Register a unified tool to get data by address or symbol name
65-
* @throws McpError if there's an error registering the tool
6664
*/
67-
private void registerGetDataTool() throws McpError {
65+
private void registerGetDataTool() {
6866
// Define schema for the tool
6967
Map<String, Object> properties = new HashMap<>();
7068
properties.put("programPath", Map.of(
@@ -98,9 +96,8 @@ private void registerGetDataTool() throws McpError {
9896

9997
/**
10098
* Register a tool to apply a data type to an address or symbol
101-
* @throws McpError if there's an error registering the tool
10299
*/
103-
private void registerApplyDataTypeTool() throws McpError {
100+
private void registerApplyDataTypeTool() {
104101
// Define schema for the tool
105102
Map<String, Object> properties = new HashMap<>();
106103
properties.put("programPath", Map.of(
@@ -201,9 +198,8 @@ private void registerApplyDataTypeTool() throws McpError {
201198

202199
/**
203200
* Register a tool to create a label at a specific address in a program
204-
* @throws McpError if there's an error registering the tool
205201
*/
206-
private void registerCreateLabelTool() throws McpError {
202+
private void registerCreateLabelTool() {
207203
// Define schema for the tool
208204
Map<String, Object> properties = new HashMap<>();
209205
properties.put("programPath", Map.of(

src/main/java/reva/tools/datatypes/DataTypeToolProvider.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import ghidra.program.model.listing.Program;
2929
import ghidra.util.Msg;
3030
import io.modelcontextprotocol.server.McpSyncServer;
31-
import io.modelcontextprotocol.spec.McpError;
3231
import io.modelcontextprotocol.spec.McpSchema;
3332
import reva.plugin.RevaProgramManager;
3433
import reva.tools.AbstractToolProvider;
@@ -49,17 +48,16 @@ public DataTypeToolProvider(McpSyncServer server) {
4948
}
5049

5150
@Override
52-
public void registerTools() throws McpError {
51+
public void registerTools() {
5352
registerGetDataTypeArchivesTool();
5453
registerGetDataTypesTool();
5554
registerGetDataTypeByStringTool();
5655
}
5756

5857
/**
5958
* Register a tool to get data type archives for a specific program
60-
* @throws McpError if there's an error registering the tool
6159
*/
62-
private void registerGetDataTypeArchivesTool() throws McpError {
60+
private void registerGetDataTypeArchivesTool() {
6361
// Define schema for the tool
6462
Map<String, Object> properties = new HashMap<>();
6563
properties.put("programPath", Map.of(
@@ -177,9 +175,8 @@ private void registerGetDataTypeArchivesTool() throws McpError {
177175

178176
/**
179177
* Register a tool to get data types from an archive
180-
* @throws McpError if there's an error registering the tool
181178
*/
182-
private void registerGetDataTypesTool() throws McpError {
179+
private void registerGetDataTypesTool() {
183180
// Define schema for the tool
184181
Map<String, Object> properties = new HashMap<>();
185182
properties.put("programPath", Map.of(
@@ -305,9 +302,8 @@ private void registerGetDataTypesTool() throws McpError {
305302

306303
/**
307304
* Register a tool to get a data type by string representation (e.g., "char**")
308-
* @throws McpError if there's an error registering the tool
309305
*/
310-
private void registerGetDataTypeByStringTool() throws McpError {
306+
private void registerGetDataTypeByStringTool() {
311307
// Define schema for the tool
312308
Map<String, Object> properties = new HashMap<>();
313309
properties.put("programPath", Map.of(

0 commit comments

Comments
 (0)