diff --git a/dubbo-plugin/dubbo-mcp/pom.xml b/dubbo-plugin/dubbo-mcp/pom.xml index 4ad926b2fbc9..652fc609cef9 100644 --- a/dubbo-plugin/dubbo-mcp/pom.xml +++ b/dubbo-plugin/dubbo-mcp/pom.xml @@ -26,7 +26,7 @@ dubbo-mcp - 0.11.2 + 0.18.2 false diff --git a/dubbo-plugin/dubbo-mcp/src/main/java/org/apache/dubbo/mcp/core/McpApplicationDeployListener.java b/dubbo-plugin/dubbo-mcp/src/main/java/org/apache/dubbo/mcp/core/McpApplicationDeployListener.java index 555c0b8aa332..0965ec9982b1 100644 --- a/dubbo-plugin/dubbo-mcp/src/main/java/org/apache/dubbo/mcp/core/McpApplicationDeployListener.java +++ b/dubbo-plugin/dubbo-mcp/src/main/java/org/apache/dubbo/mcp/core/McpApplicationDeployListener.java @@ -44,6 +44,8 @@ import java.util.concurrent.ExecutorService; import com.fasterxml.jackson.databind.ObjectMapper; +import io.modelcontextprotocol.json.McpJsonMapper; +import io.modelcontextprotocol.json.jackson2.JacksonMcpJsonMapper; import io.modelcontextprotocol.server.McpAsyncServer; import io.modelcontextprotocol.server.McpServer; import io.modelcontextprotocol.spec.McpSchema; @@ -54,6 +56,9 @@ public class McpApplicationDeployListener implements ApplicationDeployListener { private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(McpApplicationDeployListener.class); + + private static final McpJsonMapper MCP_JSON_MAPPER = createMcpJsonMapper(); + private DubboServiceToolRegistry toolRegistry; private boolean mcpEnable = true; @@ -106,12 +111,12 @@ public void onStarted(ApplicationModel applicationModel) { globalConf.getInt(McpConstant.SETTINGS_MCP_SESSION_TIMEOUT, McpConstant.DEFAULT_SESSION_TIMEOUT); if ("streamable".equals(protocol)) { dubboMcpStreamableTransportProvider = - new DubboMcpStreamableTransportProvider(new ObjectMapper(), sessionTimeout); + new DubboMcpStreamableTransportProvider(MCP_JSON_MAPPER, sessionTimeout); mcpAsyncServer = McpServer.async(getDubboMcpStreamableTransportProvider()) .capabilities(serverCapabilities) .build(); } else if ("sse".equals(protocol)) { - dubboMcpSseTransportProvider = new DubboMcpSseTransportProvider(new ObjectMapper(), sessionTimeout); + dubboMcpSseTransportProvider = new DubboMcpSseTransportProvider(MCP_JSON_MAPPER, sessionTimeout); mcpAsyncServer = McpServer.async(getDubboMcpSseTransportProvider()) .capabilities(serverCapabilities) .build(); @@ -245,4 +250,10 @@ private int getRegisterPort() { } return NetUtils.getAvailablePort(); } + + private static McpJsonMapper createMcpJsonMapper() { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.setSerializationInclusion(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL); + return new JacksonMcpJsonMapper(objectMapper); + } } diff --git a/dubbo-plugin/dubbo-mcp/src/main/java/org/apache/dubbo/mcp/tool/DubboOpenApiToolConverter.java b/dubbo-plugin/dubbo-mcp/src/main/java/org/apache/dubbo/mcp/tool/DubboOpenApiToolConverter.java index 68ac50687dcf..c24f0daf8e09 100644 --- a/dubbo-plugin/dubbo-mcp/src/main/java/org/apache/dubbo/mcp/tool/DubboOpenApiToolConverter.java +++ b/dubbo-plugin/dubbo-mcp/src/main/java/org/apache/dubbo/mcp/tool/DubboOpenApiToolConverter.java @@ -42,7 +42,6 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import com.fasterxml.jackson.databind.ObjectMapper; import io.modelcontextprotocol.spec.McpSchema; public class DubboOpenApiToolConverter { @@ -50,7 +49,6 @@ public class DubboOpenApiToolConverter { private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(DubboOpenApiToolConverter.class); private final DefaultOpenAPIService openApiService; - private final ObjectMapper objectMapper = new ObjectMapper(); private final Map opCache = new ConcurrentHashMap<>(); public DubboOpenApiToolConverter(DefaultOpenAPIService openApiService) { @@ -107,20 +105,12 @@ private McpSchema.Tool convertOperationToMcpTool( String toolName = generateToolName(op, toolConfig); String desc = generateToolDescription(op, toolConfig, path, method); - Map paramsSchemaMap = extractParameterSchema(op); - String schemaJson; - try { - schemaJson = objectMapper.writeValueAsString(paramsSchemaMap); - } catch (Exception e) { - logger.error( - LoggerCodeConstants.COMMON_UNEXPECTED_EXCEPTION, - "Failed to serialize parameter schema for tool {}: {}", - opId, - e.getMessage(), - e); - schemaJson = "{\"type\":\"object\",\"properties\":{}}"; - } - return new McpSchema.Tool(toolName, desc, schemaJson); + McpSchema.JsonSchema inputSchema = extractParameterSchema(op); + return McpSchema.Tool.builder() + .name(toolName) + .description(desc) + .inputSchema(inputSchema) + .build(); } private String generateToolName(Operation op, McpServiceFilter.McpToolConfig toolConfig) { @@ -155,10 +145,8 @@ private String generateToolDescription( return desc; } - private Map extractParameterSchema(Operation op) { - Map schema = new HashMap<>(); + private McpSchema.JsonSchema extractParameterSchema(Operation op) { Map props = new HashMap<>(); - schema.put(McpConstant.SCHEMA_PROPERTY_TYPE, JsonSchemaType.OBJECT_SCHEMA.getJsonSchemaType()); if (op.getParameters() != null) { for (Parameter apiParam : op.getParameters()) { @@ -313,8 +301,8 @@ private Map extractParameterSchema(Operation op) { } }); } - schema.put(McpConstant.SCHEMA_PROPERTY_PROPERTIES, props); - return schema; + return new McpSchema.JsonSchema( + JsonSchemaType.OBJECT_SCHEMA.getJsonSchemaType(), props, null, null, null, null); } private Map convertOpenApiSchemaToMcpMap(Schema openApiSchema) { diff --git a/dubbo-plugin/dubbo-mcp/src/main/java/org/apache/dubbo/mcp/tool/DubboServiceToolRegistry.java b/dubbo-plugin/dubbo-mcp/src/main/java/org/apache/dubbo/mcp/tool/DubboServiceToolRegistry.java index 552a68aa3989..cfb1cddcd0a9 100644 --- a/dubbo-plugin/dubbo-mcp/src/main/java/org/apache/dubbo/mcp/tool/DubboServiceToolRegistry.java +++ b/dubbo-plugin/dubbo-mcp/src/main/java/org/apache/dubbo/mcp/tool/DubboServiceToolRegistry.java @@ -42,7 +42,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiFunction; -import com.fasterxml.jackson.databind.ObjectMapper; import io.modelcontextprotocol.server.McpAsyncServer; import io.modelcontextprotocol.server.McpAsyncServerExchange; import io.modelcontextprotocol.server.McpServerFeatures; @@ -60,7 +59,6 @@ public class DubboServiceToolRegistry { private final McpServiceFilter mcpServiceFilter; private final Map registeredTools = new ConcurrentHashMap<>(); private final Map> serviceToToolsMapping = new ConcurrentHashMap<>(); - private final ObjectMapper objectMapper; public DubboServiceToolRegistry( McpAsyncServer mcpServer, @@ -71,7 +69,6 @@ public DubboServiceToolRegistry( this.toolConverter = toolConverter; this.genericCaller = genericCaller; this.mcpServiceFilter = mcpServiceFilter; - this.objectMapper = new ObjectMapper(); } public int registerService(ProviderModel providerModel) { @@ -191,7 +188,11 @@ private String registerMethodAsTool( description = generateDefaultDescription(method, providerModel); } - McpSchema.Tool mcpTool = new McpSchema.Tool(toolName, description, generateToolSchema(method)); + McpSchema.Tool mcpTool = McpSchema.Tool.builder() + .name(toolName) + .description(description) + .inputSchema(generateToolSchema(method)) + .build(); McpServerFeatures.AsyncToolSpecification toolSpec = createMethodToolSpecification(mcpTool, providerModel, method, url); @@ -369,32 +370,15 @@ private String generateDefaultDescription(Method method, ProviderModel providerM providerModel.getServiceModel().getInterfaceName()); } - private String generateToolSchema(Method method) { - Map schemaMap = new HashMap<>(); - schemaMap.put(McpConstant.SCHEMA_PROPERTY_TYPE, JsonSchemaType.OBJECT_SCHEMA.getJsonSchemaType()); - + private McpSchema.JsonSchema generateToolSchema(Method method) { Map properties = new HashMap<>(); List requiredParams = new ArrayList<>(); generateSchemaFromMethodSignature(method, properties, requiredParams); - schemaMap.put(McpConstant.SCHEMA_PROPERTY_PROPERTIES, properties); - - if (!requiredParams.isEmpty()) { - schemaMap.put(McpConstant.SCHEMA_PROPERTY_REQUIRED, requiredParams); - } - - try { - return objectMapper.writeValueAsString(schemaMap); - } catch (Exception e) { - logger.error( - LoggerCodeConstants.COMMON_UNEXPECTED_EXCEPTION, - "", - "", - "Failed to generate tool schema for method " + method.getName() + ": " + e.getMessage(), - e); - return "{\"type\":\"object\",\"properties\":{}}"; - } + List schemaRequiredParams = requiredParams.isEmpty() ? null : requiredParams; + return new McpSchema.JsonSchema( + JsonSchemaType.OBJECT_SCHEMA.getJsonSchemaType(), properties, schemaRequiredParams, null, null, null); } private void generateSchemaFromMethodSignature( diff --git a/dubbo-plugin/dubbo-mcp/src/main/java/org/apache/dubbo/mcp/transport/DubboMcpSseTransportProvider.java b/dubbo-plugin/dubbo-mcp/src/main/java/org/apache/dubbo/mcp/transport/DubboMcpSseTransportProvider.java index 2fce7725795b..ca8a9ea2b46e 100644 --- a/dubbo-plugin/dubbo-mcp/src/main/java/org/apache/dubbo/mcp/transport/DubboMcpSseTransportProvider.java +++ b/dubbo-plugin/dubbo-mcp/src/main/java/org/apache/dubbo/mcp/transport/DubboMcpSseTransportProvider.java @@ -37,8 +37,8 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; +import io.modelcontextprotocol.json.McpJsonMapper; +import io.modelcontextprotocol.json.TypeRef; import io.modelcontextprotocol.spec.McpError; import io.modelcontextprotocol.spec.McpSchema; import io.modelcontextprotocol.spec.McpServerSession; @@ -66,14 +66,14 @@ public class DubboMcpSseTransportProvider implements McpServerTransportProvider private McpServerSession.Factory sessionFactory; - private final ObjectMapper objectMapper; + private final McpJsonMapper mcpJsonMapper; /** * session cache, default expire time is 60 seconds */ private final ExpiringMap sessions; - public DubboMcpSseTransportProvider(ObjectMapper objectMapper, Integer expireSeconds) { + public DubboMcpSseTransportProvider(McpJsonMapper mcpJsonMapper, Integer expireSeconds) { if (expireSeconds != null) { if (expireSeconds < 60) { expireSeconds = 60; @@ -82,12 +82,12 @@ public DubboMcpSseTransportProvider(ObjectMapper objectMapper, Integer expireSec expireSeconds = 60; } sessions = new ExpiringMap<>(expireSeconds, 30); - this.objectMapper = objectMapper; + this.mcpJsonMapper = java.util.Objects.requireNonNull(mcpJsonMapper, "mcpJsonMapper must not be null"); sessions.getExpireThread().startExpiryIfNotStarted(); } - public DubboMcpSseTransportProvider(ObjectMapper objectMapper) { - this(objectMapper, 60); + public DubboMcpSseTransportProvider(McpJsonMapper mcpJsonMapper) { + this(mcpJsonMapper, 60); } @Override @@ -147,7 +147,7 @@ public void handleMessage() { refreshSessionExpire(session); try { McpSchema.JSONRPCMessage message = McpSchema.deserializeJsonRpcMessage( - objectMapper, IOUtils.read(request.inputStream(), String.valueOf(StandardCharsets.UTF_8))); + mcpJsonMapper, IOUtils.read(request.inputStream(), StandardCharsets.UTF_8.name())); session.handle(message).block(); response.setStatus(HttpStatus.OK.getCode()); } catch (IOException e) { @@ -160,7 +160,7 @@ private void handleSseConnection(StreamObserver> respons // Handle the SSE connection // This is where you would set up the SSE stream and send events to the client DubboMcpSessionTransport dubboMcpSessionTransport = - new DubboMcpSessionTransport(responseObserver, objectMapper); + new DubboMcpSessionTransport(responseObserver, mcpJsonMapper); McpServerSession mcpServerSession = sessionFactory.create(dubboMcpSessionTransport); sessions.put(mcpServerSession.getId(), mcpServerSession); Configuration conf = ConfigurationUtils.getGlobalConfiguration(ApplicationModel.defaultModel()); @@ -179,14 +179,14 @@ private void sendEvent(StreamObserver> responseObserver, private static class DubboMcpSessionTransport implements McpServerTransport { - private final ObjectMapper JSON; + private final McpJsonMapper mcpJsonMapper; private final StreamObserver> responseObserver; public DubboMcpSessionTransport( - StreamObserver> responseObserver, ObjectMapper objectMapper) { + StreamObserver> responseObserver, McpJsonMapper mcpJsonMapper) { this.responseObserver = responseObserver; - this.JSON = objectMapper; + this.mcpJsonMapper = mcpJsonMapper; } @Override @@ -203,7 +203,7 @@ public Mono closeGracefully() { public Mono sendMessage(McpSchema.JSONRPCMessage message) { return Mono.fromRunnable(() -> { try { - String jsonText = JSON.writeValueAsString(message); + String jsonText = mcpJsonMapper.writeValueAsString(message); responseObserver.onNext(ServerSentEvent.builder() .event(MESSAGE_EVENT_TYPE) .data(jsonText) @@ -215,8 +215,8 @@ public Mono sendMessage(McpSchema.JSONRPCMessage message) { } @Override - public T unmarshalFrom(Object data, TypeReference typeRef) { - return JSON.convertValue(data, typeRef); + public T unmarshalFrom(Object data, TypeRef typeRef) { + return mcpJsonMapper.convertValue(data, typeRef); } } } diff --git a/dubbo-plugin/dubbo-mcp/src/main/java/org/apache/dubbo/mcp/transport/DubboMcpStreamableTransportProvider.java b/dubbo-plugin/dubbo-mcp/src/main/java/org/apache/dubbo/mcp/transport/DubboMcpStreamableTransportProvider.java index 30478fcdb512..35d14e2d01f9 100644 --- a/dubbo-plugin/dubbo-mcp/src/main/java/org/apache/dubbo/mcp/transport/DubboMcpStreamableTransportProvider.java +++ b/dubbo-plugin/dubbo-mcp/src/main/java/org/apache/dubbo/mcp/transport/DubboMcpStreamableTransportProvider.java @@ -39,8 +39,8 @@ import java.util.ArrayList; import java.util.List; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; +import io.modelcontextprotocol.json.McpJsonMapper; +import io.modelcontextprotocol.json.TypeRef; import io.modelcontextprotocol.spec.McpError; import io.modelcontextprotocol.spec.McpSchema; import io.modelcontextprotocol.spec.McpStreamableServerSession; @@ -63,7 +63,7 @@ public class DubboMcpStreamableTransportProvider implements McpStreamableServerT private Factory sessionFactory; - private final ObjectMapper objectMapper; + private final McpJsonMapper mcpJsonMapper; public static final String SESSION_ID_HEADER = "mcp-session-id"; @@ -74,11 +74,11 @@ public class DubboMcpStreamableTransportProvider implements McpStreamableServerT */ private final ExpiringMap sessions; - public DubboMcpStreamableTransportProvider(ObjectMapper objectMapper) { - this(objectMapper, McpConstant.DEFAULT_SESSION_TIMEOUT); + public DubboMcpStreamableTransportProvider(McpJsonMapper mcpJsonMapper) { + this(mcpJsonMapper, McpConstant.DEFAULT_SESSION_TIMEOUT); } - public DubboMcpStreamableTransportProvider(ObjectMapper objectMapper, Integer expireSeconds) { + public DubboMcpStreamableTransportProvider(McpJsonMapper mcpJsonMapper, Integer expireSeconds) { // Minimum expiration time is 60 seconds if (expireSeconds != null) { if (expireSeconds < 60) { @@ -88,7 +88,7 @@ public DubboMcpStreamableTransportProvider(ObjectMapper objectMapper, Integer ex expireSeconds = 60; } sessions = new ExpiringMap<>(expireSeconds, 30); - this.objectMapper = objectMapper; + this.mcpJsonMapper = java.util.Objects.requireNonNull(mcpJsonMapper, "mcpJsonMapper must not be null"); sessions.getExpireThread().startExpiryIfNotStarted(); } @@ -208,7 +208,7 @@ private void handleGet(StreamObserver> responseObserver) message -> { if (responseObserver != null) { try { - String jsonData = objectMapper.writeValueAsString(message); + String jsonData = mcpJsonMapper.writeValueAsString(message); responseObserver.onNext(ServerSentEvent.builder() .event("message") .data(jsonData.getBytes(StandardCharsets.UTF_8)) @@ -296,7 +296,7 @@ private void handlePost(StreamObserver> responseObserver // Read and deserialize JSON-RPC message from request body String requestBody = IOUtils.read(request.inputStream(), StandardCharsets.UTF_8.name()); - McpSchema.JSONRPCMessage message = McpSchema.deserializeJsonRpcMessage(objectMapper, requestBody); + McpSchema.JSONRPCMessage message = McpSchema.deserializeJsonRpcMessage(mcpJsonMapper, requestBody); // Check if it's an initialization request if (message instanceof McpSchema.JSONRPCRequest @@ -318,8 +318,8 @@ private void handlePost(StreamObserver> responseObserver } // Create new session - McpSchema.InitializeRequest initializeRequest = objectMapper.convertValue( - ((McpSchema.JSONRPCRequest) message).params(), new TypeReference<>() {}); + McpSchema.InitializeRequest initializeRequest = mcpJsonMapper.convertValue( + ((McpSchema.JSONRPCRequest) message).params(), McpSchema.InitializeRequest.class); McpStreamableServerSession.McpStreamableServerSessionInit init = sessionFactory.startSession(initializeRequest); @@ -333,7 +333,7 @@ private void handlePost(StreamObserver> responseObserver response.setHeader(SESSION_ID_HEADER, session.getId()); response.setStatus(HttpStatus.OK.getCode()); - String jsonResponse = objectMapper.writeValueAsString(new McpSchema.JSONRPCResponse( + String jsonResponse = mcpJsonMapper.writeValueAsString(new McpSchema.JSONRPCResponse( McpSchema.JSONRPC_VERSION, ((McpSchema.JSONRPCRequest) message).id(), initResult, null)); if (responseObserver != null) { @@ -428,7 +428,7 @@ private void handlePost(StreamObserver> responseObserver // Handle request stream DubboMcpSessionTransport sessionTransport = - new DubboMcpSessionTransport(responseObserver, objectMapper); + new DubboMcpSessionTransport(responseObserver, mcpJsonMapper); session.responseStream((McpSchema.JSONRPCRequest) message, sessionTransport) .block(); } else { @@ -528,14 +528,14 @@ private void refreshSessionExpire(McpStreamableServerSession session) { private static class DubboMcpSessionTransport implements McpStreamableServerTransport { - private final ObjectMapper JSON; + private final McpJsonMapper mcpJsonMapper; private final StreamObserver> responseObserver; public DubboMcpSessionTransport( - StreamObserver> responseObserver, ObjectMapper objectMapper) { + StreamObserver> responseObserver, McpJsonMapper mcpJsonMapper) { this.responseObserver = responseObserver; - this.JSON = objectMapper; + this.mcpJsonMapper = mcpJsonMapper; } @Override @@ -555,7 +555,7 @@ public Mono sendMessage(McpSchema.JSONRPCMessage message) { return Mono.fromRunnable(() -> { try { if (responseObserver != null) { - String jsonText = JSON.writeValueAsString(message); + String jsonText = mcpJsonMapper.writeValueAsString(message); responseObserver.onNext(ServerSentEvent.builder() .event("message") .data(jsonText.getBytes(StandardCharsets.UTF_8)) @@ -572,7 +572,7 @@ public Mono sendMessage(McpSchema.JSONRPCMessage message, String messageId return Mono.fromRunnable(() -> { try { if (responseObserver != null) { - String jsonText = JSON.writeValueAsString(message); + String jsonText = mcpJsonMapper.writeValueAsString(message); ServerSentEvent event = ServerSentEvent.builder() .event("message") .data(jsonText.getBytes(StandardCharsets.UTF_8)) @@ -587,8 +587,8 @@ public Mono sendMessage(McpSchema.JSONRPCMessage message, String messageId } @Override - public T unmarshalFrom(Object data, TypeReference typeRef) { - return JSON.convertValue(data, typeRef); + public T unmarshalFrom(Object data, TypeRef typeRef) { + return mcpJsonMapper.convertValue(data, typeRef); } } } diff --git a/dubbo-plugin/dubbo-mcp/src/test/java/org/apache/dubbo/mcp/tool/DubboServiceToolRegistryTest.java b/dubbo-plugin/dubbo-mcp/src/test/java/org/apache/dubbo/mcp/tool/DubboServiceToolRegistryTest.java index 56416b82f022..aee6322241ef 100644 --- a/dubbo-plugin/dubbo-mcp/src/test/java/org/apache/dubbo/mcp/tool/DubboServiceToolRegistryTest.java +++ b/dubbo-plugin/dubbo-mcp/src/test/java/org/apache/dubbo/mcp/tool/DubboServiceToolRegistryTest.java @@ -201,8 +201,12 @@ private McpServiceFilter.McpToolConfig createMockToolConfig() { private java.util.Map createMockTools() { java.util.Map tools = new java.util.HashMap<>(); - io.modelcontextprotocol.spec.McpSchema.Tool tool = - new io.modelcontextprotocol.spec.McpSchema.Tool("testTool", "Test description", "{}"); + io.modelcontextprotocol.spec.McpSchema.Tool tool = io.modelcontextprotocol.spec.McpSchema.Tool.builder() + .name("testTool") + .description("Test description") + .inputSchema(new io.modelcontextprotocol.spec.McpSchema.JsonSchema( + "object", java.util.Collections.emptyMap(), null, null, null, null)) + .build(); tools.put("testTool", tool); return tools; } diff --git a/dubbo-plugin/dubbo-mcp/src/test/java/org/apache/dubbo/mcp/transport/DubboMcpSseTransportProviderTest.java b/dubbo-plugin/dubbo-mcp/src/test/java/org/apache/dubbo/mcp/transport/DubboMcpSseTransportProviderTest.java index bd92f8f870e1..5eb92d28d396 100644 --- a/dubbo-plugin/dubbo-mcp/src/test/java/org/apache/dubbo/mcp/transport/DubboMcpSseTransportProviderTest.java +++ b/dubbo-plugin/dubbo-mcp/src/test/java/org/apache/dubbo/mcp/transport/DubboMcpSseTransportProviderTest.java @@ -29,6 +29,7 @@ import java.io.ByteArrayInputStream; import com.fasterxml.jackson.databind.ObjectMapper; +import io.modelcontextprotocol.json.jackson2.JacksonMcpJsonMapper; import io.modelcontextprotocol.spec.McpSchema; import io.modelcontextprotocol.spec.McpServerSession; import org.junit.jupiter.api.AfterEach; @@ -37,7 +38,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; -import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockedStatic; import org.mockito.junit.jupiter.MockitoExtension; @@ -76,7 +76,6 @@ class DubboMcpSseTransportProviderTest { private MockedStatic rpcContextMockedStatic; - @InjectMocks private DubboMcpSseTransportProvider transportProvider; private final ObjectMapper objectMapper = new ObjectMapper(); @@ -87,7 +86,7 @@ void setUp() { rpcContextMockedStatic.when(RpcContext::getServiceContext).thenReturn(rpcServiceContext); when(rpcServiceContext.getRequest(HttpRequest.class)).thenReturn(httpRequest); when(rpcServiceContext.getResponse(HttpResponse.class)).thenReturn(httpResponse); - transportProvider = new DubboMcpSseTransportProvider(objectMapper); + transportProvider = new DubboMcpSseTransportProvider(new JacksonMcpJsonMapper(objectMapper)); transportProvider.setSessionFactory(sessionFactory); } diff --git a/dubbo-plugin/dubbo-mcp/src/test/java/org/apache/dubbo/mcp/transport/DubboMcpStreamableTransportProviderTest.java b/dubbo-plugin/dubbo-mcp/src/test/java/org/apache/dubbo/mcp/transport/DubboMcpStreamableTransportProviderTest.java index 71e0e1e6463d..b592d07fd49e 100644 --- a/dubbo-plugin/dubbo-mcp/src/test/java/org/apache/dubbo/mcp/transport/DubboMcpStreamableTransportProviderTest.java +++ b/dubbo-plugin/dubbo-mcp/src/test/java/org/apache/dubbo/mcp/transport/DubboMcpStreamableTransportProviderTest.java @@ -29,6 +29,7 @@ import java.util.Collections; import com.fasterxml.jackson.databind.ObjectMapper; +import io.modelcontextprotocol.json.jackson2.JacksonMcpJsonMapper; import io.modelcontextprotocol.spec.McpSchema; import io.modelcontextprotocol.spec.McpStreamableServerSession; import org.junit.jupiter.api.AfterEach; @@ -78,7 +79,7 @@ void setUp() { rpcContextMockedStatic.when(RpcContext::getServiceContext).thenReturn(rpcServiceContext); when(rpcServiceContext.getRequest(HttpRequest.class)).thenReturn(httpRequest); when(rpcServiceContext.getResponse(HttpResponse.class)).thenReturn(httpResponse); - transportProvider = new DubboMcpStreamableTransportProvider(objectMapper); + transportProvider = new DubboMcpStreamableTransportProvider(new JacksonMcpJsonMapper(objectMapper)); transportProvider.setSessionFactory(sessionFactory); } @@ -171,7 +172,7 @@ void handleGetReturnsNotFoundForUnknownSessionId() { void handleGetWithReplayRequestCallsSessionReplay() throws Exception { // Create a transport provider subclass for testing to access private methods and fields DubboMcpStreamableTransportProvider transportProviderUnderTest = - new DubboMcpStreamableTransportProvider(objectMapper); + new DubboMcpStreamableTransportProvider(new JacksonMcpJsonMapper(objectMapper)); transportProviderUnderTest.setSessionFactory(sessionFactory); // Use reflection to put mockSession into the sessions map