核心io.modelcontextprotocol.sdk:mcp模块提供STDIO和SSE服务器传输实现,无需外部web框架。 Spring特定的传输实现可作为可选依赖项io.modelcontextprotocol.sdk:mcp-Spring-webflux、io.modelcontext protocol.sdk:mcp-sprinng-webmvc提供给Spring Framework用户。 这个基于Spring AI MCP的快速入门演示将向您展示如何构建MCP服务器。 服务器支持同步和异步API,允许在不同的应用程序上下文中灵活集成。
Copy
// Create a server with custom configuration
McpSyncServer syncServer = McpServer.sync(transportProvider)
.serverInfo("my-server", "1.0.0")
.capabilities(ServerCapabilities.builder()
.resources(false, true) // Enable resource support
.tools(true) // Enable tool support
.prompts(true) // Enable prompt support
.logging() // Enable logging support
.completions() // Enable completions support
.build())
.build();
// Register tools, resources, and prompts
syncServer.addTool(syncToolSpecification);
syncServer.addResource(syncResourceSpecification);
syncServer.addPrompt(syncPromptSpecification);
// Close the server when done
syncServer.close();
Copy
// Create a server with custom configuration
McpSyncServer syncServer = McpServer.sync(transportProvider)
.serverInfo("my-server", "1.0.0")
.capabilities(ServerCapabilities.builder()
.resources(false, true) // Enable resource support
.tools(true) // Enable tool support
.prompts(true) // Enable prompt support
.logging() // Enable logging support
.completions() // Enable completions support
.build())
.build();
// Register tools, resources, and prompts
syncServer.addTool(syncToolSpecification);
syncServer.addResource(syncResourceSpecification);
syncServer.addPrompt(syncPromptSpecification);
// Close the server when done
syncServer.close();
Creates a Servlet-based SSE server transport. It is included in the core mcp module. The HttpServletSseServerTransport can be used with any Servlet container. To use it with a Spring Web application, you can register it as a Servlet bean:
Copy
StdioServerTransportProvider transportProvider = new StdioServerTransportProvider(new ObjectMapper());
Creates WebFlux-based SSE server transport. Requires the mcp-spring-webflux dependency.
Creates a Servlet-based SSE server transport. It is included in the core mcp module. The HttpServletSseServerTransport can be used with any Servlet container. To use it with a Spring Web application, you can register it as a Servlet bean:
Copy
@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);
}
}
var capabilities = ServerCapabilities.builder()
.resources(false, true) // Resource support with list changes notifications
.tools(true) // Tool support with list changes notifications
.prompts(true) // Prompt support with list changes notifications
.logging() // Enable logging support (enabled by default with logging level INFO)
.build();
日志记录支持
服务器提供结构化日志记录功能,允许向具有不同严重级别的客户端发送日志消息:
// Send a log message to clients
server.loggingNotification(LoggingMessageNotification.builder()
.level(LoggingLevel.INFO)
.logger("custom-logger")
.data("Custom log message")
.build());
// Create a server
McpSyncServer server = McpServer.sync(transportProvider)
.serverInfo("my-server", "1.0.0")
.build();
// Define a tool that uses sampling
var calculatorTool = new McpServerFeatures.SyncToolSpecification(
new Tool("ai-calculator", "Performs calculations using AI", schema),
(exchange, arguments) -> {
// Check if client supports sampling
if (exchange.getClientCapabilities().sampling() == null) {
return new CallToolResult("Client does not support AI capabilities", false);
}
// Create a sampling request
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) // Prioritize intelligence
.speedPriority(0.5) // Moderate speed importance
.build())
.systemPrompt("You are a helpful calculator assistant. Provide only the numerical answer.")
.maxTokens(100)
.build();
// Request sampling from the client
McpSchema.CreateMessageResult result = exchange.createMessage(request);
// Process the result
String answer = result.content().text();
return new CallToolResult(answer, false);
}
);
// Add the tool to the server
server.addTool(calculatorTool);
Copy
// Create a server
McpAsyncServer server = McpServer.async(transportProvider)
.serverInfo("my-server", "1.0.0")
.build();
// Define a tool that uses sampling
var calculatorTool = new McpServerFeatures.AsyncToolSpecification(
new Tool("ai-calculator", "Performs calculations using AI", schema),
(exchange, arguments) -> {
// Check if client supports sampling
if (exchange.getClientCapabilities().sampling() == null) {
return Mono.just(new CallToolResult("Client does not support AI capabilities", false));
}
// Create a sampling request
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) // Prioritize intelligence
.speedPriority(0.5) // Moderate speed importance
.build())
.systemPrompt("You are a helpful calculator assistant. Provide only the numerical answer.")
.maxTokens(100)
.build();
// Request sampling from the client
return exchange.createMessage(request)
.map(result -> {
// Process the result
String answer = result.content().text();
return new CallToolResult(answer, false);
});
}
);
// Add the tool to the server
server.addTool(calculatorTool)
.subscribe();