--- date: 2025-10-22 --- - [为什么需要 MCP?](#为什么需要-mcp) - [基本概念](#基本概念) - [关键术语](#关键术语) - [分层架构](#分层架构) - [传输机制](#传输机制) - [Java Spring AI 集成实践](#java-spring-ai-集成实践) - [POM 依赖](#pom-依赖) - [配置示例 `application.properties`](#配置示例-applicationproperties) - [暴露 Tool](#暴露-tool) - [启动服务](#启动服务) - [在 MCP client 中配置 mcp.setting](#在-mcp-client-中配置-mcpsetting) - [使用 MCP!](#使用-mcp) - [说明](#说明) - [完整配置示例](#完整配置示例) - [MCP Client 配置与使用](#mcp-client-配置与使用) - [Claude Desktop 配置](#claude-desktop-配置) - [Cursor IDE 配置](#cursor-ide-配置) - [Cline/Continue 配置](#clinecontinue-配置) - [实际使用示例](#实际使用示例) - [最佳实践](#最佳实践) - [安全考虑](#安全考虑) - [性能优化](#性能优化) - [错误处理](#错误处理) - [监控与日志](#监控与日志) - [典型应用场景](#典型应用场景) - [1. IDE 智能助手](#1-ide-智能助手) - [2. 企业数据分析](#2-企业数据分析) - [3. 文档生成与管理](#3-文档生成与管理) - [4. DevOps 自动化](#4-devops-自动化) - [生态系统与工具](#生态系统与工具) - [官方工具](#官方工具) - [社区服务器](#社区服务器) - [客户端支持](#客户端支持) - [常见问题](#常见问题) - [未来展望](#未来展望) - [即将到来的特性](#即将到来的特性) - [技术演进方向](#技术演进方向) - [生态发展](#生态发展) - [参考资源](#参考资源) - [官方资源](#官方资源) - [Spring AI 相关](#spring-ai-相关) - [技术规范](#技术规范) - [社区资源](#社区资源) - [相关项目](#相关项目) --- > **目的**:帮助 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)模式。 ## 基本概念 ### 关键术语 ![](http://yano.oss-cn-beijing.aliyuncs.com/blog/2025-04-22-13-43-40.png) * **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](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-overview.html) 开发,详细说明可以参考官网文档。 > MCP 分为 Stdio 和 SSE 两种传输方式,下面的例子使用 SSE 方式,最简化开发一个发票助手 MCP,并展示如何通过模型自动调用这个 MCP。 ### POM 依赖 ```xml org.springframework.ai spring-ai-starter-mcp-server-webflux ``` ### 配置示例 `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]([https://](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-server-boot-starter-docs.html#_configuration_properties))。 ### 暴露 Tool 这里就模拟一个非常简单的功能,仅拼装对应参数,返回发票链接。 ```java @Service public class InvoiceService { @Tool(description = "获取发票链接") public String getInvoiceUrl(@ToolParam(required = true, description = "发票 id") String invoiceId) { return "https://www.example.com/invoice/" + invoiceId; } } ``` ```JAVA @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 插件如何配置。 ![](http://yano.oss-cn-beijing.aliyuncs.com/blog/2025-04-22-14-24-29.png) cline_mcp_setting.json 增加如下配置: ```json { "mcpServers": { "invoice-local": { "url": "http://localhost:8080/sse", "autoApprove": [ "getInvoiceUrl" ] } } } ``` 我们可以看到对应的 getInvoiceUrl 方法已经被自动注册到 MCP Server 中。 ![](http://yano.oss-cn-beijing.aliyuncs.com/blog/2025-04-22-14-25-28.png) ### 使用 MCP! 在 cline 中输入问题:“我有一个发票 id 是 123456,发票链接是多少?”,可以看到模型会自动判断是否需要调用 MCP Server 中的 getInvoiceUrl 方法,并拼装参数,获取结果。 ![](http://yano.oss-cn-beijing.aliyuncs.com/blog/2025-04-22-14-27-02.png) ### 说明 1. JDK 版本必须 >= 17 2. Spring Boot 版本必须 >= 3.2 3. Spring AI 底层使用 [modelcontextprotocol / java-sdk]([https://](https://github.com/modelcontextprotocol/java-sdk)) 4. MCP 协议等都在快速发展中,上面的代码示例仅供参考,具体实现可能会有所不同 ## 完整配置示例 **Application.java:** ```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:** ```yaml 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:** ```bash ~/Library/Application\ Support/Claude/claude_desktop_config.json ``` **Windows:** ```bash %APPDATA%\Claude\claude_desktop_config.json ``` **配置示例:** ```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 服务器: ```json { "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` ```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. **输入验证** ```java 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. **权限控制** ```java @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 速率限制** ```java @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. **结果缓存** ```java @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. **异步处理** ```java @Service public class AsyncFileTools { @Tool(description = "异步搜索文件") public CompletableFuture> searchFilesAsync( @ToolParam(name = "pattern") String pattern ) { return CompletableFuture.supplyAsync(() -> { // 耗时的文件搜索操作 return fileService.search(pattern); }); } } ``` 3. **连接池管理** ```java @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); } } ``` ### 错误处理 **统一异常处理:** ```java @ControllerAdvice public class McpExceptionHandler { @ExceptionHandler(SecurityException.class) public ResponseEntity handleSecurityException( SecurityException ex ) { return ResponseEntity .status(HttpStatus.FORBIDDEN) .body(new ErrorResponse( "SECURITY_ERROR", ex.getMessage() )); } @ExceptionHandler(IllegalArgumentException.class) public ResponseEntity handleValidationException( IllegalArgumentException ex ) { return ResponseEntity .status(HttpStatus.BAD_REQUEST) .body(new ErrorResponse( "VALIDATION_ERROR", ex.getMessage() )); } @ExceptionHandler(Exception.class) public ResponseEntity 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 ) {} ``` ### 监控与日志 ```java @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 中提供代码生成、重构、调试等智能辅助功能。 **实现示例:** ```java @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 suggestRefactoring( @ToolParam(name = "code") String code ) { return refactoringService.analyzePotentialImprovements(code); } } ``` ### 2. 企业数据分析 **功能描述:** 提供自然语言到 SQL 的转换,支持数据可视化。 ```java @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> data, @ToolParam(name = "chart_type") String chartType ) { return chartGenerator.generate(data, chartType); } } ``` ### 3. 文档生成与管理 ```java @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 自动化 ```java @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 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 服务器 - 网址: https://github.com/modelcontextprotocol/inspector - 功能: 实时查看工具调用、测试 prompts、监控资源 2. **MCP CLI** - 命令行工具 ```bash npm install -g @modelcontextprotocol/cli mcp test http://localhost:8080/sse ``` ### 社区服务器 访问 [mcp.so](https://mcp.so/servers) 浏览 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: 建议使用异步模式: ```java @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 官方网站**: https://modelcontextprotocol.io - **MCP 规范**: https://spec.modelcontextprotocol.io - **MCP GitHub**: https://github.com/modelcontextprotocol - **MCP 服务器目录**: https://mcp.so/servers ### Spring AI 相关 - **Spring AI 文档**: https://docs.spring.io/spring-ai/reference/ - **MCP 集成指南**: https://docs.spring.io/spring-ai/reference/api/mcp/ - **示例仓库**: https://github.com/spring-projects/spring-ai-examples - **Spring AI MCP Server Starter**: https://docs.spring.io/spring-ai/reference/api/mcp/mcp-server-boot-starter-docs.html ### 技术规范 - **JSON-RPC 2.0**: https://www.jsonrpc.org/specification - **Server-Sent Events**: https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events - **OpenAPI 3.0**: https://swagger.io/specification/ ### 社区资源 - **MCP Discord**: https://discord.gg/modelcontextprotocol - **MCP Reddit**: https://reddit.com/r/mcp - **Stack Overflow**: 标签 `model-context-protocol` - **YouTube 教程**: 搜索 "MCP Tutorial" ### 相关项目 - **Java SDK**: https://github.com/modelcontextprotocol/java-sdk - **TypeScript SDK**: https://github.com/modelcontextprotocol/typescript-sdk - **Python SDK**: https://github.com/modelcontextprotocol/python-sdk - **MCP Inspector**: https://github.com/modelcontextprotocol/inspector