Spring Boot Starter for building Model Context Protocol (MCP) servers with auto-configuration, annotation-based tool/resource/prompt definitions, and support for STDIO, SSE, and Streamable-HTTP transports
Spring Boot starter for building Model Context Protocol (MCP) servers with auto-configuration, annotation-based definitions, and multiple transport protocols.
| Aspect | Details |
|---|---|
| Package | org.springframework.ai:spring-ai-starter-mcp-server |
| Type | Maven Spring Boot Starter |
| Language | Java |
| Protocols | STDIO, SSE, Streamable-HTTP, Stateless |
| Server Types | Synchronous (SYNC), Asynchronous (ASYNC) |
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server</artifactId>
</dependency>@SpringBootApplication
public class MyMcpServerApplication {
public static void main(String[] args) {
SpringApplication.run(MyMcpServerApplication.class, args);
}
}
@Component
public class MyTools {
@McpTool(name = "add", description = "Add two numbers")
public int add(
@McpToolParam(description = "First number", required = true) int a,
@McpToolParam(description = "Second number", required = true) int b) {
return a + b;
}
}spring.ai.mcp.server.stdio=true
spring.ai.mcp.server.name=my-mcp-server
spring.ai.mcp.server.version=1.0.0| Annotation | Purpose | Example |
|---|---|---|
@McpTool | Define executable tool | @McpTool(name = "calc") |
@McpResource | Define resource | @McpResource(uri = "config://{key}") |
@McpPrompt | Define prompt template | @McpPrompt(name = "greeting") |
@McpComplete | Define completion | @McpComplete(prompt = "city") |
| Protocol | Use Case | Configuration |
|---|---|---|
| STDIO | CLI tools | spring.ai.mcp.server.stdio=true |
| SSE | Web apps (default) | spring.ai.mcp.server.protocol=SSE |
| Streamable | HTTP streaming | spring.ai.mcp.server.protocol=STREAMABLE |
| Stateless | Scalable deployments | spring.ai.mcp.server.protocol=STATELESS |
| Type | Execution Model | Return Types |
|---|---|---|
| SYNC | Blocking operations | Primitives, Objects, MCP types |
| ASYNC | Reactive operations | Mono<T>, Flux<T> |
// Annotations
import org.springaicommunity.mcp.annotation.McpTool;
import org.springaicommunity.mcp.annotation.McpToolParam;
import org.springaicommunity.mcp.annotation.McpResource;
import org.springaicommunity.mcp.annotation.McpPrompt;
import org.springaicommunity.mcp.annotation.McpArg;
// Context
import org.springaicommunity.mcp.server.McpSyncRequestContext;
import org.springaicommunity.mcp.server.McpAsyncRequestContext;
// Schema Types
import org.springaicommunity.mcp.schema.McpSchema.*;
// Spring
import org.springframework.stereotype.Component;
import org.springframework.context.annotation.Bean;@McpTool(name = "divide", description = "Divide two numbers")
public CallToolResult divide(
@McpToolParam(description = "Numerator", required = true) double a,
@McpToolParam(description = "Denominator", required = true) double b) {
if (b == 0) {
return CallToolResult.builder()
.addTextContent("Error: Division by zero")
.isError(true)
.build();
}
return CallToolResult.builder()
.addTextContent("Result: " + (a / b))
.build();
}@McpTool(name = "process", description = "Process with progress")
public String process(McpSyncRequestContext context,
@McpToolParam(description = "Data") String data) {
context.info("Starting");
context.progress(0);
// Work...
context.progress(50);
// More work...
context.progress(100);
return "Done";
}@McpResource(
uri = "config://{key}",
name = "Configuration",
description = "Get config value")
public String getConfig(String key) {
return configService.get(key);
}# Server basics
spring.ai.mcp.server.enabled=true
spring.ai.mcp.server.name=mcp-server
spring.ai.mcp.server.version=1.0.0
spring.ai.mcp.server.type=SYNC # or ASYNC
# Transport
spring.ai.mcp.server.stdio=false
spring.ai.mcp.server.protocol=SSE # SSE, STREAMABLE, STATELESS
# Capabilities
spring.ai.mcp.server.capabilities.tool=true
spring.ai.mcp.server.capabilities.resource=true
spring.ai.mcp.server.capabilities.prompt=true
spring.ai.mcp.server.capabilities.completion=true
# Timeouts
spring.ai.mcp.server.request-timeout=20s| Problem | Solution |
|---|---|
| Tool not discovered | Ensure class is @Component and method is public |
| Connection fails | Check transport config and port availability |
| Schema generation fails | Use supported types or explicit CallToolRequest |
| Context unavailable | Verify stateful protocol (not STATELESS) |