手把手教你用 Spring Boot 搭建一个 MCP Server

手把手教你用 Spring Boot 搭建一个 MCP Server

随着 AI Agent 技术的发展,MCP(Model Context Protocol) 正在成为连接大模型与外部工具的标准协议之一。使用 Spring Boot 搭建一个 MCP Server,可以帮助你将自己的业务能力(如数据库查询、文件处理、内部系统调用等)安全地暴露给 LLM Agents 使用。


🚀 使用 Spring Boot 搭建自己的 MCP Server

✅ 本文将带你从零开始构建一个符合 MCP 规范 的轻量级 MCP Server,支持:工具注册动态上下文交互JSON-RPC over HTTPOpenAPI 文档集成
🔧 技术栈:Spring Boot 3 + Java 17 + Maven + Spring Web + Jackson

一、什么是 MCP?

MCP(Model Context Protocol) 是由 Anthropic 提出的一种标准化协议,用于让语言模型(LLM)以结构化方式访问外部工具和数据源。

核心功能:

  • List Tools:列出可用的工具
  • Call Tool:调用指定工具并返回结果
  • Streaming Support(可选):支持流式响应
类似于 OpenAI 的 Function Calling 或 Google 的 Vertex AI Gateway,但更开放、轻量。

二、项目结构设计

src/ ├── main/ │ ├── java/ │ │ └── com.example.mcpserver/ │ │ ├── McpApplication.java # 主启动类 │ │ │ │ │ ├── controller/ │ │ │ └── McpController.java # 处理 /mcp 路由 │ │ │ │ │ ├── model/ │ │ │ ├── Tool.java # 工具元信息 │ │ │ ├── ToolCallRequest.java # 调用请求 │ │ │ └── ToolResult.java # 返回结果 │ │ │ │ │ └── service/ │ │ ├── ToolRegistry.java # 工具注册中心 │ │ └── impl/ │ │ ├── TimeTool.java # 示例工具:获取当前时间 │ │ └── WeatherTool.java # 示例工具:查天气 │ │ │ └── resources/ │ ├── application.yml │ └── openapi/mcp-api.yaml # OpenAPI 描述文件(可选)

三、添加依赖(pom.xml)

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Lombok 简化 POJO --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency><!-- JSON 处理 --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></endependency></dependencies>

四、定义核心数据模型

Tool.java —— 工具元信息

packagecom.example.mcpserver.model;importlombok.Data;importjava.util.Map;@DatapublicclassTool{privateString name;privateString description;privateMap<String,Object> inputSchema;// JSON Schema 格式}

ToolCallRequest.java

packagecom.example.mcpserver.model;importlombok.Data;importjava.util.List;importjava.util.Map;@DatapublicclassToolCallRequest{privateList<Map<String,Object>> toolCalls;}

ToolResult.java

packagecom.example.mcpserver.model;importlombok.Data;@DatapublicclassToolResult{privateString toolName;privateObject result;privateboolean isError;}

五、实现工具接口与注册中心

定义工具接口

// service/Tool.javapublicinterfaceTool{StringgetName();StringgetDescription();ObjectgetInputSchema();// 返回 JSON SchemaObjectinvoke(Map<String,Object> input);}

实现示例工具:获取当前时间

// service/impl/TimeTool.java@ComponentpublicclassTimeToolimplementsTool{@OverridepublicStringgetName(){return"get_current_time";}@OverridepublicStringgetDescription(){return"Returns the current time in ISO8601 format.";}@OverridepublicObjectgetInputSchema(){returnMap.of("type","object","properties",Map.of());}@OverridepublicObjectinvoke(Map<String,Object> input){returnMap.of("time",Instant.now().toString(),"timezone",ZoneId.systemDefault());}}

工具注册中心(自动收集所有工具)

// service/ToolRegistry.java@ServicepublicclassToolRegistry{privatefinalMap<String,Tool> tools =newConcurrentHashMap<>();publicToolRegistry(List<Tool> toolList){for(Tool tool : toolList){ tools.put(tool.getName(), tool);}System.out.println("✅ 注册了 "+ tools.size()+" 个 MCP 工具");}publicCollection<Tool>getTools(){return tools.values();}publicToolgetTool(String name){return tools.get(name);}}
Spring 会自动注入所有实现了 Tool 接口的 Bean。

六、编写 MCP Controller(核心端点)

// controller/McpController.java@RestController@RequestMapping("/mcp")@RequiredArgsConstructorpublicclassMcpController{privatefinalToolRegistry toolRegistry;/** * GET /mcp/tools - 列出所有可用工具 */@GetMapping("/tools")publicResponseEntity<List<Tool>>listTools(){returnResponseEntity.ok(toolRegistry.getTools().stream().toList());}/** * POST /mcp/call-tool - 调用工具 */@PostMapping("/call-tool")publicResponseEntity<List<ToolResult>>callTools(@RequestBodyToolCallRequest request){returnResponseEntity.ok(request.getToolCalls().stream().map(call ->{String toolName =(String) call.get("name");Map<String,Object> input =(Map<String,Object>) call.get("input");Tool tool = toolRegistry.getTool(toolName);if(tool ==null){returnnewToolResult(toolName,"Tool not found",true);}try{Object result = tool.invoke(input);returnnewToolResult(toolName, result,false);}catch(Exception e){returnnewToolResult(toolName, e.getMessage(),true);}}).collect(Collectors.toList()));}}

七、配置路由(application.yml)

server:port:8080logging:level:com.example: DEBUG 

八、测试你的 MCP Server

启动应用

mvn spring-boot:run 

1. 查看可用工具

curl http://localhost:8080/mcp/tools 

输出示例:

[{"name":"get_current_time","description":"Returns the current time in ISO8601 format.","inputSchema":{...}}]

2. 调用工具

curl -X POST http://localhost:8080/mcp/call-tool \ -H "Content-Type: application/json"\ -d '{ "toolCalls": [ { "name": "get_current_time", "input": {} } ] }'

返回:

[{"toolName":"get_current_time","result":{"time":"2025-11-04T15:40:00Z","timezone":"Asia/Shanghai"},"isError":false}]

九、进阶优化建议

功能实现思路
✅ 认证鉴权添加 JWT 或 API Key 验证(如 @RequestHeader("X-API-Key")
✅ 请求校验使用 @Valid 和 JSON Schema 校验输入参数
✅ 异步执行对耗时工具使用 @Async 支持非阻塞调用
✅ 日志追踪加入 MDC、Trace ID,便于调试
✅ OpenAPI 文档使用 SpringDoc(Swagger)生成 /docs 页面
✅ 流式响应改用 SseEmitter 或 WebSocket 支持 streaming
✅ 自动发现扫描注解(如 @McPTool)自动注册

十、部署与集成

部署方式

  • 构建成 JAR 包运行
  • 打包为 Docker 镜像
  • 部署到 Kubernetes 并通过 Ingress 暴露

与 AI Agent 集成

你可以将这个 MCP Server 地址注册到支持 MCP 的客户端中,例如:

{"mcpServers":{"my-company-tools":{"url":"https://mcp.yourcompany.com/mcp","apiKey":"xxx"}}}

目前主流平台如 Anthropic Claude,以及开源框架如 LangChainLlamaIndex 正在逐步支持 MCP。


✅ 总结:搭建 MCP Server 的关键步骤

  1. ✅ 定义工具接口 Tool
  2. ✅ 实现具体业务逻辑(如时间、天气、订单查询)
  3. ✅ 使用 ToolRegistry 自动注册
  4. ✅ 提供 /mcp/tools/mcp/call-tool 两个标准接口
  5. ✅ 安全加固 + 监控日志
  6. ✅ 部署上线并接入 AI Agent

🙌 感谢你读到这里!
🔍 技术之路没有捷径,但每一次阅读、思考和实践,都在悄悄拉近你与目标的距离。
💡 如果本文对你有帮助,不妨 👍 点赞、📌 收藏、📤 分享 给更多需要的朋友!
💬 欢迎在评论区留下你的想法、疑问或建议,我会一一回复,我们一起交流、共同成长 🌿
🔔 关注我,不错过下一篇干货!我们下期再见!✨

Read more

PHP驱动Pdo_kdb连接Kingbase数据库全攻略:从零到实战的深度指南

PHP驱动Pdo_kdb连接Kingbase数据库全攻略:从零到实战的深度指南

引言:当国产数据库遇见PHP生态的桥梁 在数字化转型的浪潮中,国产数据库正以惊人的速度崛起。作为人大金仓自主研发的核心产品,KingbaseES凭借其与PostgreSQL的高度兼容性、金融级安全特性以及国产化适配优势,已成为政企领域替代Oracle的主流选择。然而,对于PHP开发者而言,如何高效连接并操作这款国产数据库却成为一道技术门槛。 KingbaseES 数据库【系列篇章】: No.文章地址(点击进入)1电科金仓KingbaseES数据库解析:国产数据库的崛起与技术创新2KingBase数据库迁移利器:KDTS工具深度解析与实战指南3KingBase数据库迁移利器:KDTS工具 MySQL数据迁移到KingbaseES实战4电科金仓KingbaseES V9数据库:国产数据库的自主创新与行业实践深度解析5KingbaseES客户端工具Ksql使用全指南:从安装到高级操作6Spring JDBC与KingbaseES深度集成:构建高性能国产数据库应用实战7深度解析:基于 ODBC连接 KingbaseES 数据库的完整操作与实践8Python驱动Ksycopg2连接和使

【MCP】使用SpringBoot基于Streamable-HTTP构建MCP-Server

【MCP】使用SpringBoot基于Streamable-HTTP构建MCP-Server

【MCP】使用SpringBoot基于Streamable-HTTP构建MCP-Server * 背景 * SSE与Streamable-HTTP * 本文开发环境介绍 * pom核心依赖 * MCP工具类 * 创建自动配置类 * 创建启动类 * 配置文件 * 必须配置项 * 注意配置项 * 相关配置类 * 核心逻辑 * curl测试 背景 最近几年AI应用越来越广泛,Anthropic公司在2024年11月提出了MCP协议,随着时间推移,支持MCP协议的厂商越来越多。 MCP的client端和server端通讯的协议也在逐步演进,一开始主流的是SSE协议,随后又诞生了Streamable-HTTP协议,用于取代SSE协议。 本文将介绍如何使用SpringBoot基于Streamable-HTTP构建MCP-Server服务端。 SSE与Streamable-HTTP MCP(Model Context Protocol)协议通过PR #206引入的Streamable HTTP传输层,是针对AI模型与外部工具通信场景的一次底层革

Flutter 组件 okay 的适配 鸿蒙Harmony 深度进阶 - 驾驭异步结果链式融合、实现鸿蒙端分布式业务逻辑解耦与精密审计方案

Flutter 组件 okay 的适配 鸿蒙Harmony 深度进阶 - 驾驭异步结果链式融合、实现鸿蒙端分布式业务逻辑解耦与精密审计方案

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 okay 的适配 鸿蒙Harmony 深度进阶 - 驾驭异步结果链式融合、实现鸿蒙端分布式业务逻辑解耦与精密审计方案 前言 在前文中,我们探讨了 okay 在鸿蒙(OpenHarmony)端实现基础 Result 模式包装的实战。但在真正的“分布式微服务聚合”、“高并发资产对账”以及“具备自愈能力的 IoT 指令链”场景中。简单的 ok() 与 err() 判定往往不足以支撑起复杂的业务全景。面对需要同时并行发起 3 个 API 请求,并要求在“所有请求均成功时执行合并、任一请求失败时执行局部逻辑路由”的高阶需求。如果缺乏一套完善的异步结果映射与多级逻辑聚合机制。不仅会导致异步回调地狱(Callback Hell)在

多智能体(Multi-Agent)架构选型:四种模式,一张图看懂

多智能体(Multi-Agent)架构选型:四种模式,一张图看懂 摘要(先看结论) 多智能体不是“更高级”,而是用更高的系统复杂度换取:上下文隔离、并行化、分工协作、长流程可控。 * 仍然能用“单 Agent + 好工具”解决:不要上多智能体 * 需要强控制权 + 上下文隔离:选 Subagents(主-子集中编排) * 需要单 Agent 多专业化且保持交互简单:选 Skills(按需加载) * 需要多阶段顺序流程(每阶段职责清晰):选 Handoffs(状态驱动交接) * 需要多领域并行查询 + 合成答案:选 Router(路由分发 + 汇总) 一句话口诀:并行找 Router,顺序走 Handoffs,强控用 Subagents,轻量用