掘金 人工智能 05月31日 21:03
原生Java SDK实现MCP Server(基于WebMvc的SSE通信方式)
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文介绍了如何在Spring MVC框架中集成MCP Server,实现与客户端的SSE通信。通过引入mcp-spring-webmvc依赖,并配置WebMvcSseServerTransportProvider和RouterFunction,可以轻松地将MCP功能集成到现有的Spring MVC项目中。文章还展示了如何将业务代码(如订单服务)暴露为MCP工具,并通过cherry studio进行测试验证,确保MCP Server正常运行并提供服务。与Servlet实现方式相比,该方案更适用于Spring MVC项目,简化了集成过程。

🛠️ 引入`mcp-spring-webmvc`依赖,该依赖是MCP官方针对Spring MVC做的适配方案,适用于Spring MVC项目集成MCP功能。

⚙️ 配置`WebMvcSseServerTransportProvider`,它是基于Spring MVC实现的SSE通信方式,并使用`RouterFunction`处理`/sse`和`/mcp/message`请求,将这些请求交给`WebMvcSseServerTransportProvider`处理。

🧩 创建`McpSyncServer` Bean对象,并使用`McpSchema.Tool`定义需要暴露的业务接口(例如,通过订单号获取订单详情),然后通过`addTool`方法将工具添加到工具集中。

🧪 使用cherry studio作为MCP Client进行测试验证,确保MCP Server启动成功,并且能够正常提供服务,同时验证暴露的接口是否能够在工具栏中正确显示。

前言

看了第一小节如何通过Servlet实现MCP Server SSE的方式,我们接下来在此基础上,通过web mvc的方式来实现同样的功能。

环境要求

工具版本
JDK17或以上
SpringBoot3.0或以上
Tomcat10或以上
Maven3.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启动成功,且能正常提供服务,并且可在工具栏看到我们暴露出来的接口:

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

Spring MVC MCP Server SSE通信 WebMvcSseServerTransportProvider
相关文章