原生Java SDK实现MCP Server(Stdio的通信方式)

前言

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即可:

xml 复制代码
<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>

业务代码

此次业务代码直接照搬前面的,通过订单号获取订单详情:

java 复制代码
import org.springframework.stereotype.Service;

@Service
public 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,不需要请求路由:

java 复制代码
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:

java 复制代码
@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包命令如下:

shell 复制代码
mvn clean package -DskipTests

或者也可以直接使用idea操作界面进行打包:

接下来我们就可以在项目中看到生成的target目录了,在target里面就有我们生成的jar文件:

测试

我们的jar包已经生成好了,接下来我们需要使用MCP Client来进行测试,确认我们的代码是没有问题的。依然还是使用cherry studio作为MCP Client验证:

如果按照上述图示配置没有异常,那么说明MCP Server启动成功,且能正常提供服务,并且可在工具栏看到我们暴露出来的接口:

相关推荐
booooooty8 分钟前
【Java项目设计】基于Springboot+Vue的OA办公自动化系统
java·vue.js·spring boot·毕业设计·课程设计·程序开发
白云如幻8 分钟前
【Java】HQL分页查询
java·hibernate
小猫咪怎么会有坏心思呢31 分钟前
华为OD机考-观看文艺汇演问题-区间问题(JAVA 2025B卷)
java·jvm
Java初学者小白1 小时前
秋招Day14 - MySQL - SQL优化
java·数据库·sql·mysql
Cyanto1 小时前
Tomcat双击startup.bat闪退的解决方法
java·tomcat
武昌库里写JAVA2 小时前
Vue状态管理实践:使用Vuex进行前端状态管理
java·vue.js·spring boot·课程设计·宠物管理
豆沙沙包?2 小时前
2025年- H83-Lc191--139.单词拆分(动态规划)--Java版
java·算法·动态规划
lovebugs2 小时前
百万并发下的生存之道:Java秒杀系统架构设计全解析
java·后端·架构
发仔1232 小时前
超硬核实战!用Java玩转Neo4j图数据库,轻松搞定复杂关系网!
java·数据库