0.8.x 版本中的重大变化 ⚠️
注意: 0.8.x 版本引入了多个重大变化,包括新的基于会话的架构。
如果您从 0.7.0 版本升级,请参考 迁移指南 以获取详细说明。
MCP 服务器是 Model Context Protocol (MCP) 架构中的基础组件,向客户端提供工具、资源和功能。它实现了协议的服务器端部分,负责:
- 暴露客户端可以发现和执行的工具
- 使用基于 URI 的访问模式管理资源
- 提供提示模板并处理提示请求
- 支持与客户端的功能协商
- 实现服务器端协议操作
- 管理并发客户端连接
- 提供结构化日志和通知
核心 io.modelcontextprotocol.sdk:mcp
模块提供了 STDIO 和 SSE 服务器传输实现,无需外部 Web 框架。
对于 Spring Framework 用户,Spring 特定的传输实现作为可选依赖 io.modelcontextprotocol.sdk:mcp-spring-webflux
和 io.modelcontextprotocol.sdk:mcp-spring-webmvc
提供。
服务器支持同步和异步 API,允许在不同应用场景中灵活集成。
// 使用自定义配置创建服务器
McpSyncServer syncServer = McpServer.sync(transportProvider)
.serverInfo("my-server", "1.0.0")
.capabilities(ServerCapabilities.builder()
.resources(true) // 启用资源支持
.tools(true) // 启用工具支持
.prompts(true) // 启用提示支持
.logging() // 启用日志支持
.build())
.build();
// 注册工具、资源和提示
syncServer.addTool(syncToolSpecification);
syncServer.addResource(syncResourceSpecification);
syncServer.addPrompt(syncPromptSpecification);
// 发送日志通知
syncServer.loggingNotification(LoggingMessageNotification.builder()
.level(LoggingLevel.INFO)
.logger("custom-logger")
.data("Server initialized")
.build());
// 完成后关闭服务器
syncServer.close();
// 使用自定义配置创建服务器
McpSyncServer syncServer = McpServer.sync(transportProvider)
.serverInfo("my-server", "1.0.0")
.capabilities(ServerCapabilities.builder()
.resources(true) // 启用资源支持
.tools(true) // 启用工具支持
.prompts(true) // 启用提示支持
.logging() // 启用日志支持
.build())
.build();
// 注册工具、资源和提示
syncServer.addTool(syncToolSpecification);
syncServer.addResource(syncResourceSpecification);
syncServer.addPrompt(syncPromptSpecification);
// 发送日志通知
syncServer.loggingNotification(LoggingMessageNotification.builder()
.level(LoggingLevel.INFO)
.logger("custom-logger")
.data("Server initialized")
.build());
// 完成后关闭服务器
syncServer.close();
McpAsyncServer asyncServer = McpServer.async(transportProvider)
.serverInfo("my-server", "1.0.0")
.capabilities(ServerCapabilities.builder()
.resources(true) // 启用资源支持
.tools(true) // 启用工具支持
.prompts(true) // 启用提示支持
.logging() // 启用日志支持
.build())
.build();
// 注册工具、资源和提示
asyncServer.addTool(asyncToolSpecification)
.doOnSuccess(v -> logger.info("Tool registered"))
.subscribe();
asyncServer.addResource(asyncResourceSpecification)
.doOnSuccess(v -> logger.info("Resource registered"))
.subscribe();
asyncServer.addPrompt(asyncPromptSpecification)
.doOnSuccess(v -> logger.info("Prompt registered"))
.subscribe();
// 发送日志通知
asyncServer.loggingNotification(LoggingMessageNotification.builder()
.level(LoggingLevel.INFO)
.logger("custom-logger")
.data("Server initialized")
.build());
// 完成后关闭服务器
asyncServer.close()
.doOnSuccess(v -> logger.info("Server closed"))
.subscribe();
服务器传输提供者
MCP SDK 中的传输层负责处理客户端和服务器之间的通信。它提供了不同的实现以支持各种通信协议和模式。SDK 包括几个内置的传输提供者实现:
创建基于进程内的传输:
StdioServerTransportProvider transportProvider = new StdioServerTransportProvider(new ObjectMapper());
通过标准输入/输出流提供双向 JSON-RPC 消息处理,支持非阻塞消息处理、序列化/反序列化和优雅关闭。
关键功能:
- 通过 stdin/stdout 进行双向通信
- 支持基于进程的集成
- 简单设置和配置
- 轻量级实现
创建基于进程内的传输:
StdioServerTransportProvider transportProvider = new StdioServerTransportProvider(new ObjectMapper());
通过标准输入/输出流提供双向 JSON-RPC 消息处理,支持非阻塞消息处理、序列化/反序列化和优雅关闭。
关键功能:
- 通过 stdin/stdout 进行双向通信
- 支持基于进程的集成
- 简单设置和配置
- 轻量级实现
创建基于 WebFlux 的 SSE 服务器传输。
需要 mcp-spring-webflux
依赖。
@Configuration
class McpConfig {
@Bean
WebFluxSseServerTransportProvider webFluxSseServerTransportProvider(ObjectMapper mapper) {
return new WebFluxSseServerTransportProvider(mapper, "/mcp/message");
}
@Bean
RouterFunction<?> mcpRouterFunction(WebFluxSseServerTransportProvider transportProvider) {
return transportProvider.getRouterFunction();
}
}
实现 MCP HTTP 与 SSE 传输规范,提供:
- 使用 WebFlux 的响应式 HTTP 流
- 通过 SSE 端点支持并发客户端连接
- 消息路由和会话管理
- 优雅关闭功能
创建基于 WebMvc 的 SSE 服务器传输。
需要 mcp-spring-webmvc
依赖。
@Configuration
@EnableWebMvc
class McpConfig {
@Bean
WebMvcSseServerTransportProvider webMvcSseServerTransportProvider(ObjectMapper mapper) {
return new WebMvcSseServerTransportProvider(mapper, "/mcp/message");
}
@Bean
RouterFunction<ServerResponse> mcpRouterFunction(WebMvcSseServerTransportProvider transportProvider) {
return transportProvider.getRouterFunction();
}
}
实现 MCP HTTP 与 SSE 传输规范,提供:
- 服务器端事件流
- 与 Spring WebMVC 集成
- 支持传统 Web 应用程序
- 同步操作处理
创建基于 Servlet 的 SSE 服务器传输。包含在核心 mcp
模块中。
HttpServletSseServerTransport
可以与任何 Servlet 容器一起使用。
要在 Spring Web 应用程序中使用它,可以将其注册为 Servlet bean:
@Configuration
@EnableWebMvc
public class McpServerConfig implements WebMvcConfigurer {
@Bean
public HttpServletSseServerTransportProvider servletSseServerTransportProvider() {
return new HttpServletSseServerTransportProvider(new ObjectMapper(), "/mcp/message");
}
@Bean
public ServletRegistrationBean customServletBean(HttpServletSseServerTransportProvider transportProvider) {
return new ServletRegistrationBean(transportProvider);
}
}
使用传统的 Servlet API 实现 MCP HTTP 与 SSE 传输规范,提供:
- 使用 Servlet 6.0 异步支持的异步消息处理
- 多个客户端连接的会话管理
两种类型的端点:
- SSE 端点(
/sse
)用于服务器到客户端的事件 - 消息端点(可配置)用于客户端到服务器的请求
- 错误处理和响应格式化
- 优雅关闭支持
服务器功能
服务器可以配置各种功能:
var capabilities = ServerCapabilities.builder()
.resources(false, true) // 资源支持,带列表变更通知
.tools(true) // 工具支持,带列表变更通知
.prompts(true) // 提示支持,带列表变更通知
.logging() // 启用日志支持(默认启用,日志级别为 INFO)
.build();
日志支持
服务器提供结构化日志功能,允许以不同严重级别向客户端发送日志消息:
// 向客户端发送日志消息
server.loggingNotification(LoggingMessageNotification.builder()
.level(LoggingLevel.INFO)
.logger("custom-logger")
.data("Custom log message")
.build());
客户端可以通过 mcpClient.setLoggingLevel(level)
请求控制他们接收的最低日志级别。低于设置级别的消息将被过滤掉。
支持的日志级别(按严重性递增顺序):DEBUG (0), INFO (1), NOTICE (2), WARNING (3), ERROR (4), CRITICAL (5), ALERT (6), EMERGENCY (7)
工具规范
Model Context Protocol 允许服务器 暴露工具,这些工具可以被语言模型调用。Java SDK 允许实现工具规范及其处理函数。工具使 AI 模型能够执行计算、访问外部 API、查询数据库和操作文件:
// 同步工具规范
var schema = """
{
"type" : "object",
"id" : "urn:jsonschema:Operation",
"properties" : {
"operation" : {
"type" : "string"
},
"a" : {
"type" : "number"
},
"b" : {
"type" : "number"
}
}
}
""";
var syncToolSpecification = new McpServerFeatures.SyncToolSpecification(
new Tool("calculator", "Basic calculator", schema),
(exchange, arguments) -> {
// 工具实现
return new CallToolResult(result, false);
}
);
// 同步工具规范
var schema = """
{
"type" : "object",
"id" : "urn:jsonschema:Operation",
"properties" : {
"operation" : {
"type" : "string"
},
"a" : {
"type" : "number"
},
"b" : {
"type" : "number"
}
}
}
""";
var syncToolSpecification = new McpServerFeatures.SyncToolSpecification(
new Tool("calculator", "Basic calculator", schema),
(exchange, arguments) -> {
// 工具实现
return new CallToolResult(result, false);
}
);
// 异步工具规范
var schema = """
{
"type" : "object",
"id" : "urn:jsonschema:Operation",
"properties" : {
"operation" : {
"type" : "string"
},
"a" : {
"type" : "number"
},
"b" : {
"type" : "number"
}
}
}
""";
var asyncToolSpecification = new McpServerFeatures.AsyncToolSpecification(
new Tool("calculator", "Basic calculator", schema),
(exchange, arguments) -> {
// 工具实现
return Mono.just(new CallToolResult(result, false));
}
);
工具规范包括工具定义,包含 name
、description
和 parameter schema
,后跟实现工具逻辑的调用处理程序。函数的第一个参数是 McpAsyncServerExchange
,用于客户端交互,第二个参数是工具参数的映射。
资源规范
资源及其处理函数的规范。资源通过暴露数据为 AI 模型提供上下文,例如:文件内容、数据库记录、API 响应、系统信息、应用程序状态。示例资源规范:
// 同步资源规范
var syncResourceSpecification = new McpServerFeatures.syncResourceSpecification(
new Resource("custom://resource", "name", "description", "mime-type", null),
(exchange, request) -> {
// 资源读取实现
return new ReadResourceResult(contents);
}
);
// 同步资源规范
var syncResourceSpecification = new McpServerFeatures.syncResourceSpecification(
new Resource("custom://resource", "name", "description", "mime-type", null),
(exchange, request) -> {
// 资源读取实现
return new ReadResourceResult(contents);
}
);
// 异步资源规范
var asyncResourceSpecification = new McpServerFeatures.asyncResourceSpecification(
new Resource("custom://resource", "name", "description", "mime-type", null),
(exchange, request) -> {
// 资源读取实现
return Mono.just(new ReadResourceResult(contents));
}
);
资源规范由资源定义和资源读取处理程序组成。资源定义包括 name
、description
和 MIME type
。处理资源读取请求的函数的第一个参数是 McpAsyncServerExchange
,服务器可以通过它与连接的客户端交互。第二个参数是 McpSchema.ReadResourceRequest
。
提示规范
作为 提示功能 的一部分,MCP 为服务器提供了一种标准化的方式来向客户端暴露提示模板。提示规范是用于 AI 模型交互的结构化模板,支持一致的消息格式化、参数替换、上下文注入、响应格式化和指令模板化。
// 同步提示规范
var syncPromptSpecification = new McpServerFeatures.syncPromptSpecification(
new Prompt("greeting", "description", List.of(
new PromptArgument("name", "description", true)
)),
(exchange, request) -> {
// 提示实现
return new GetPromptResult(description, messages);
}
);
// 同步提示规范
var syncPromptSpecification = new McpServerFeatures.syncPromptSpecification(
new Prompt("greeting", "description", List.of(
new PromptArgument("name", "description", true)
)),
(exchange, request) -> {
// 提示实现
return new GetPromptResult(description, messages);
}
);
// 异步提示规范
var asyncPromptSpecification = new McpServerFeatures.asyncPromptSpecification(
new Prompt("greeting", "description", List.of(
new PromptArgument("name", "description", true)
)),
(exchange, request) -> {
// 提示实现
return Mono.just(new GetPromptResult(description, messages));
}
);
提示定义包括名称(提示的标识符)、描述(提示的用途)和参数列表(用于模板化的参数)。处理函数处理请求并返回格式化的模板。第一个参数是 McpAsyncServerExchange
,用于客户端交互,第二个参数是 GetPromptRequest
实例。
从服务器使用采样
要使用 采样功能,请连接到支持采样的客户端。无需特殊的服务器配置,但在发出请求前请验证客户端的采样支持。了解 客户端采样支持。
一旦连接到兼容的客户端,服务器可以请求语言模型生成:
// 创建服务器
McpSyncServer server = McpServer.sync(transportProvider)
.serverInfo("my-server", "1.0.0")
.build();
// 定义使用采样的工具
var calculatorTool = new McpServerFeatures.SyncToolSpecification(
new Tool("ai-calculator", "Performs calculations using AI", schema),
(exchange, arguments) -> {
// 检查客户端是否支持采样
if (exchange.getClientCapabilities().sampling() == null) {
return new CallToolResult("Client does not support AI capabilities", false);
}
// 创建采样请求
McpSchema.CreateMessageRequest request = McpSchema.CreateMessageRequest.builder()
.messages(List.of(new McpSchema.SamplingMessage(McpSchema.Role.USER,
new McpSchema.TextContent("Calculate: " + arguments.get("expression")))
.modelPreferences(McpSchema.ModelPreferences.builder()
.hints(List.of(
McpSchema.ModelHint.of("claude-3-sonnet"),
McpSchema.ModelHint.of("claude")
))
.intelligencePriority(0.8) // 优先考虑智能
.speedPriority(0.5) // 中等速度重要性
.build())
.systemPrompt("You are a helpful calculator assistant. Provide only the numerical answer.")
.maxTokens(100)
.build();
// 向客户端请求采样
McpSchema.CreateMessageResult result = exchange.createMessage(request);
// 处理结果
String answer = result.content().text();
return new CallToolResult(answer, false);
}
);
// 将工具添加到服务器
server.addTool(calculatorTool);
// 创建服务器
McpSyncServer server = McpServer.sync(transportProvider)
.serverInfo("my-server", "1.0.0")
.build();
// 定义使用采样的工具
var calculatorTool = new McpServerFeatures.SyncToolSpecification(
new Tool("ai-calculator", "Performs calculations using AI", schema),
(exchange, arguments) -> {
// 检查客户端是否支持采样
if (exchange.getClientCapabilities().sampling() == null) {
return new CallToolResult("Client does not support AI capabilities", false);
}
// 创建采样请求
McpSchema.CreateMessageRequest request = McpSchema.CreateMessageRequest.builder()
.messages(List.of(new McpSchema.SamplingMessage(McpSchema.Role.USER,
new McpSchema.TextContent("Calculate: " + arguments.get("expression")))
.modelPreferences(McpSchema.ModelPreferences.builder()
.hints(List.of(
McpSchema.ModelHint.of("claude-3-sonnet"),
McpSchema.ModelHint.of("claude")
))
.intelligencePriority(0.8) // 优先考虑智能
.speedPriority(0.5) // 中等速度重要性
.build())
.systemPrompt("You are a helpful calculator assistant. Provide only the numerical answer.")
.maxTokens(100)
.build();
// 向客户端请求采样
McpSchema.CreateMessageResult result = exchange.createMessage(request);
// 处理结果
String answer = result.content().text();
return new CallToolResult(answer, false);
}
);
// 将工具添加到服务器
server.addTool(calculatorTool);
// 创建服务器
McpAsyncServer server = McpServer.async(transportProvider)
.serverInfo("my-server", "1.0.0")
.build();
// 定义使用采样的工具
var calculatorTool = new McpServerFeatures.AsyncToolSpecification(
new Tool("ai-calculator", "Performs calculations using AI", schema),
(exchange, arguments) -> {
// 检查客户端是否支持采样
if (exchange.getClientCapabilities().sampling() == null) {
return Mono.just(new CallToolResult("Client does not support AI capabilities", false));
}
// 创建采样请求
McpSchema.CreateMessageRequest request = McpSchema.CreateMessageRequest.builder()
.content(new McpSchema.TextContent("Calculate: " + arguments.get("expression")))
.modelPreferences(McpSchema.ModelPreferences.builder()
.hints(List.of(
McpSchema.ModelHint.of("claude-3-sonnet"),
McpSchema.ModelHint.of("claude")
))
.intelligencePriority(0.8) // 优先考虑智能
.speedPriority(0.5) // 中等速度重要性
.build())
.systemPrompt("You are a helpful calculator assistant. Provide only the numerical answer.")
.maxTokens(100)
.build();
// 向客户端请求采样
return exchange.createMessage(request)
.map(result -> {
// 处理结果
String answer = result.content().text();
return new CallToolResult(answer, false);
});
}
);
// 将工具添加到服务器
server.addTool(calculatorTool)
.subscribe();
CreateMessageRequest
对象允许您指定:Content
- 模型的输入文本或图像,Model Preferences
- 模型选择的提示和优先级,System Prompt
- 模型行为的指令和 Max Tokens
- 生成响应的最大长度。
错误处理
SDK 通过 McpError 类提供了全面的错误处理,涵盖协议兼容性、传输通信、JSON-RPC 消息传递、工具执行、资源管理、提示处理、超时和连接问题。这种统一的错误处理方法确保了在同步和异步操作中一致且可靠的错误管理。