- name
- mcp-server
- description
- Use when exposing Spring Boot 3 application capabilities through Model Context Protocol tools, resources, or prompts. Covers Spring AI 1.x tool callback registration, transports, schemas, errors, security, and standalone MCP Java SDK compatibility.
MCP Server - Spring Boot 3
Prefer the Spring AI MCP server starters in a Spring Boot application. Let the Spring AI BOM manage its MCP SDK dependency; do not force the standalone SDK version into a starter-based application.
Dependencies
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server</artifactId>
</dependency>
For a raw SDK application without Spring AI, use the current MCP Java SDK 2.x release and follow its migration guide. Do not assume raw SDK examples match the version managed by Spring AI 1.x.
<dependency>
<groupId>io.modelcontextprotocol.sdk</groupId>
<artifactId>mcp</artifactId>
<version>2.0.0</version>
</dependency>
Spring AI 1.x tool callback integration
Spring AI 1.0.x exposes @Tool methods only through an explicit MethodToolCallbackProvider —
a bare @Component with @Tool methods registers nothing. Spring AI 1.1.x additionally supports
native @McpTool/@McpToolParam with spring.ai.mcp.server.annotation-scanner.enabled=true,
imported from org.springaicommunity.mcp.annotation (Spring AI 2.0 moved them to
org.springframework.ai.mcp.annotation). Pick one registration path per tool.
@Configuration
class McpToolsConfiguration {
@Bean
ToolCallbackProvider orderTools(OrderMcpTools tools) {
return MethodToolCallbackProvider.builder()
.toolObjects(tools)
.build();
}
}
@Component
final class OrderMcpTools {
private final OrderService orderService;
OrderMcpTools(OrderService orderService) {
this.orderService = orderService;
}
@Tool(description = "Get an order by UUID with line items and status history")
OrderResponse getOrder(
@ToolParam(description = "Order UUID") String orderId) {
return OrderResponse.from(orderService.findById(UUID.fromString(orderId)));
}
}
- Return DTOs rather than serialized JPA entities.
- Register each tool object once; duplicate providers create duplicate capabilities.
- Keep tool names and descriptions stable because clients and models depend on them.
- Bound result size, execution time, and downstream calls.
- For raw SDK code, use builders such as
CallToolResult.builder(); old constructors were removed.