随着 AI Agent 技术的发展,MCP(Model Context Protocol) 正在成为连接大模型与外部工具的标准协议之一。使用 Spring Boot 搭建一个 MCP Server,可以帮助你将自己的业务能力(如数据库查询、文件处理、内部系统调用等)安全地暴露给 LLM Agents 使用。
🚀 使用 Spring Boot 搭建自己的 MCP Server
✅ 本文将带你从零开始构建一个符合 MCP 规范 的轻量级 MCP Server,支持:
- 工具注册
- 动态上下文交互
- JSON-RPC over HTTP
- OpenAPI 文档集成
🔧 技术栈: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 —— 工具元信息
package com.example.mcpserver.model;
import lombok.Data;
import java.util.Map;
@Data
public class Tool {
private String name;
private String description;
private Map<String, Object> inputSchema; // JSON Schema 格式
}
ToolCallRequest.java
package com.example.mcpserver.model;
import lombok.Data;
import java.util.List;
import java.util.Map;
@Data
public class ToolCallRequest {
private List<Map<String, Object>> toolCalls;
}
ToolResult.java
package com.example.mcpserver.model;
import lombok.Data;
@Data
public class ToolResult {
private String toolName;
private Object result;
private boolean isError;
}
五、实现工具接口与注册中心
定义工具接口
// service/Tool.java
public interface Tool {
String getName();
String getDescription();
Object getInputSchema(); // 返回 JSON Schema
Object invoke(Map<String, Object> input);
}
实现示例工具:获取当前时间
// service/impl/TimeTool.java
@Component
public class TimeTool implements Tool {
@Override
public String getName() {
return "get_current_time";
}
@Override
public String getDescription() {
return "Returns the current time in ISO8601 format.";
}
@Override
public Object getInputSchema() {
return Map.of(
"type", "object",
"properties", Map.of()
);
}
@Override
public Object invoke(Map<String, Object> input) {
return Map.of(
"time", Instant.now().toString(),
"timezone", ZoneId.systemDefault()
);
}
}
工具注册中心(自动收集所有工具)
// service/ToolRegistry.java
@Service
public class ToolRegistry {
private final Map<String, Tool> tools = new ConcurrentHashMap<>();
public ToolRegistry(List<Tool> toolList) {
for (Tool tool : toolList) {
tools.put(tool.getName(), tool);
}
System.out.println("✅ 注册了 " + tools.size() + " 个 MCP 工具");
}
public Collection<Tool> getTools() {
return tools.values();
}
public Tool getTool(String name) {
return tools.get(name);
}
}
Spring 会自动注入所有实现了
Tool接口的 Bean。
六、编写 MCP Controller(核心端点)
// controller/McpController.java
@RestController
@RequestMapping("/mcp")
@RequiredArgsConstructor
public class McpController {
private final ToolRegistry toolRegistry;
/**
* GET /mcp/tools - 列出所有可用工具
*/
@GetMapping("/tools")
public ResponseEntity<List<Tool>> listTools() {
return ResponseEntity.ok(toolRegistry.getTools().stream().toList());
}
/**
* POST /mcp/call-tool - 调用工具
*/
@PostMapping("/call-tool")
public ResponseEntity<List<ToolResult>> callTools(@RequestBody ToolCallRequest request) {
return ResponseEntity.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) {
return new ToolResult(toolName, "Tool not found", true);
}
try {
Object result = tool.invoke(input);
return new ToolResult(toolName, result, false);
} catch (Exception e) {
return new ToolResult(toolName, e.getMessage(), true);
}
})
.collect(Collectors.toList()));
}
}
七、配置路由(application.yml)
server:
port: 8080
logging:
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,以及开源框架如 LangChain、LlamaIndex 正在逐步支持 MCP。
✅ 总结:搭建 MCP Server 的关键步骤
- ✅ 定义工具接口
Tool - ✅ 实现具体业务逻辑(如时间、天气、订单查询)
- ✅ 使用
ToolRegistry自动注册 - ✅ 提供
/mcp/tools和/mcp/call-tool两个标准接口 - ✅ 安全加固 + 监控日志
- ✅ 部署上线并接入 AI Agent
🙌 感谢你读到这里!
🔍 技术之路没有捷径,但每一次阅读、思考和实践,都在悄悄拉近你与目标的距离。
💡 如果本文对你有帮助,不妨 👍 点赞、📌 收藏、📤 分享 给更多需要的朋友!
💬 欢迎在评论区留下你的想法、疑问或建议,我会一一回复,我们一起交流、共同成长 🌿
🔔 关注我,不错过下一篇干货!我们下期再见!✨
2152

被折叠的 条评论
为什么被折叠?



