原生Java SDK实现MCP Server(基于WebFlux的SSE通信方式)

前言

MCP官方除了为Spring mvc定制sdk,另外还为响应式编程的WebFlux定制了对应的sdk,以便使用Spring WebFlux的项目也能很方便地接入MCP服务。下面我们就快速开始,看看如何在Spring WebFlux项目中接入MCP Server吧。

环境要求

工具 版本
JDK 17或以上
SpringBoot 3.0或以上
Tomcat 10或以上
Maven 3.8.3+,最好是3.9.x

引入依赖

我们依然还是先创建一个最基本的SpringBoot项目,然后在此基础上新增以下依赖。注意版本,截止2025-04-30,MCP Java SDK最新版本为0.9.0:

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-spring-webflux</artifactId>  
	</dependency>
</dependencies>

注意:如果依赖中有spring-boot-starter-web依赖,需要更换成spring-boot-starter-webflux:

xml 复制代码
<dependency>  
	<groupId>org.springframework.boot</groupId>  
	<artifactId>spring-boot-starter-webflux</artifactId>  
</dependency>

另外就是需要把@EnableWebMvc去掉,开启@EnableWebFlux,避免服务启动后产生404错误;

业务代码

目前在这几个demo当中,我们使用的业务代码都是同一套,通过订单号获取订单详情:

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、首先我们依然是配置SSE的通信方式,这个取决于TransportProvider,WebFlux的实现类是WebFluxSseServerTransportProvider,并且通过新增RouterFunction把/sse、/mcp/message请求交给WebFluxSseServerTransportProvider处理:

java 复制代码
import com.fasterxml.jackson.databind.ObjectMapper;
import io.modelcontextprotocol.server.transport.WebFluxSseServerTransportProvider;
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.web.reactive.config.EnableWebFlux;  
import org.springframework.web.reactive.function.server.RouterFunction;

@EnableWebFlux  
@Configuration  
class McpConfig {  
	@Bean  
	WebFluxSseServerTransportProvider webFluxSseServerTransportProvider(ObjectMapper mapper) {  
		return new WebFluxSseServerTransportProvider(mapper, "/mcp/message");  
	}  
  
	@Bean  
	RouterFunction<?> mcpRouterFunction(WebFluxSseServerTransportProvider transportProvider) {  
		return transportProvider.getRouterFunction();  
	}
}

2、接下来依然还是配置McpSyncServer对象,这次传入的TransportProvider对象是WebFluxSseServerTransportProvider:

java 复制代码
@Bean(destroyMethod = "close")  
public McpSyncServer mcpSyncServer(WebFluxSseServerTransportProvider transportProvider,  
OrderService orderService) {  
	McpSyncServer mcpSyncServer = McpServer.sync(transportProvider)  
	.serverInfo("my-server", "1.0.0")  
	.capabilities(McpSchema.ServerCapabilities.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;  
}

测试

现在我们所有的代码都编写完毕,接下来依然通过cherry studio作为MCP Client验证,可按照以下图示进行配置:

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

相关推荐
zhanghe6877 小时前
es的密码带有特殊字符,导出
java
pnoker7 小时前
IoT DC3 概念解读:把设备抽象成一套语义模板——位号、指令、事件与面向智能体的设备建模
java·人工智能·物联网·iot·dc3
my_realmy7 小时前
Java SE 基础学习笔记(一):面向对象、继承多态、抽象接口与异常(JDK 8)
java·多线程·并发··生产者消费者模式
天远数科8 小时前
风险治理实战:基于天远车信盟出险构建自动化理赔核保流水线
java·网络·人工智能·自动化
骇客野人8 小时前
SpringBoot电商系统用户注册、登录、留存及数据埋点设计与落地实施方案
java·spring boot·后端
qiuhaipeng18 小时前
Claude code 升级后上下文长度变短问题
java·前端·数据库
霸道流氓气质9 小时前
Spring AI 输出解析器进阶
人工智能·windows·spring
wxwx_bscxy3229 小时前
基于Python新冠疫情可视化分析系统的设计与实现
java·数据库·spring boot·python·微信小程序·sqlite
evans在进步10 小时前
Tomcat NIO 工作原理详解:从 Acceptor、Poller 到容器处理链
java·tomcat·nio
渡我白衣12 小时前
并查集:基础认识与模拟实现
android·java·javascript·数据结构·c++·算法·并查集