前言
看了第一小节如何通过Servlet实现MCP Server SSE的方式,我们接下来在此基础上,通过web mvc的方式来实现同样的功能。
环境要求
工具 | 版本 |
---|---|
JDK | 17或以上 |
SpringBoot | 3.0或以上 |
Tomcat | 10或以上 |
Maven | 3.8.3+,最好是3.9.x |
引入依赖
新建一个Springboot项目,目前Springboot最高版本是3.4.5,当前demo在3.0.0或以上都支持,并新增以下依赖。注意版本,截止2025-04-30,MCP Java SDK最新版本为0.9.0:
<dependencyManagement> <dependencies> <dependency> <groupId>io.modelcontextprotocol.sdk</groupId> <artifactId>mcp-bom</artifactId> <version>0.9.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement><dependencies> <dependency> <groupId>io.modelcontextprotocol.sdk</groupId> <artifactId>mcp-spring-webmvc</artifactId> </dependency></dependencies>
mcp-spring-webmvc是MCP官方针对spring mvc做的适配方案,适用于spring mvc项目集成MCP功能。
业务代码
我们依然使用上一节的OrderService作为我们这次示例的业务代码,通过订单号获取订单详情:
import org.springframework.stereotype.Service;@Servicepublic class OrderService {public OrderDetail getOrderDetail(String orderId) { OrderDetail orderDetail = new OrderDetail(); orderDetail.setOrderId(orderId);orderDetail.setDetail("订单详情");return orderDetail; }public static class OrderDetail { private String orderId; private String detail; public void setOrderId(String orderId) { this.orderId = orderId; } public String getOrderId() { return this.orderId; } public void setDetail(String detail) { this.detail = detail; } public String getDetail() { return this.detail; } @Override public String toString() { return "{\"orderId\":\"" + this.orderId + "\",\"detail\":\"" + this.detail+ "\"}"; }}}
编写MCP Server配置
因为我们这次是在Spring mvc的基础上集成mcp server,所以下面的配置和上一节Servlet的配置有所不同:
import com.fasterxml.jackson.databind.ObjectMapper;import io.modelcontextprotocol.server.transport.WebMvcSseServerTransportProvider;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.function.RouterFunction; import org.springframework.web.servlet.function.ServerResponse;@Configuration @EnableWebMvc public class McpConfig { @Bean WebMvcSseServerTransportProvider webMvcSseServerTransportProvider(ObjectMapper mapper) { return new WebMvcSseServerTransportProvider(mapper, "/mcp/message"); } @Bean RouterFunction<ServerResponse> mcpRouterFunction(WebMvcSseServerTransportProvider transportProvider) { return transportProvider.getRouterFunction(); }}
WebMvcSseServerTransportProvider是基于Spring mvc基础上实现了SSE通信方式,RouterFunction作用和ServletRegistrationBean类似,它里面针对/sse、/mcp/message请求做了路由处理,把这类请求都交给了WebMvcSseServerTransportProvider处理;
剩下的就是我们配置一个McpSyncServer Bean对象,并把需要暴露的业务接口配置到Tools里面去:
@Bean(destroyMethod = "close") public McpSyncServer mcpSyncServer(WebMvcSseServerTransportProvider transportProvider, OrderService orderService) { McpSyncServer mcpSyncServer = McpServer.sync(transportProvider) .serverInfo("my-server", "1.0.0") .capabilities(McpSchema.ServerCapabilities.builder() .tools(true) // Enable tool support .logging() // Enable logging support .build()) .build(); String jsonSchema = """ { "type":"object", "properties":{ "orderId" : { "type": "string", "description": "订单号" } }, "required":[ "orderId" ], "additionalProperties":false } """; // 方法的描述 McpSchema.Tool tool = new McpSchema.Tool("getOrderDetail", "通过订单号获取订单详情信息", jsonSchema); // 方法描述对应的执行逻辑 BiFunction<McpSyncServerExchange, Map<String, Object>, McpSchema.CallToolResult> call = (exchange, arguments) -> { OrderService.OrderDetail result = orderService.getOrderDetail(String.valueOf(arguments.get("orderId"))); return new McpSchema.CallToolResult(result.toString(), false); }; // 绑定描述和执行逻辑 McpServerFeatures.SyncToolSpecification toolHandler = new McpServerFeatures.SyncToolSpecification(tool, call); // 添加到工具集中 mcpSyncServer.addTool(toolHandler); return mcpSyncServer; }
我们在创建McpSyncServer时和上一小节的区别就是更换了transportProvider,之前使用的是HttpServletSseServerTransportProvider创建McpSyncServer,此次更换成使用WebMvcSseServerTransportProvider创建McpSyncServer,虽然本质上实现原理都一样,但是基于的框架是不同的,HttpServletSseServerTransportProvider的实现只依赖于Servlet,不需要Spring框架来支撑,而WebMvcSseServerTransportProvider是基于Spring mvc框架实现的。
测试
我们的测试方式完全可以参考上一小节使用cherry studio作为MCP Client验证,可按照以下图示进行配置:
如果按照上述图示配置没有异常,那么说明MCP Server启动成功,且能正常提供服务,并且可在工具栏看到我们暴露出来的接口: