目的:帮助 Java / Spring Boot 开发者快速理解 MCP 的设计动机、协议细节、以及 如何在 Spring AI 中落地。
为什么需要 MCP?
MCP 助力开发者在 LLM 之上构建智能体和复杂工作流。由于 LLM 需要频繁与外部数据和工具集成,MCP 提供了以下核心价值:
开箱即用的集成能力:提供丰富的预置集成方案,LLM 可直接接入使用
灵活的供应商切换:支持在不同 LLM 服务商之间无缝迁移
安全最佳实践:内置数据安全防护机制,确保基础设施安全可控
MCP 用 JSON‑RPC 2.0 + 能力发现 的模式,把「模型 ↔ 应用 ↔ 工具」之间的交互标准化,实现 一次接入,多处复用。
MCP 协议就好比 USB 接口,USB 设备可以通过 USB Hub 连接到不同的计算机上,而不需要重新设计接口。
- 我们在电脑上可以同时使用多个 USB 设备(鼠标、键盘、硬盘、游戏手柄),这些 USB 设备有不同的功能,只要实现了标准的 USB 接口协议即可。
- 电脑可以类比成 LLM,USB Hub 可以类比成 MCP Server,USB 设备可以类比成 Tool、Resource、Prompt 等。
- 通过 MCP 协议,LLM 可以通过 USB Hub 访问不同的 USB 设备,从而扩展出各种各样的能力(发邮件、打电话、地图旅行规划、订票)。
从某种程度上说,MCP 就像是设计模式中的命令(Command)模式 + 外观(Facade)模式。
基本概念
关键术语

MCP 主机:需要通过 MCP 访问数据的程序,如 Claude Desktop、IDE 或 AI 工具
MCP 客户端:与服务器保持 1:1 连接的协议客户端
MCP 服务器:通过标准化的模型上下文协议暴露特定能力的轻量级程序
本地数据源:MCP 服务器可以安全访问的计算机文件、数据库和服务
远程服务:MCP 服务器可以通过互联网连接的外部系统(例如通过 API)
分层架构
┌────────────────────────────┐ │ Client / Server API 层 │ ← McpClient / McpServer ├────────────────────────────┤ │ Session 会话层 │ ← 会话 & 状态管理 ├────────────────────────────┤ │ Transport 传输层 │ ← Stdio / SSE / WebSocket / gRPC └────────────────────────────┘
MCP 采用分层架构设计,每一层都有其特定的职责:
1. Client / Server API 层
提供 McpClient 和 McpServer 接口
处理高层业务逻辑和协议交互
负责能力发现和工具调用
2. Session 会话层
管理客户端和服务器之间的会话状态
处理会话的生命周期(初始化、运行、关闭)
维护会话上下文和状态信息
3. Transport 传输层
提供多种传输机制支持:
Stdio:标准输入输出,适合本地进程间通信
SSE (Server-Sent Events):单向服务器推送
WebSocket:全双工通信
gRPC:高性能 RPC 框架
处理底层通信细节和协议转换
这种分层设计使得 MCP 具有:
良好的可扩展性:可以轻松添加新的传输机制
清晰的职责分离:各层专注于自己的功能
灵活的部署方式:支持多种通信场景
传输机制
| 传输 | 场景 | 特点 |
|------|------|------|
| Stdio | 本地 CLI / 子进程 | 零网络开销,启动快 |
| HTTP + SSE | 微服务 / Web 应用 | POST 请求 + SSE 推流,部署友好 |
| 自定义 | WebSocket / gRPC | 只需实现 Transport 接口即可 |
Java Spring AI 集成实践
使用 Spring AI 开发,详细说明可以参考官网文档。
MCP 分为 Stdio 和 SSE 两种传输方式,下面的例子使用 SSE 方式,最简化开发一个发票助手 MCP,并展示如何通过模型自动调用这个 MCP。
POM 依赖
<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-mcp-server-webflux</artifactId> </dependency>
配置示例 `application.properties`
spring.main.banner-mode=off # logging.pattern.console= spring.ai.mcp.server.name=my-invoice-server spring.ai.mcp.server.version=0.0.1
详细的配置参数及默认值可以参考官方文档:Spring AI / Model Context Protocol (MCP) / MCP Server Boot Starters)。
暴露 Tool
这里就模拟一个非常简单的功能,仅拼装对应参数,返回发票链接。
@Service
public class InvoiceService {
@Tool(description = "获取发票链接")
public String getInvoiceUrl(@ToolParam(required = true, description = "发票 id") String invoiceId) {
return "https://www.example.com/invoice/" + invoiceId;
}
}@SpringBootApplication
public class McpServerApplication {
public static void main(String[] args) {
SpringApplication.run(McpServerApplication.class, args);
}
@Bean
public ToolCallbackProvider invoiceTools(InvoiceService invoiceService) {
return MethodToolCallbackProvider.builder().toolObjects(invoiceService).build();
}
}启动服务
执行 java -jar mcp-server.jar 启动服务,默认监听 8080 端口。
在 MCP client 中配置 mcp.setting
cursor、VS code 中的 cline 插件都算是 MCP client。本文展示 cline 插件如何配置。

cline_mcp_setting.json 增加如下配置:
{
"mcpServers": {
"invoice-local": {
"url": "http://localhost:8080/sse",
"autoApprove": [
"getInvoiceUrl"
]
}
}
}我们可以看到对应的 getInvoiceUrl 方法已经被自动注册到 MCP Server 中。

使用 MCP!
在 cline 中输入问题:“我有一个发票 id 是 123456,发票链接是多少?”,可以看到模型会自动判断是否需要调用 MCP Server 中的 getInvoiceUrl 方法,并拼装参数,获取结果。

说明
1. JDK 版本必须 >= 17
2. Spring Boot 版本必须 >= 3.2
3. Spring AI 底层使用 modelcontextprotocol / java-sdk)
4. MCP 协议等都在快速发展中,上面的代码示例仅供参考,具体实现可能会有所不同
完整配置示例
Application.java:
package com.example.mcp;
import org.springframework.ai.mcp.server.tool.ToolCallbackProvider;
import org.springframework.ai.mcp.server.tool.MethodToolCallbackProvider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.reactive.function.client.WebClient;
@SpringBootApplication
public class McpServerApplication {
public static void main(String[] args) {
SpringApplication.run(McpServerApplication.class, args);
}
/**
* 注册所有 Tools
*/
@Bean
public ToolCallbackProvider toolCallbackProvider(
DatabaseTools databaseTools,
FileTools fileTools,
HttpTools httpTools
) {
return MethodToolCallbackProvider.builder()
.toolObjects(databaseTools, fileTools, httpTools)
.build();
}
/**
* WebClient for HTTP tools
*/
@Bean
public WebClient webClient() {
return WebClient.builder()
.defaultHeader("User-Agent", "MCP-Server/1.0")
.build();
}
}application.yml:
spring: application: name: mcp-server-demo ai: mcp: server: name: "Enterprise MCP Server" version: "1.0.0" description: "Comprehensive MCP server with database, file, and HTTP capabilities" server: port: 8080 logging: level: org.springframework.ai.mcp: DEBUG com.example.mcp: DEBUG
MCP Client 配置与使用
Claude Desktop 配置
Claude Desktop 是最早支持 MCP 的应用之一。配置文件位置:
macOS:
~/Library/Application\ Support/Claude/claude_desktop_config.json
Windows:
%APPDATA%\Claude\claude_desktop_config.json
配置示例:
{
"mcpServers": {
"enterprise-server": {
"command": "java",
"args": [
"-jar",
"/path/to/mcp-server.jar"
],
"env": {
"SERVER_PORT": "8080"
}
},
"database-server": {
"url": "http://localhost:8080/sse",
"headers": {
"Authorization": "Bearer YOUR_TOKEN"
}
}
}
}Cursor IDE 配置
Cursor 通过 .cursor/mcp.json 文件配置 MCP 服务器:
{
"mcpServers": {
"local-dev": {
"command": "java",
"args": ["-jar", "mcp-server.jar"],
"env": {
"WORKSPACE_ROOT": "${workspaceFolder}"
}
},
"remote-api": {
"url": "https://api.example.com/mcp/sse",
"autoApprove": ["read_file", "list_directory"]
}
}
}Cline/Continue 配置
VS Code 插件 Cline 的配置文件:~/.cline/mcp_settings.json
{
"mcpServers": {
"development": {
"url": "http://localhost:8080/sse",
"autoApprove": [
"query_database",
"read_file",
"list_directory"
],
"alwaysAllow": ["get_table_schema"]
}
}
}实际使用示例
场景 1:数据库查询
用户: 查询用户表中所有活跃用户的数量
AI: 我会帮你查询数据库。
[调用 query_database]
参数: sql = "SELECT COUNT(*) as count FROM users WHERE status = 'active'"
结果: {"rowCount": 1, "rows": [{"count": 1234}]}
AI: 当前有 1,234 个活跃用户。场景 2:文件操作
用户: 帮我创建一个 README.md 文件,包含项目介绍 AI: 好的,我会创建 README 文件。 [调用 write_file] 参数: path = "README.md" content = "# Project Name\n\nThis is a comprehensive guide..." create_dirs = true AI: README.md 文件已创建成功!
场景 3:代码审查
用户: 使用 code-review prompt 审查这段代码
AI: 我会使用专业的代码审查模板。
[调用 code-review prompt]
参数:
language = "Java"
code = "public class User { ... }"
focus_areas = "安全性和性能"
AI: [提供详细的代码审查反馈...]最佳实践
安全考虑
1. 输入验证
public class SecurityValidator {
public static void validateSqlQuery(String sql) {
// 防止 SQL 注入
String lowerSql = sql.toLowerCase();
String[] dangerousKeywords = {
"drop", "delete", "update", "insert",
"truncate", "alter", "create"
};
for (String keyword : dangerousKeywords) {
if (lowerSql.contains(keyword)) {
throw new SecurityException(
"不允许的 SQL 操作: " + keyword
);
}
}
}
public static Path validatePath(Path basePath, String userPath) {
Path resolved = basePath.resolve(userPath).normalize();
// 防止路径遍历攻击
if (!resolved.startsWith(basePath)) {
throw new SecurityException(
"路径超出允许范围: " + userPath
);
}
return resolved;
}
}2. 权限控制
@Configuration
public class McpSecurityConfig {
@Bean
public McpAuthorizationManager authorizationManager() {
return new McpAuthorizationManager() {
@Override
public boolean canExecuteTool(String toolName, Principal user) {
// 基于用户角色的权限控制
return switch (toolName) {
case "query_database" ->
user.hasRole("DATA_ANALYST");
case "write_file" ->
user.hasRole("DEVELOPER");
default -> true;
};
}
};
}
}3. API 速率限制
@Aspect
@Component
public class RateLimitAspect {
private final RateLimiter rateLimiter =
RateLimiter.create(10.0); // 每秒 10 个请求
@Around("@annotation(Tool)")
public Object rateLimit(ProceedingJoinPoint joinPoint)
throws Throwable {
if (!rateLimiter.tryAcquire()) {
throw new RateLimitException(
"请求过于频繁,请稍后再试"
);
}
return joinPoint.proceed();
}
}性能优化
1. 结果缓存
@Service
public class CachedDatabaseTools {
@Cacheable(value = "tableSchema", key = "#tableName")
public TableSchema getTableSchema(String tableName) {
// 缓存表结构,避免重复查询
return databaseService.getSchema(tableName);
}
@Cacheable(
value = "queryResults",
key = "#sql",
condition = "#sql.toLowerCase().startsWith('select')"
)
public QueryResult executeQuery(String sql) {
return databaseService.execute(sql);
}
}2. 异步处理
@Service
public class AsyncFileTools {
@Tool(description = "异步搜索文件")
public CompletableFuture<List<String>> searchFilesAsync(
@ToolParam(name = "pattern") String pattern
) {
return CompletableFuture.supplyAsync(() -> {
// 耗时的文件搜索操作
return fileService.search(pattern);
});
}
}3. 连接池管理
@Configuration
public class DatabaseConfig {
@Bean
public DataSource dataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl(jdbcUrl);
config.setUsername(username);
config.setPassword(password);
// 优化连接池配置
config.setMaximumPoolSize(20);
config.setMinimumIdle(5);
config.setConnectionTimeout(30000);
config.setIdleTimeout(600000);
return new HikariDataSource(config);
}
}错误处理
统一异常处理:
@ControllerAdvice
public class McpExceptionHandler {
@ExceptionHandler(SecurityException.class)
public ResponseEntity<ErrorResponse> handleSecurityException(
SecurityException ex
) {
return ResponseEntity
.status(HttpStatus.FORBIDDEN)
.body(new ErrorResponse(
"SECURITY_ERROR",
ex.getMessage()
));
}
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<ErrorResponse> handleValidationException(
IllegalArgumentException ex
) {
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(new ErrorResponse(
"VALIDATION_ERROR",
ex.getMessage()
));
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGenericException(
Exception ex
) {
log.error("Unexpected error", ex);
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ErrorResponse(
"INTERNAL_ERROR",
"服务暂时不可用,请稍后重试"
));
}
}
record ErrorResponse(
String code,
String message
) {}监控与日志
@Aspect
@Component
public class McpMonitoringAspect {
@Around("@annotation(tool)")
public Object monitorToolExecution(
ProceedingJoinPoint joinPoint,
Tool tool
) throws Throwable {
String toolName = tool.name();
long startTime = System.currentTimeMillis();
try {
Object result = joinPoint.proceed();
long duration = System.currentTimeMillis() - startTime;
// 记录成功的工具调用
log.info(
"Tool executed: {} | Duration: {}ms",
toolName, duration
);
// 发送指标到监控系统
metricsService.recordToolExecution(
toolName, duration, "success"
);
return result;
} catch (Exception ex) {
long duration = System.currentTimeMillis() - startTime;
// 记录失败的工具调用
log.error(
"Tool failed: {} | Duration: {}ms | Error: {}",
toolName, duration, ex.getMessage()
);
metricsService.recordToolExecution(
toolName, duration, "failure"
);
throw ex;
}
}
}典型应用场景
1. IDE 智能助手
功能描述: 在 IDE 中提供代码生成、重构、调试等智能辅助功能。
实现示例:
@Service
public class IdeTools {
@Tool(description = "生成单元测试")
public String generateUnitTest(
@ToolParam(name = "source_code") String sourceCode,
@ToolParam(name = "test_framework") String framework
) {
// 分析源代码
CodeAnalysis analysis = codeAnalyzer.analyze(sourceCode);
// 生成测试代码
return testGenerator.generate(analysis, framework);
}
@Tool(description = "代码重构建议")
public List<RefactoringSuggestion> suggestRefactoring(
@ToolParam(name = "code") String code
) {
return refactoringService.analyzePotentialImprovements(code);
}
}2. 企业数据分析
功能描述: 提供自然语言到 SQL 的转换,支持数据可视化。
@Service
public class DataAnalyticsTools {
@Tool(description = "自然语言查询")
public QueryResult nlQuery(
@ToolParam(name = "question") String question
) {
// 将自然语言转换为 SQL
String sql = nlToSqlConverter.convert(question);
log.info("Generated SQL: {}", sql);
// 执行查询
return databaseService.executeQuery(sql);
}
@Tool(description = "生成数据可视化")
public ChartConfig generateChart(
@ToolParam(name = "data") List<Map<String, Object>> data,
@ToolParam(name = "chart_type") String chartType
) {
return chartGenerator.generate(data, chartType);
}
}3. 文档生成与管理
@Service
public class DocumentationTools {
@Tool(description = "生成 API 文档")
public String generateApiDocs(
@ToolParam(name = "swagger_spec") String swaggerSpec
) {
return apiDocGenerator.generate(swaggerSpec);
}
@Tool(description = "更新用户手册")
public UpdateResult updateUserManual(
@ToolParam(name = "section") String section,
@ToolParam(name = "content") String content
) {
Path manualPath = docsPath.resolve("user-manual.md");
return documentService.updateSection(manualPath, section, content);
}
}4. DevOps 自动化
@Service
public class DevOpsTools {
@Tool(description = "部署应用")
public DeploymentResult deploy(
@ToolParam(name = "environment") String environment,
@ToolParam(name = "version") String version
) {
return deploymentService.deploy(environment, version);
}
@Tool(description = "查看日志")
public List<LogEntry> getLogs(
@ToolParam(name = "service") String service,
@ToolParam(name = "lines") int lines
) {
return logService.getTailLogs(service, lines);
}
@Tool(description = "检查服务健康状态")
public HealthStatus checkHealth(
@ToolParam(name = "service") String service
) {
return healthCheckService.check(service);
}
}生态系统与工具
官方工具
1. MCP Inspector - 调试和测试 MCP 服务器
网址: inspector
功能: 实时查看工具调用、测试 prompts、监控资源
2. MCP CLI - 命令行工具
``bash``
npm install -g @modelcontextprotocol/cli
mcp test http://localhost:8080/sse
社区服务器
访问 mcp.so 浏览 1000+ 社区 MCP 服务器:
数据库: PostgreSQL, MySQL, MongoDB, Redis
云服务: AWS, Azure, GCP
开发工具: GitHub, GitLab, Jira
通信: Slack, Discord, Email
数据处理: Pandas, NumPy, Excel
客户端支持
| 客户端 | 支持程度 | 配置方式 |
|--------|---------|----------|
| Claude Desktop | ✅ 完整支持 | JSON 配置文件 |
| Cursor | ✅ 完整支持 | .cursor/mcp.json |
| Cline (VS Code) | ✅ 完整支持 | 插件配置 |
| Continue | ✅ 完整支持 | config.json |
| Zed | ✅ 实验性支持 | 内置配置 |
常见问题
Q: MCP 与 OpenAI Function Calling 有什么区别?
A: MCP 是一个开放协议,不绑定特定 AI 提供商。Function Calling 是 OpenAI 特定的实现。MCP 支持更丰富的能力(Tools, Resources, Prompts),而 Function Calling 主要聚焦于函数调用。
Q: stdio 和 SSE 传输方式如何选择?
A:
stdio: 适合本地命令行工具,零网络开销,启动快
SSE: 适合 Web 服务,支持远程访问,易于部署和扩展
Q: MCP 服务器如何处理长时间运行的任务?
A: 建议使用异步模式:
@Tool(description = "异步任务")
public TaskId startAsyncTask(
@ToolParam(name = "input") String input
) {
// 返回任务 ID
return taskService.submit(input);
}
@Tool(description = "查询任务状态")
public TaskStatus getTaskStatus(
@ToolParam(name = "task_id") String taskId
) {
return taskService.getStatus(taskId);
}Q: 如何调试 MCP 服务器?
A:
1. 使用 MCP Inspector 工具
2. 启用详细日志: logging.level.org.springframework.ai.mcp=DEBUG
3. 使用 Postman 测试 SSE 端点
4. 添加监控和追踪
Q: MCP 服务器的性能瓶颈在哪里?
A: 常见瓶颈:
数据库连接池不足
未使用缓存
同步阻塞操作
大数据传输
优化建议见"性能优化"章节。
未来展望
即将到来的特性
1. 细粒度权限控制
基于工具的 ACL
资源级别的访问控制
审计日志
2. 多模态支持
图像分析工具
音频处理
视频内容理解
3. 增强的上下文管理
会话状态持久化
跨工具上下文共享
智能缓存策略
4. 更好的可观测性
内置追踪和指标
性能分析工具
实时监控面板
技术演进方向
协议版本 2.0: 更高效的二进制传输
边缘计算: 在浏览器中运行 MCP 服务器
联邦学习: 跨服务器的知识共享
AI Agent 框架: 与 LangChain, AutoGPT 等深度集成
生态发展
企业采用: 更多企业级 MCP 服务器
标准化: 行业标准和最佳实践
认证体系: MCP 服务器质量认证
市场生态: MCP 服务器市场和交易平台
参考资源
官方资源
MCP 官方网站: modelcontextprotocol
MCP 规范: modelcontextprotocol
MCP GitHub: modelcontextprotocol
MCP 服务器目录: mcp
Spring AI 相关
Spring AI 文档: reference
MCP 集成指南: mcp
示例仓库: spring-ai-examples
Spring AI MCP Server Starter: mcp-server-boot-starter-docs.html
技术规范
JSON-RPC 2.0: specification
Server-Sent Events: Server-sent_events
OpenAPI 3.0: specification
社区资源
MCP Discord: modelcontextprotocol
MCP Reddit: reddit
Stack Overflow: 标签
model-context-protocolYouTube 教程: 搜索 "MCP Tutorial"
相关项目
Java SDK: java-sdk
TypeScript SDK: typescript-sdk
Python SDK: python-sdk
MCP Inspector: inspector
- 关键术语
- 分层架构
- 传输机制
- POM 依赖
- 配置示例 `application.properties`
- 暴露 Tool
- 启动服务
- 在 MCP client 中配置 mcp.setting
- 使用 MCP!
- 说明
- Claude Desktop 配置
- Cursor IDE 配置
- Cline/Continue 配置
- 实际使用示例
- 安全考虑
- 性能优化
- 错误处理
- 监控与日志
- 1. IDE 智能助手
- 2. 企业数据分析
- 3. 文档生成与管理
- 4. DevOps 自动化
- 官方工具
- 社区服务器
- 客户端支持
- 即将到来的特性
- 技术演进方向
- 生态发展
- 官方资源
- Spring AI 相关
- 技术规范
- 社区资源
- 相关项目










![20个常见的SQL数据库面试问题和答案[2022] 20个常见的SQL数据库面试问题和答案[2022]](https://www.lw50.com/zb_users/upload/2022/08/202208201661010492876616.png)



























发表评论