手把手教你用 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 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,以及开源框架如 LangChainLlamaIndex 正在逐步支持 MCP。


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

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

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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Aollo风起

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值