本文对比两种将 Java8 老项目接入 MCP 的典型架构,从 initialize、tools/list、tools/call、执行 四个阶段说明 Agent、中间层、业务项目的职责与差异。


1. 架构总览

模式一:Agent - Gateway - 业务项目

Agent (MCP Client)
    |  MCP / SSE
    v
ai-mcp-gateway (查 DB 配置)
    |  HTTP 转发
    v
业务项目 (Java8 REST)

模式二:Agent - Adapter - 业务项目

Agent (MCP Client)
    |  MCP / SSE
    v
MCP Adapter (Java17 + @Tool)
    |  HTTP 内部调用
    v
业务项目 (Java8 REST)
角色职责
AgentMCP Client:配置 SSE 地址,initialize / tools/list / tools/call
Gateway / AdapterMCP Server:维护工具清单,响应 MCP 协议,转发或执行调用
业务项目普通 REST API,不感知 MCP,零改动

共同点: Agent 侧行为一致,只和 MCP Server 通信,永远不直连业务项目。


2. 四阶段对比

2.1 initialize(握手)

对比项Agent - Gateway - 业务项目Agent - Adapter - 业务项目
Agent 连接地址GET /api-gateway/{gatewayId}/mcp/sseGET /sse
Agent 发送JSON-RPC initialize同左
中间层行为InitializeHandler 查 mcp_gateway 表,返回网关 name / version / desc / capabilitiesSpring AI MCP Server 读 application.yml,返回 serverInfo + capabilities
是否访问业务项目
是否发现工具否,此阶段不做否,此阶段不做(工具在 Adapter 启动时已注册)
鉴权支持 api_key(mcp_gateway_auth:限流、过期)默认无,需自行实现

initialize 只做协议握手,不拉工具列表。


2.2 tools/list(工具发现)

对比项网关模式Adapter 模式
工具清单来源MySQL进程内存
具体存储mcp_gateway_tool + mcp_protocol_mappingMethodToolCallbackProvider 扫描 @Tool
inputSchema 生成Swagger 导入存库,ToolsListHandler 运行时重建嵌套 Schema方法签名 + @JsonProperty 反射生成
新增/修改工具管理页导入 Swagger,改 DB,无需重启写 Java 代码,需重新发版
是否访问业务项目

Agent 从 tools/list 拿到什么:

{
  "tools": [
    {
      "name": "getCompanyEmployee",
      "description": "获取公司雇员信息",
      "inputSchema": {
        "type": "object",
        "properties": {}
      }
    }
  ]
}
包含不包含
name、description、inputSchema业务项目 HTTP URL
内部转发规则、鉴权 Header

真实 URL 封装在中间层内部,不暴露给 Agent。


2.3 tools/call(工具调用)

对比项网关模式Adapter 模式
Agent 发送tools/call { name, arguments } 发给网关同左,发给 Adapter
路由方式ToolsCallHandler 按 gatewayId + toolName 查 DBMCP 框架按 name 匹配 @Tool 方法
配置来源mcp_protocol_http(url / method / headers / timeout)@Tool 方法体内的 Java 代码
参数处理SessionPort:POST 序列化 body;GET 拼 query / pathJackson 反序列化为方法参数对象
找不到工具METHOD_NOT_FOUND框架返回 tool not found

重要:tools/call 是 Agent 调中间层(MCP 协议),不是 Agent 直接 HTTP 调业务项目。


2.4 执行阶段(调业务项目)

对比项网关模式Adapter 模式
谁调业务项目网关 SessionPort + GenericHttpGateway@Tool 方法内 RestTemplate / Feign
调用方式通用 HTTP 透传(URL 来自 DB)手写逻辑(可编排、聚合、缓存)
业务项目改动零改动(需 REST + Swagger)零改动
响应处理响应体原样包进 MCP result方法返回值序列化,可先加工

调用链:

LLM 选择 tool
  -> Agent 发 MCP tools/call
  -> Gateway / Adapter 执行
  -> HTTP 调业务项目
  -> 结果沿 MCP 返回 Agent -> LLM

3. 关键差异一览

维度网关模式Adapter 模式
工具定义DB 配置驱动代码 @Tool 驱动
维护成本导 Swagger,运维友好开发发版
调用能力通用透传,受 mapping 模型限制任意 Java 逻辑
多系统接入一个网关统一治理、鉴权、限流通常一业务一 Adapter
header 参数当前 mapping 不映射 header代码内任意处理
适用场景接口多、标准 REST、要统一网关接口少、需业务加工、Swagger 不规范

4. Agent 侧配置(两种模式相同)

Agent 是 MCP Client,只需配置 MCP Server 的 SSE 地址:

// McpConfigVO
private String baseUri;       // http://gateway:8777 或 http://adapter:8701
private String sseEndpoint;   // /api-gateway/gateway_001/mcp/sse 或 /sse
private String authApiKey;    // 可选
private Integer timeout;      // 可选

初始化与拉工具(SDK 自动完成):

HttpClientSseClientTransport transport = HttpClientSseClientTransport
        .builder(baseUri)
        .sseEndpoint(sseEndpoint)
        .build();

McpSyncClient client = McpClient.sync(transport).build();
client.initialize();   // 1. 握手

ToolCallback[] tools = new SyncMcpToolCallbackProvider(client)
        .getToolCallbacks();   // 2. 内部发 tools/list

Agent 不需要:

  • 在每个 Tool 上写 @Tool
  • 维护 Swagger / 工具 schema
  • 知道业务项目 HTTP 地址

5. 网关模式:DB 表结构

mcp_gateway          -> 网关实例(gateway_id、名称、版本)
mcp_gateway_tool     -> Tool 注册(tool_name、description、protocol_id)
mcp_protocol_mapping -> 参数映射,生成 inputSchema
mcp_protocol_http    -> 实际 HTTP 地址(tools/call 时用,Agent 不可见)
mcp_gateway_auth     -> api_key、限流、过期
  • tools/list:读 mcp_gateway_tool + mcp_protocol_mapping
  • tools/call:读 mcp_gateway_tool + mcp_protocol_http,再 HTTP 转发

6. Adapter 模式:Tool 注册

@SpringBootApplication
public class Application {
    @Bean
    public ToolCallbackProvider tools(XxxToolService service) {
        return MethodToolCallbackProvider.builder()
                .toolObjects(service)
                .build();
    }
}

@Service
public class XxxToolService {
    @Tool(description = "获取公司员工信息")
    public XxxResponse getCompanyEmployee(XxxRequest req) {
        return restTemplate.postForObject(
                "http://old-project/api/v1/employee/query",
                req,
                XxxResponse.class
        );
    }
}
  • 启动时:扫描 @Tool,注册,日志 Registered tools: N
  • tools/list:从内存注册表返回
  • tools/call:反射调用方法,内部 HTTP 调业务项目

7. 完整时序

7.1 网关模式

Agent          Gateway         MySQL           业务项目
  |               |               |               |
  |-- GET /sse -->|               |               |
  |-- initialize->|               |               |
  |               |-- 查网关 ---->|               |
  |<- Initialize -|               |               |
  |               |               |               |
  |-- tools/list->|               |               |
  |               |-- 查 tool --->|               |
  |<- tools[] ----|               |               |
  |               |               |               |
  |-- tools/call->|               |               |
  |               |-- 查 http --->|               |
  |               |---------------- HTTP ------->|
  |               |<--------------- 响应 ---------|
  |<- result -----|               |               |

7.2 Adapter 模式

Agent          Adapter         业务项目
  |               |               |
  |-- GET /sse -->|               |
  |-- initialize->|               |
  |<- Initialize -|               |
  |               |               |
  |-- tools/list->|               |
  |<- tools[] ----|               |
  |               |               |
  |-- tools/call->|               |
  |               |-- 执行 @Tool -|
  |               |---------------- HTTP ------->|
  |               |<--------------- 响应 ---------|
  |<- result -----|               |

8. 选型建议

场景推荐
老项目有 REST + Swagger,接口多,要统一鉴权/限流网关模式
MCP Client 直连,接口少,需要复杂编排/聚合Adapter 模式
老项目是 Java8,不能跑 Spring AI MCP新建 Java17 Adapter,业务项目不动
已有 ai-mcp-gatewayAgent 配网关 SSE,不必再建 @Tool 项目

9. 常见误解

误解正确理解
tools/list 里有业务项目 URL只有 name / description / inputSchema
Agent tools/call 直接 HTTP 调业务项目Agent 只发 MCP tools/call 给中间层
initialize 时会扫 @Tool 或 Swagger工具在网关是 DB 预置;在 Adapter 是启动时注册
Agent 里要写 @Tool 才能调老项目 MCPAgent 只配 SSE;@Tool 在 Adapter 侧

10. 一句话总结

Agent 在两种模式下行为完全一致(连 SSE -> initialize -> tools/list -> tools/call)。

差异在中间层:网关 = DB 配置 + 通用 HTTP 透传;Adapter = @Tool 注册 + Java 方法内 HTTP。

业务项目两种方式均零改动,且永远不被 Agent 直连。

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐