Spring Boot + Spring AI 构建 MCP 服务完全指南
# Spring Boot + Spring AI 构建 MCP 服务完全指南
# 引言
在人工智能应用快速发展的今天,如何让 AI 助手安全、高效地访问外部工具和数据源成为架构设计的关键挑战。Anthropic 推出的 MCP(Model Context Protocol,模型上下文协议) 提供了一种标准化的解决方案。作为 Java 生态系统的领导者,Spring 社区通过 Spring AI 为开发者提供了便捷的 MCP 支持,使得在 Spring Boot 应用中构建 MCP 服务变得前所未有的简单。
本文将深入探讨如何利用 Spring Boot 和 Spring AI 构建完整的 MCP 服务,涵盖从基础概念到生产级实现的完整技术路径。
# MCP 协议核心概念
# 什么是 MCP
MCP(Model Context Protocol)是一种开放标准协议,旨在定义 AI 助手与外部工具、数据源之间的标准化通信方式。它由 Anthropic 创建,最初用于增强 Claude 的能力,如今已发展成为跨平台、跨语言的通用协议。
MCP 的核心价值在于解决了 AI 应用与外部系统集成时的碎片化问题。在 MCP 出现之前,每个 AI 应用需要为不同的数据源和工具实现独立的集成代码,导致大量重复工作。MCP 通过提供统一的接口规范,让 AI 应用可以透明地调用任何支持 MCP 的外部服务。
# MCP 架构概览
MCP 采用经典的客户端-服务器架构,主要包含以下核心组件:
MCP 主机(Host):这是用户直接交互的 AI 应用程序,如 Claude Desktop、Cursor 或自定义聊天应用。主机负责协调用户请求、调用工具并生成响应。
MCP 客户端(Client):位于主机内部,负责与一个或多个 MCP 服务器建立和维护连接。客户端处理协议层面的通信细节,包括请求序列化、响应解析等。
MCP 服务器(Server):这是我们使用 Spring Boot 构建的核心组件。服务器暴露工具(Tools)、资源(Resources)和提示(Prompts),供客户端调用。服务器通常与实际的数据源或服务(数据库、文件系统、API 等)进行交互。
传输层(Transport):MCP 支持多种传输方式,包括标准输入输出(STDIO)和 Server-Sent Events(SSE)。STDIO 适合本地命令行集成,SSE 则支持基于 HTTP 的远程通信。
# 核心原语
MCP 定义了三种主要的原语来暴露功能:
工具(Tools):可执行的函数或方法,这是 MCP 最常用的原语。工具可以执行数据库查询、调用外部 API、执行计算等任何业务逻辑。每个工具都有明确定义的输入模式和输出格式。
资源(Resources):类似于传统 REST API 中的资源概念,资源提供数据访问能力。客户端可以列出可用资源、读取资源内容。资源可以是文件、数据库查询结果或任何动态生成的数据。
提示(Prompts):预定义的提示模板,可以包含动态参数。提示帮助 AI 更好地利用特定领域的上下文信息。
# Spring AI MCP 生态概览
# Spring AI 简介
Spring AI 是 Spring 生态系统为人工智能应用提供的集成框架。它简化了与各种 AI 模型提供商的交互,包括 OpenAI、Anthropic、Azure OpenAI、Hugging Face 等。Spring AI 提供了统一的 API 抽象,让开发者可以使用相同的代码模式接入不同的 AI 提供商。
# MCP 支持的演进
Spring AI 从 1.0.0 版本开始正式支持 MCP 协议。随着版本迭代,MCP 支持不断完善。最新的 Spring AI 1.1.0-M2 版本基于 MCP Java SDK v0.13.1 构建,支持 MCP 协议版本 2025-06-18,并提供了多项关键改进:
- 改进的工具名称前缀生成和重复处理
- AOT(Ahead-of-Time)编译支持
- 改进的 JSON 序列化能力
- 更完善的配置属性体系
# 可用的 Spring AI MCP 组件
Spring AI 提供了两组关键的 Starter 组件:
MCP Server 端:
spring-ai-starter-mcp-server-webmvc:基于 Spring MVC 的 MCP 服务器,支持同步 HTTP 通信spring-ai-starter-mcp-server-webflux:基于 Spring WebFlux 的 MCP 服务器,支持 SSE 和响应式编程
MCP Client 端:
spring-ai-starter-mcp-client:标准 MCP 客户端spring-ai-starter-mcp-client-sse:支持 SSE 的 MCP 客户端
开发者可以根据实际需求选择合适的组件。对于大多数应用场景,WebFlux 版本提供了更好的性能和实时能力。
# 项目初始化与依赖配置
# 环境要求
在开始实现之前,确保开发环境满足以下要求:
- Java 17 或更高版本(推荐 Java 21)
- Maven 3.8+ 或 Gradle 7+
- Spring Boot 3.2+(推荐 3.4.x)
# 创建 Spring Boot 项目
使用 Spring Initializr 快速创建项目基础结构。在添加依赖时,选择以下模块:
- Spring Web(构建 REST API)
- Model Context Protocol Server(MCP 服务器支持)
# Maven 依赖配置
在 pom.xml 中添加必要的依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.2</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>mcp-server-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mcp-server-demo</name>
<description>Spring Boot MCP Server Demo</description>
<properties>
<java.version>21</java.version>
<spring-ai.version>1.0.0</spring-ai.version>
</properties>
<dependencies>
<!-- Spring Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring AI MCP Server -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
<version>${spring-ai.version}</version>
</dependency>
<!-- Spring AI OpenAI (如果需要调用外部 AI) -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-openai</artifactId>
<version>${spring-ai.version}</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# 配置文件
在 application.yml 中配置 MCP 服务器的基本参数:
server:
port: 8080
spring:
ai:
mcp:
server:
name: "conference-mcp-server"
version: "1.0.0"
type: sync
stdio: false
# 日志配置
logging:
level:
org.springframework.ai: DEBUG
io.modelcontextprotocol: DEBUG
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 核心实现:构建 MCP 工具服务
# 定义业务领域模型
首先,我们需要定义业务领域模型。以一个会议管理系统为例,我们创建实体类来表示会议和演讲者信息:
package com.example.mcpdemo.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Session {
private String id;
private String title;
private String speaker;
private String description;
private String day;
private String time;
private String room;
private String track;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 创建服务层
接下来创建服务类,实现业务逻辑:
package com.example.mcpdemo.service;
import com.example.mcpdemo.model.Session;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class ConferenceService {
private final List<Session> sessions;
public ConferenceService() {
this.sessions = initializeSessions();
}
private List<Session> initializeSessions() {
List<Session> list = new ArrayList<>();
list.add(new Session("1", "Opening Keynote: The Future of AI",
"Dr. Sarah Chen", "Exploring AI trends", "Thursday", "09:00",
"Main Hall", "Keynote"));
list.add(new Session("2", "Building MCP Servers with Spring AI",
"John Doe", "Hands-on guide", "Thursday", "10:30",
"Room A", "Development"));
list.add(new Session("3", "Cloud Native Development",
"Jane Smith", "K8s best practices", "Thursday", "11:30",
"Room B", "DevOps"));
list.add(new Session("4", "Machine Learning in Production",
"Mike Johnson", "MLOps strategies", "Thursday", "14:00",
"Room A", "ML/AI"));
list.add(new Session("5", "Security Best Practices",
"Alice Brown", "AppSec overview", "Friday", "09:30",
"Main Hall", "Security"));
list.add(new Session("6", "Closing Keynote",
"Dr. Sarah Chen", "Wrap up", "Friday", "16:00",
"Main Hall", "Keynote"));
return list;
}
public List<Session> getAllSessions() {
return new ArrayList<>(sessions);
}
public List<Session> getSessionsByDay(String day) {
return sessions.stream()
.filter(s -> s.getDay().equalsIgnoreCase(day))
.collect(Collectors.toList());
}
public List<Session> getSessionsByTrack(String track) {
return sessions.stream()
.filter(s -> s.getTrack().equalsIgnoreCase(track))
.collect(Collectors.toList());
}
public Session getSessionById(String id) {
return sessions.stream()
.filter(s -> s.getId().equals(id))
.findFirst()
.orElse(null);
}
public List<Session> searchSessions(String keyword) {
String lowerKeyword = keyword.toLowerCase();
return sessions.stream()
.filter(s -> s.getTitle().toLowerCase().contains(lowerKeyword) ||
s.getDescription().toLowerCase().contains(lowerKeyword) ||
s.getSpeaker().toLowerCase().contains(lowerKeyword))
.collect(Collectors.toList());
}
public long countSessionsByDay(String day) {
return sessions.stream()
.filter(s -> s.getDay().equalsIgnoreCase(day))
.count();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# 使用 @Tool 注解暴露服务方法
这是实现 MCP 服务的核心步骤。Spring AI 允许开发者使用 @Tool 注解直接标记服务方法,无需编写繁琐的协议处理代码:
package com.example.mcpdemo.tools;
import com.example.mcpdemo.model.Session;
import com.example.mcpdemo.service.ConferenceService;
import org.springframework.ai.mcp.annotation.Tool;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class ConferenceTools {
private final ConferenceService conferenceService;
public ConferenceTools(ConferenceService conferenceService) {
this.conferenceService = conferenceService;
}
@Tool(name = "get-all-sessions", description = "获取所有会议演讲信息")
public List<Session> getAllSessions() {
return conferenceService.getAllSessions();
}
@Tool(name = "get-sessions-by-day",
description = "根据日期获取会议演讲列表,例如:Thursday 或 Friday")
public List<Session> getSessionsByDay(String day) {
return conferenceService.getSessionsByDay(day);
}
@Tool(name = "get-sessions-by-track",
description = "根据主题获取会议演讲列表,如:Development, DevOps, ML/AI, Security")
public List<Session> getSessionsByTrack(String track) {
return conferenceService.getSessionsByTrack(track);
}
@Tool(name = "get-session-by-id",
description = "根据演讲ID获取详细信息")
public Session getSessionById(String id) {
return conferenceService.getSessionById(id);
}
@Tool(name = "search-sessions",
description = "搜索会议演讲,通过关键词匹配标题、描述或演讲者")
public List<Session> searchSessions(String keyword) {
return conferenceService.searchSessions(keyword);
}
@Tool(name = "count-sessions-by-day",
description = "统计某一天的演讲数量")
public long countSessionsByDay(String day) {
return conferenceService.countSessionsByDay(day);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# 工具方法命名与描述规范
在定义 @Tool 方法时,需要注意以下规范:
工具名称(name):必须是唯一的,通常使用 kebab-case 命名风格。Spring AI 会自动处理名称冲突,添加前缀或后缀以确保唯一性。
工具描述(description):这是 AI 模型理解工具用途的关键依据。描述应该清晰、准确,包含:
- 工具的主要功能
- 参数的含义和预期格式
- 可能的返回值类型
良好的描述能够帮助 AI 正确调用工具,提高整体系统的准确率。
# 注册 MCP 服务器
在 Spring AI 中,MCP 服务器的注册通常是自动的。Spring 会扫描带有 @Tool 注解的方法,并自动创建对应的工具定义。但我们需要创建配置类来确保组件正确加载:
package com.example.mcpdemo.config;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.ai.mcp.tool.MethodToolCallbackProvider;
@SpringBootApplication
public class McpServerApplication {
public static void main(String[] args) {
SpringApplication.run(McpServerApplication.class, args);
}
@Bean
public MethodToolCallbackProvider methodToolCallbackProvider() {
return MethodToolCallbackProvider.builder().build();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 高级:自定义 MCP 服务器配置
对于更复杂的需求,可以手动配置 MCP 服务器参数:
package com.example.mcpdemo.config;
import io.modelcontextprotocol.server.McpServer;
import io.modelcontextprotocol.spec.McpServerRunner;
import io.modelcontextprotocol.spec.McpSchema;
import org.springframework.ai.mcp.SyncMcpServerAdapter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class McpServerConfiguration {
@Bean
public SyncMcpServerAdapter mcpServerAdapter() {
return new SyncMcpServerAdapter(
McpServer.builder()
.serverInfo(
McpSchema.ServerInfo.builder()
.name("my-custom-mcp-server")
.version("1.0.0")
.build()
)
.build()
);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 暴露资源与提示
# 暴露数据资源
MCP 的资源原语允许服务器暴露可供客户端读取的数据。在 Spring AI 中,可以通过实现特定接口或使用配置来暴露资源:
package com.example.mcpdemo.resources;
import org.springframework.ai.mcp.resource.Resource;
import org.springframework.ai.mcp.resource.ResourceResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration
public class ResourceConfiguration {
@Bean
public ResourceResolver resourceResolver() {
return new ResourceResolver() {
@Override
public List<String> listResources() {
return List.of(
"conference://sessions",
"conference://speakers"
);
}
@Override
public Resource getResource(String uri) {
if (uri.equals("conference://sessions")) {
return new Resource() {
@Override
public String getUri() {
return "conference://sessions";
}
@Override
public String getName() {
return "Conference Sessions";
}
@Override
public String getDescription() {
return "List of all conference sessions";
}
@Override
public String getMimeType() {
return "application/json";
}
@Override
public byte[] read() {
return "[]".getBytes();
}
};
}
return null;
}
};
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# 传输协议配置
# STDIO 传输模式
STDIO 传输适合本地集成场景,例如与 Claude Desktop 配合使用:
spring:
ai:
mcp:
server:
stdio: true
type: sync
2
3
4
5
6
启用 STDIO 后,应用不会启动 Web 服务器,而是通过标准输入输出进行通信。
# SSE 传输模式
SSE(Server-Sent Events)适合需要远程访问的场景:
spring:
ai:
mcp:
server:
stdio: false
type: sync
2
3
4
5
6
SSE 模式下,MCP 服务器会在以下端点暴露服务:
POST /mcp/message:处理 MCP 消息请求GET /mcp/sse:建立 SSE 连接用于实时推送
# WebFlux 响应式支持
对于高并发场景,可以使用 WebFlux 版本获得更好的性能:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
</dependency>
2
3
4
WebFlux 版本支持完整的响应式编程模型,适合构建实时性要求较高的应用。
# 测试与调试
# 本地测试 MCP 服务器
使用 MCP Inspector 工具可以方便地测试 MCP 服务器:
# 安装 MCP Inspector
npm install -g @modelcontextprotocol/inspector
# 启动 Inspector 并连接本地服务器
mcp-inspector stdio -- java -jar target/mcp-server-demo-0.0.1-SNAPSHOT.jar
2
3
4
5
Inspector 提供了图形界面,可以列出服务器提供的所有工具,查看工具定义,并执行测试调用。
# 与 Claude Desktop 集成
将 MCP 服务器配置到 Claude Desktop:
打开 Claude Desktop 配置目录:
- macOS:
~/Library/Application Support/Claude/ - Windows:
%APPDATA%/Claude/
- macOS:
编辑
claude_desktop_config.json:
{
"mcpServers": {
"conference-server": {
"command": "java",
"args": [
"-jar",
"/path/to/mcp-server-demo-0.0.1-SNAPSHOT.jar"
]
}
}
}
2
3
4
5
6
7
8
9
10
11
- 重启 Claude Desktop
# 单元测试
创建针对 MCP 工具的单元测试:
package com.example.mcpdemo;
import com.example.mcpdemo.tools.ConferenceTools;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
class ConferenceToolsTest {
@Autowired
private ConferenceTools conferenceTools;
@Test
void testGetAllSessions() {
var sessions = conferenceTools.getAllSessions();
assertNotNull(sessions);
assertFalse(sessions.isEmpty());
}
@Test
void testGetSessionsByDay() {
var thursdaySessions = conferenceTools.getSessionsByDay("Thursday");
assertTrue(thursdaySessions.size() > 0);
var fridaySessions = conferenceTools.getSessionsByDay("Friday");
assertTrue(fridaySessions.size() > 0);
}
@Test
void testSearchSessions() {
var results = conferenceTools.searchSessions("AI");
assertFalse(results.isEmpty());
}
@Test
void testCountSessionsByDay() {
var count = conferenceTools.countSessionsByDay("Thursday");
assertTrue(count > 0);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# MCP 客户端实现
除了构建 MCP 服务器,Spring AI 也支持实现 MCP 客户端来消费外部 MCP 服务。
# 配置 MCP 客户端
spring:
ai:
mcp:
client:
sse:
connections:
weather-server:
url: http://localhost:8081
file-server:
url: http://localhost:8082
2
3
4
5
6
7
8
9
10
# 在代码中使用 MCP 工具
@Service
public class ChatService {
private final ChatClient chatClient;
public ChatService(ChatClient chatClient) {
this.chatClient = chatClient;
}
public String chat(String userMessage) {
return chatClient.prompt()
.user(userMessage)
.call()
.content();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 典型应用场景
# 企业内部知识库
企业可以使用 Spring Boot 构建 MCP 服务,将内部文档、数据库、API 等资源暴露给 AI 助手。员工可以通过自然语言查询技术文档、检索产品信息、执行常见操作。
# 业务流程自动化
将企业业务流程封装为 MCP 工具,AI 助手可以代替用户执行复杂的多步骤操作,如订单处理、审批流程触发、数据同步等。
# 数据分析平台
构建支持 MCP 的数据分析服务,AI 可以调用数据查询、报表生成、数据可视化等工具,帮助用户快速获取业务洞察。
# 多系统集成
通过 MCP 协议连接多个遗留系统或第三方服务,AI 充当统一的数据交换层,简化系统间集成复杂度。
# 优势分析
# Spring 生态系统集成
使用 Spring Boot 构建 MCP 服务的最大优势在于可以充分利用 Spring 生态系统的丰富特性:
- 依赖注入和自动配置简化了组件管理
- Spring Data 支持轻松连接各类数据库
- Spring Security 提供完善的安全保障
- 成熟的测试框架确保代码质量
# 声明式工具定义
通过 @Tool 注解,开发者可以用最少的代码暴露复杂的业务功能。Spring AI 负责处理协议解析、参数验证、结果序列化等繁琐工作。
# 灵活的传输支持
Spring AI MCP 支持 STDIO、SSE 和 WebFlux 三种传输模式,可以根据实际需求选择最合适的方案。本地集成使用 STDIO,远程服务使用 SSE,高并发场景使用 WebFlux。
# 生产级稳定性
Spring AI 基于 MCP Java SDK 构建,该 SDK 由 Anthropic 官方维护和更新,确保了与最新 MCP 协议规范的兼容性。Spring 的发布周期也保证了及时的安全更新和 bug 修复。
# 注意事项与最佳实践
# 安全性考虑
在生产环境中部署 MCP 服务时,需要关注以下安全要点:
认证与授权:MCP 协议本身不包含认证机制,需要在传输层实现。可以考虑使用 API Key、JWT 或 OAuth2 进行保护。
输入验证:对工具参数进行严格验证,防止注入攻击。
日志审计:记录工具调用日志,便于问题排查和合规审计。
限流保护:防止恶意请求对服务造成压力。
# 性能优化
模型缓存:首次加载模型可能耗时较长,确保模型正确缓存。
连接池:对于需要调用外部 API 的工具,使用连接池提高效率。
异步处理:对于耗时操作,考虑使用异步处理模式。
# 监控与可观测性
集成 Spring Boot Actuator 提供健康检查、指标监控等能力:
management:
endpoints:
web:
exposure:
include: health,metrics,info
2
3
4
5
# 总结
MCP 为 AI 应用与外部系统的集成提供了标准化的解决方案,而 Spring Boot + Spring AI 的组合使得构建 MCP 服务变得简洁高效。开发者可以专注于业务逻辑的实现,将协议处理的复杂性交给框架处理。
通过本文介绍的技术,开发者可以快速构建功能完整的 MCP 服务器,将企业数据和服务能力无缝暴露给 AI 助手。随着 AI 应用的持续发展,掌握 MCP 服务开发将成为 Java 工程师的重要技能。