前言
stdio的通信方式是基于操作系统的标准输入输出进行数据交换的,那么意味着MCP Client和MCP Server要求部署在同一台计算上,接下来我们开始实战如何实现使用Java SDK实现stdio通信方式的MCP Server。
环境要求
工具 | 版本 |
---|---|
JDK | 17或以上 |
SpringBoot | 3.0或以上 |
Maven | 3.8.3+,最好是3.9.x |
因为是基于操作系统标准输入输出进行数据交换的,所以不需要tomcat。从本质上来说,我们其实也可以不需要Springboot,但是为了能够快速构建项目,依然还是使用Springboot框架。
引入依赖
创建Springboot项目,记得选择jar包开始创建项目,因为stdio本地通信需要把MCP Server打成jar包来调用,然后我们只要引入最基本的MCP Java SDK即可:
<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</artifactId> </dependency></dependencies>
业务代码
此次业务代码直接照搬前面的,通过订单号获取订单详情:
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配置
1、stdio基于操作系统标准输入输出进行通信,所以这次只需要配置对应的TransportProvider,不需要请求路由:
import io.modelcontextprotocol.server.transport.StdioServerTransportProvider;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;@Configuration public class McpServerConfig { @Bean public StdioServerTransportProvider transportProvider() { return new StdioServerTransportProvider(); }}
2、配置McpSyncServer,这一步都是必备的,目的是为了暴露我们的业务方法给MCP Client:
@Bean public McpSyncServer mcpSyncServer(StdioServerTransportProvider transportProvider, OrderService orderService) { McpSyncServer mcpSyncServer = McpServer.sync(transportProvider) .serverInfo("my-server", "1.0.0") .capabilities(McpSchema.SeerCapabilities.builder().tools(true) .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; }
项目打包
项目代码全部编写完毕后,接下来就是要把项目打成jar包,因为MCP Client需要通过java -jar命令启动MCP Server服务,打jar包命令如下:
mvn clean package -DskipTests
或者也可以直接使用idea操作界面进行打包:
接下来我们就可以在项目中看到生成的target目录了,在target里面就有我们生成的jar文件:
测试
我们的jar包已经生成好了,接下来我们需要使用MCP Client来进行测试,确认我们的代码是没有问题的。依然还是使用cherry studio作为MCP Client验证:
如果按照上述图示配置没有异常,那么说明MCP Server启动成功,且能正常提供服务,并且可在工具栏看到我们暴露出来的接口: