如何基于现有的 Controller 接口 API 暴露 MCP(Model Context Protocol)。MCP 是 Anthropic 推出的开放协议,用于标准化 AI 模型与外部工具/数据源的集成。
基于现有 Controller 接口 API 暴露 MCP(Model Context Protocol)主要有以下几种架构方案,适用于不同的技术栈和场景:
🏗️ 架构方案对比
| 方案 | 适用场景 | 复杂度 | 侵入性 |
|---|---|---|---|
| Spring AI MCP 注解 | Spring Boot 项目 | 低 | 无(直接注解现有方法) |
| API Gateway 转换 | 已有 REST API,需统一管理 | 中 | 无(网关层转换) |
| 独立 MCP Wrapper | 非 Spring 项目或复杂遗留系统 | 中 | 低(外挂式) |
| OpenAPI 自动生成 | 已有 OpenAPI 规范 | 低 | 无 |
方案一:Spring AI MCP 注解(推荐)
适用于 Spring Boot + 现有 Controller,直接在现有方法上加注解暴露为 MCP Tool 。
1. 添加依赖
xml
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-mcp-server-webmvc-spring-boot-starter</artifactId>
</dependency>
2. 现有 Controller 改造
java
@RestController
@RequestMapping("/api/orders")
public class OrderController {
// 原有 HTTP 接口保持不变
@GetMapping("/{orderNo}")
public Order getOrder(@PathVariable String orderNo) {
return orderService.query(orderNo);
}
// 新增:同一方法暴露为 MCP Tool
@Tool(description = "根据订单号查询订单状态")
public Order queryOrderStatus(
@ToolParam(description = "订单号,格式为8位数字") String orderNo
) {
// 复用原有业务逻辑
return orderService.query(orderNo);
}
}
3. 配置 MCP Server
yaml
# application.yml
spring:
ai:
mcp:
server:
enabled: true
name: my-business-mcp-server
version: 1.0.0
type: sync # 或 async
sse-message-endpoint: /mcp/messages # SSE 传输端点
4. 启动类配置
java
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public ToolCallbackProvider orderTools(OrderController orderController) {
return MethodToolCallbackProvider.builder()
.toolObjects(orderController) // 扫描 Controller 中的 @Tool 方法
.build();
}
}
特点:
- ✅ 零侵入:原有 HTTP 接口完全保留
- ✅ 双协议支持:同时支持 REST + MCP
- ✅ 自动发现:
@Tool方法自动注册为 MCP Tools
方案二:Azure API Management / Gravitee 网关转换
适用于 已有 REST API,需在网关层统一暴露 MCP 。
Azure API Management 配置
json
// 在 Azure Portal 中配置
{
"mcpServer": {
"enabled": true,
"transport": {
"type": "streamableHttp"
},
"tools": [
{
"name": "queryOrder",
"description": "查询订单",
"endpoint": "/api/orders/{orderNo}", // 映射到后端 Controller
"method": "GET",
"parameters": {
"orderNo": {
"type": "string",
"description": "订单号",
"required": true
}
}
}
]
}
}
特点:
- ✅ 零代码改造
- ✅ 内置限流、认证、审计
- ⚠️ 仅支持 Tools,不支持 Resources/Prompts
方案三:独立 MCP Wrapper(通用方案)
适用于 非 Spring 项目 或需要 解耦暴露 。
目录结构
mcp-wrapper/
├── config/
│ └── mcp-config.yaml # API 映射配置
├── src/
│ └── wrapper/
│ └── ApiMcpServer.java # 包装器实现
└── pom.xml
YAML 配置映射
yaml
# mcp-config.yaml
server:
name: "Order API MCP Wrapper"
description: "Wrap existing Order Controller as MCP"
version: "1.0.0"
tools:
- name: "query_order"
description: "查询订单状态"
endpoint: "http://localhost:8080/api/orders/{orderNo}" # 指向现有 Controller
method: "GET"
parameters:
orderNo:
type: "string"
description: "订单号"
required: true
location: "path"
auth:
type: "bearer"
token_env: "API_TOKEN"
- name: "create_order"
description: "创建新订单"
endpoint: "http://localhost:8080/api/orders"
method: "POST"
body_template: |
{
"productId": "{{productId}}",
"quantity": {{quantity}}
}
parameters:
productId:
type: "string"
required: true
quantity:
type: "integer"
required: true
default: 1
Wrapper 实现(Go 示例)
go
package main
import (
"github.com/gomcpgo/api-wrapper-mcp/pkg/server"
)
func main() {
// 读取配置,自动创建 MCP Server
svr, err := server.FromConfig("mcp-config.yaml")
if err != nil {
log.Fatal(err)
}
// 启动 SSE 服务
svr.StartSSE(":8081")
}
方案四:OpenAPI 自动生成 MCP
适用于 已有 OpenAPI/Swagger 规范 。
bash
# 使用 openapi-to-mcp-converter
npx openapi-to-mcp-converter \
--input ./api-docs.json \
--output ./mcp-server.yaml \
--base-url http://localhost:8080
生成的 mcp-server.yaml 可直接被 MCP 客户端使用。
🔧 关键配置对比
| 配置项 | Spring AI | Gateway 转换 | Wrapper 模式 |
|---|---|---|---|
| 传输协议 | SSE / stdio | HTTP/SSE | HTTP/SSE/WebSocket |
| 认证方式 | 继承 Spring Security | 网关统一处理 | 配置文件中指定 |
| 参数映射 | 注解自动推导 | OpenAPI 规范 | YAML 模板配置 |
| 错误处理 | 全局异常处理器 | 网关策略 | 自定义中间件 |
| 性能 | 高(原生) | 中(代理层) | 中(额外跳转) |
💡 选型建议
| 场景 | 推荐方案 |
|---|---|
| Spring Boot 新项目 | 方案一:Spring AI MCP 注解 |
| Spring Boot 遗留系统 | 方案一:添加注解,或方案三:Wrapper |
| 多语言/异构系统 | 方案三:独立 Wrapper |
| 已有 API 网关 | 方案二:Azure APIM / Gravitee |
| 快速 POC | 方案四:OpenAPI 自动生成 |
需要针对具体技术栈(如 Spring Boot 版本、是否有网关)提供更详细的代码示例吗?