MCP 协议深度解析:AI Agent 时代的"USB-C 接口",Java 开发者如何上车?

全文约 12000 字,覆盖协议原理、架构剖析、Spring AI 实战、生产落地全流程。
不聊概念焦虑,只聊能跑通的代码和架构决策。


目录

  1. 引言:当 AI 遇到"信息孤岛"
  2. MCP 是什么?一个 USB-C 接口的类比
  3. MCP 核心架构:两层协议一张图
  4. 三大原语:Tools、Resources、Prompts
  5. 实战一:用 Spring AI 搭建你的第一个 MCP Server
  6. 实战二:MCP Client 消费远程 Server
  7. 传输层选型:Stdio vs Streamable HTTP 怎么选?
  8. MCP 的安全模型
  9. MCP vs Function Calling vs Agent API——一张表说清楚
  10. 2026 年 MCP 生态全景
  11. 从架构师视角看 MCP 的定位
  12. 避坑指南(来自实际踩坑)
  13. 总结与行动清单

一、引言:当 AI 遇到"信息孤岛"

1.1 一个每天都在发生的场景

想象这个场景:你正在用 Claude Code 或 ChatGPT 写代码,想让 AI 帮忙查一下生产数据库里某个用户的订单状态。于是你手动复制了一段 SQL,跑到数据库客户端执行,然后把结果粘贴回对话框。

这个动作,2026 年的开发者可能每天要重复几十次。

问题出在哪里?AI 的能力再强,也连不上你的系统。 它读不到你的数据库、查不了你的 API、操作不了你的文件系统。每一个数据源、每一个工具,都需要你手动"投喂"。

1.2 2025 年之前:Function Calling 的碎片化困境

在 MCP 出现之前,让 AI 调用外部工具的主流方式是各家大模型厂商提供的 Function Calling(工具调用)

  • OpenAI 有 tools 参数,你需要写 JSON Schema 描述每个函数
  • Anthropic 有 tool_use,格式跟 OpenAI 不完全兼容
  • 你需要把工具描述硬编码在每次请求里
  • 每接入一个外部系统,都要写一堆适配胶水代码

结果就是:每个 AI 应用都在重复造轮子,整个生态像极了 USB 标准统一之前——每个设备有自己的接口和线缆。

1.3 MCP 的诞生:一个开放标准的出现

2024 年底,Anthropic 提出了 Model Context Protocol(MCP),一个开放协议,旨在标准化 AI 模型与外部工具、数据源、API 之间的交互方式。到 2026 年 7 月,MCP 已经迭代到 2026-07-28 协议版本,获得了整个行业的广泛支持:

  • Claude Code / Claude Desktop 原生支持
  • ChatGPT 全面接入 MCP
  • VS Code Copilot 支持配置 MCP Server
  • Cursor / MCPJam 等工具也已拥抱

从一个社区倡议变成了 AI Agent 基础设施层的核心协议


二、MCP 是什么?一个 USB-C 接口的类比

2.1 一句话定义

MCP(Model Context Protocol)是一个开源的标准化协议,用于连接 AI 应用程序与外部系统。它定义了一套通用的通信规范,让 AI 模型能够发现和调用外部工具、读取数据源、使用预设提示模板。

用官方文档的原话说:

Think of MCP like a USB-C port for AI applications. Just as USB-C provides a standardized way to connect electronic devices, MCP provides a standardized way to connect AI applications to external systems.

2.2 USB-C 类比拆解

USB-C MCP
统一了设备充电和数据传输接口 统一了 AI ↔ 外部系统的连接方式
一个充电器可以充手机、笔记本、平板 一个 MCP Server 可以被 Claude、ChatGPT、VS Code 共用
支持不同的协议(USB 2.0/3.0/Thunderbolt) 支持不同的传输层(Stdio / Streamable HTTP)
即插即用 通过 discovery 机制自动发现能力

2.3 用 MCP 能做什么?

  • Agent 访问你的 Google Calendar 和 Notion,像一个真正的个人助理
  • Claude Code 根据 Figma 设计稿生成完整的 Web 应用
  • 企业聊天机器人连接多个内部数据库,用户用自然语言查数据
  • AI 模型操作 Blender 做 3D 建模,然后直接 3D 打印

这些不是 Demo,而是 2026 年已经普遍落地的场景。


三、MCP 核心架构:两层协议一张图

3.1 三大参与者

MCP 遵循 客户端-服务器架构,涉及三个角色:

┌─────────────────────────────────────────────────┐
│                  MCP Host                        │
│          (AI 应用: Claude Code / ChatGPT)        │
│                                                   │
│  ┌──────────────┐   ┌──────────────┐             │
│  │ MCP Client 1 │   │ MCP Client 2 │  ...        │
│  └──────┬───────┘   └──────┬───────┘             │
│         │                  │                      │
└─────────┼──────────────────┼──────────────────────┘
          │                  │
    ┌─────▼──────┐    ┌─────▼──────┐
    │ MCP        │    │ MCP        │
    │ Server A   │    │ Server B   │
    │ (数据库)    │    │ (文件系统)  │
    └────────────┘    └────────────┘
  • MCP Host:AI 应用程序,协调和管理多个 MCP Client(如 Claude Code、VS Code)
  • MCP Client:与 MCP Server 建立点对点连接的组件
  • MCP Server:对外提供工具、数据和提示的服务程序

Host 每连接一个 Server,就创建一个 Client 实例。本地 Stdio 传输通常一个 Client 对应一个 Server 进程;远程 Streamable HTTP 传输一个 Server 可以服务多个 Client。

3.2 两层协议

MCP 分为 数据层传输层,概念上数据层在内,传输层在外:

┌──────────────────────────────────────┐
│            Data Layer                │
│  (JSON-RPC 2.0 协议 · 原语 · 发现)   │
├──────────────────────────────────────┤
│          Transport Layer             │
│  (Stdio / Streamable HTTP / SSE)     │
└──────────────────────────────────────┘
数据层(Data Layer)

基于 JSON-RPC 2.0 的消息协议,包含:

  • 发现(Discovery):Client 通过 server/discover 查询 Server 支持的协议版本和能力
  • 工具操作tools/list 发现工具列表,tools/call 调用工具
  • 资源操作resources/listresources/read
  • 提示操作prompts/listprompts/get
  • 通知(Notifications):实时变更通知(如工具列表变化)
传输层(Transport Layer)

两种传输机制(注意:传统 SSE 协议自 Spring AI 2.0 起已废弃,统一使用 Streamable HTTP):

传输方式 适用场景 特点
Stdio 本地进程间通信 零网络开销,适合开发调试和单机部署
Streamable HTTP 远程服务通信 支持 HTTP POST + SSE 流式返回,支持 OAuth 认证;SSE 的替代方案

3.3 协议版本 2026-07-28 的重要变化

2026 年最新协议版本相比早期版本有几个关键变化:

  1. Elicitation 取代 Sampling:Server 不再直接请求 LLM 采样,而是通过 Elicitation 向用户请求输入
  2. Notification 机制成熟:基于订阅(subscriptions/listen)的实时变更通知
  3. Stateless 设计:每个请求携带 _meta 字段包含协议版本和能力声明,Server 可以独立处理每个请求
  4. 三方登录标准化:OAuth 2.0 成为推荐的远程认证方式

3.4 一次完整的 MCP 交互流程

Client                          Server
  │                               │
  │──── server/discover ────────→│  ← 发现:查询能力
  │←── supportedVersions, caps ─│
  │                               │
  │──── tools/list ─────────────→│  ← 工具发现
  │←── [tool1, tool2, ...] ────│
  │                               │
  │──── tools/call(tool1,args) →│  ← 工具调用
  │←── result(content) ────────│
  │                               │
  │──── subscriptions/listen ───→│  ← 订阅通知
  │←── ack (subscriptionId) ───│
  │                               │
  │←── notification(toolsChanged)│  ← 实时变更通知
  │                               │

这是 MCP 最核心的交互模式。理解这 5 步,就理解了 MCP 的 80%


四、三大原语:Tools、Resources、Prompts

MCP 定义了三个核心原语(Primitives),它们是 Server 可以暴露给 Client 的能力类型:

4.1 Tools(工具)—— 最重要的原语

Tools 是 AI 模型可以调用的可执行函数,相当于给 AI 装上了"手"。

特点:

  • AI 模型决定何时调用(不是开发者硬编码调用)
  • 通过 tools/list 发现,通过 tools/call 执行
  • 入参使用 JSON Schema 定义,自动生成类型约束

典型场景:

  • 数据库查询:query_orders(userId)
  • API 调用:get_weather(city)
  • 文件操作:read_file(path)
// tools/list 响应示例
{
  "tools": [
    {
      "name": "query_orders",
      "description": "根据用户ID查询订单列表",
      "inputSchema": {
        "type": "object",
        "properties": {
          "userId": {
            "type": "integer",
            "description": "用户ID"
          },
          "status": {
            "type": "string",
            "enum": ["pending", "shipped", "completed"],
            "description": "订单状态筛选"
          }
        },
        "required": ["userId"]
      }
    }
  ]
}

4.2 Resources(资源)—— 提供给 AI 的数据

Resources 是有结构的数据源,让 AI 能"读到"系统中的信息。

特点:

  • 通过 URI 标识和访问,如 file:///config/app.yml
  • 支持 URI 模板参数:config://{key}
  • 可以订阅变更通知

典型场景:

  • 项目配置文件
  • 数据库 Schema
  • 日志文件内容

4.3 Prompts(提示模板)—— 可复用的交互模板

Prompts 是预定义的提示模板,帮助结构化 AI 的交互方式。

特点:

  • 包含参数化占位符
  • 可以包含 few-shot 示例
  • prompts/list 发现,通过 prompts/get 获取

4.4 三者对比

维度 Tools Resources Prompts
本质 函数执行 数据读取 模板填充
AI 角色 主动调用 被动读取 结构化输入
操作 tools/list + tools/call resources/list + resources/read prompts/list + prompts/get
典型场景 查数据库、发邮件 读配置文件、访问日志 生成 SQL、格式化输出
返回 执行结果 数据内容 填充后的提示

五、实战一:用 Spring AI 搭建你的第一个 MCP Server

这是全篇最核心的实战内容。我们将用 Spring Boot + Spring AI 2.0 搭建一个 MCP Server,暴露一个查询订单的 Tool。代码全程可跑通

5.1 技术选型

2026 年的 MCP Java 生态是这样的:

组件 选择 说明
Spring Boot 3.4+ 基础框架
Spring AI 2.0+ MCP 集成(Spring 官方维护)
MCP Java SDK 2.0.0 底层协议实现
传输方式 Stdio / Streamable HTTP 根据部署场景选择

从 Spring AI 2.0 开始,MCP 的 Spring 集成从 MCP Java SDK 迁移到了 Spring AI 项目组下。使用 org.springframework.ai 坐标。

5.2 项目初始化

方式一:Spring Initializr(推荐)

访问 start.spring.io,搜索并添加 “MCP Server” 依赖。

方式二:手动添加 Maven 依赖

Spring AI 2.0 提供两个 MCP Server Starter,根据你的传输模式选择:

<!-- ⭐ 方案 A:Stdio 模式(本地进程间通信,开发首选) -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-server</artifactId>
</dependency>

<!-- ⭐ 方案 B:Streamable HTTP 模式(远程服务,生产首选) -->
<!-- 需要配合 spring-boot-starter-web 使用 -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
</dependency>

⚠️ 特别注意:这两个 starter 对应不同的传输模式,不能混用。Stdio 模式用 spring-ai-starter-mcp-server,Streamable HTTP 用 spring-ai-starter-mcp-server-webmvc

完整示例(以 Stdio 模式为例):

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.4.3</version>
</parent>

<dependencyManagement>
    <dependencies>
        <!-- Spring AI BOM:统一管理版本 -->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>2.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <!-- Stdio 模式 MCP Server(版本由 BOM 管理) -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-starter-mcp-server</artifactId>
    </dependency>

    <!-- 数据库操作示例 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

5.3 编写 MCP Tool(核心代码)

Spring AI 2.0 提供了 @McpTool 注解,一行注解就能把普通 Spring Bean 方法暴露为 MCP Tool:

@Component
public class OrderTools {

    private final OrderRepository orderRepository;

    public OrderTools(OrderRepository orderRepository) {
        this.orderRepository = orderRepository;
    }

    @McpTool(
        name = "query_orders",
        description = "根据用户ID和状态筛选查询订单列表"
    )
    public List<Order> queryOrders(
            @McpToolParam(description = "用户ID", required = true) Long userId,
            @McpToolParam(description = "订单状态:pending/shipped/completed", required = false) String status) {

        if (status != null && !status.isEmpty()) {
            return orderRepository.findByUserIdAndStatus(userId, status);
        }
        return orderRepository.findByUserId(userId);
    }

    @McpTool(
        name = "get_order_detail",
        description = "查询单个订单的详细信息"
    )
    public Order getOrderDetail(
            @McpToolParam(description = "订单ID", required = true) Long orderId) {
        return orderRepository.findById(orderId)
                .orElseThrow(() -> new IllegalArgumentException("订单不存在: " + orderId));
    }

    @McpTool(
        name = "get_order_stats",
        description = "统计某个时间范围内的订单数据",
        annotations = @McpTool.McpAnnotations(readOnlyHint = true, idempotentHint = true)
    )
    public OrderStats getOrderStats(
            @McpToolParam(description = "开始日期 (yyyy-MM-dd)", required = true) String startDate,
            @McpToolParam(description = "结束日期 (yyyy-MM-dd)", required = true) String endDate) {

        LocalDate start = LocalDate.parse(startDate);
        LocalDate end = LocalDate.parse(endDate);
        return orderRepository.statByDateRange(start, end);
    }
}

💡 关键点@McpTool 注解的方法会被自动扫描并注册到 MCP Server。参数上的 @McpToolParam 会自动生成 JSON Schema。readOnlyHint = true 告诉 AI 这是一个只读操作,不会修改数据。

5.4 实体和 Repository

@Entity
@Table(name = "orders")
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private Long userId;
    private String orderNo;
    private BigDecimal amount;
    private String status;      // pending, shipped, completed
    private LocalDate createDate;

    // getters & setters 省略
}

public interface OrderRepository extends JpaRepository<Order, Long> {
    List<Order> findByUserId(Long userId);
    List<Order> findByUserIdAndStatus(Long userId, String status);

    @Query("SELECT new OrderStats(count(o), sum(o.amount)) " +
           "FROM Order o WHERE o.createDate BETWEEN :start AND :end")
    OrderStats statByDateRange(@Param("start") LocalDate start, @Param("end") LocalDate end);
}

5.5 配置文件

根据不同传输模式选择对应的配置:

Stdio 模式(配合 spring-ai-starter-mcp-server

# application.yml
spring:
  application:
    name: mcp-order-server

  ai:
    mcp:
      server:
        stdio: true        # 启用 Stdio 传输
        name: order-service
        version: 1.0.0

  datasource:
    url: jdbc:h2:mem:orderdb
    driver-class-name: org.h2.Driver

  jpa:
    hibernate:
      ddl-auto: create-drop
    show-sql: false

Streamable HTTP 模式(配合 spring-ai-starter-mcp-server-webmvc + spring-boot-starter-web

# application.yml
spring:
  application:
    name: mcp-order-server

  ai:
    mcp:
      server:
        stdio: false
        protocol: STREAMABLE   # 使用 Streamable HTTP 协议
        name: order-service
        version: 1.0.0

  datasource:
    url: jdbc:h2:mem:orderdb
    driver-class-name: org.h2.Driver

  jpa:
    hibernate:
      ddl-auto: create-drop
    show-sql: false

server:
  port: 8080

💡 选择建议:本地开发调试用 Stdio 模式(零依赖、零网络开销);需要远程访问或被多个 AI 客户端调用时用 Streamable HTTP 模式。

5.6 启动类

@SpringBootApplication
public class McpOrderServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(McpOrderServerApplication.class, args);
    }
}

5.7 测试你的 MCP Server

测试方法一:MCP Inspector(推荐)

MCP Inspector 是官方提供的可视化调试工具:

npx @modelcontextprotocol/inspector \
  --transport stdio \
  --command "java -jar target/mcp-order-server.jar"

然后在浏览器中打开 Inspector 界面,你可以:

  • 查看 Server 发现的能力列表
  • 调用 tools/list 查看所有工具
  • 传入参数调用 query_orders 查看返回结果
  • 模拟 AI Agent 的完整交互流程

测试方法二:低层级 MCP Client

如果想用 Java SDK 直接测试:

@Component
public class McpServerTester implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        // 使用 MCP Java SDK 创建同步 Client 连接本地 Stdio Server
        var stdioParams = ServerParameters.builder("java")
                .args("-jar", "target/mcp-order-server.jar")
                .build();

        var transport = new StdioClientTransport(stdioParams, McpJsonDefaults.getMapper());

        try (var client = McpClient.sync(transport)
                .requestTimeout(Duration.ofSeconds(10))
                .build()) {

            // 初始化连接(协议版本协商 + 能力发现)
            client.initialize();

            // 发现工具
            var tools = client.listTools();
            System.out.println("发现 " + tools.tools().size() + " 个工具:");
            tools.tools().forEach(t ->
                System.out.println("  - " + t.name() + ": " + t.description()));

            // 调用工具(使用 builder 模式)
            var result = client.callTool(CallToolRequest.builder("query_orders")
                    .arguments(Map.of("userId", 1001))
                    .build());
            System.out.println("查询结果: " + result);
        }
    }
}

5.8 验证 Server 启动

启动 Spring Boot 应用后,Stdio 模式的 Server 会通过标准输入/输出与 Client 通信;Streamable HTTP 模式的 Server 会在 http://localhost:8080/mcp 暴露端点。

你可以用 curl 简单验证 Streamable HTTP Server 是否在线:

curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"server/discover","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28"}}}'

六、实战二:MCP Client 消费远程 Server

在生产环境中,你的应用通常是 MCP Client——消费其他团队或第三方提供的 MCP Server。

6.1 添加依赖

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-client</artifactId>
</dependency>

6.2 配置连接

连接远程 Streamable HTTP Server:

spring:
  ai:
    mcp:
      client:
        enabled: true
        type: SYNC
        request-timeout: 30s
        streamable-http:
          connections:
            order-service:
              url: http://localhost:8080
              endpoint: /mcp
            payment-service:
              url: http://payment-service:8081
              endpoint: /mcp

6.3 在代码中使用

@Service
public class OrderAssistantService {

    private final SyncMcpToolCallbackProvider toolCallbackProvider;
    private final ChatClient chatClient;

    public OrderAssistantService(
            SyncMcpToolCallbackProvider toolCallbackProvider,
            ChatClient.Builder chatClientBuilder) {

        this.toolCallbackProvider = toolCallbackProvider;

        // 将 MCP Tools 注册为 AI 模型可用的工具
        this.chatClient = chatClientBuilder
                .defaultTools(toolCallbackProvider.getToolCallbacks())
                .build();
    }

    public String ask(String userMessage) {
        return chatClient.prompt()
                .user(userMessage)
                .call()
                .content();
    }
}

当用户说"帮我查一下用户 1001 的订单",Spring AI 会自动:

  1. 将自然语言匹配到 query_orders 工具
  2. 提取参数 userId = 1001
  3. 通过 MCP Client 调用远程 Server
  4. 将结果返回给 LLM 生成回答

你可以同时连接多个 MCP Server,Spring AI 会自动合并所有工具。通过 toolFilter 可以按 Server 名称筛选。


七、传输层选型:Stdio vs Streamable HTTP 怎么选?

7.1 对比表格

维度 Stdio Streamable HTTP
通信方式 标准输入/输出管道 HTTP POST + SSE
网络开销 无(进程间) 有(HTTP 往返)
部署复杂度 低(本地进程) 中(需 HTTP 服务)
进程管理 需管理子进程生命周期 无状态,水平扩展
认证 不适用 OAuth 2.0 / Bearer Token
负载均衡 不支持 支持(标准 HTTP LB)
适用环境 本地开发、单机部署 生产环境、微服务集群
并发连接 通常 1:1 1:N(一个 Server 服务多个 Client)

7.2 选型建议

场景 推荐传输 理由
开发调试 Stdio 零配置,启动即用
Claude Code 本地工具 Stdio 官方推荐模式
企业内部 AI 平台 Streamable HTTP 多消费者、需认证
对外暴露业务能力 Streamable HTTP 安全控制、运维监控
容器化部署 Streamable HTTP 标准 K8s 服务治理

7.3 混用策略

很多团队采用"开发用 Stdio,生产用 Streamable HTTP"的策略。注意这需要切换 starter 依赖,而非仅改配置:

开发环境(pom.xml + application-dev.yml)

<!-- pom.xml: Stdio 模式 -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-server</artifactId>
</dependency>
# application-dev.yml
spring:
  ai:
    mcp:
      server:
        stdio: true

生产环境(pom.xml + application-prod.yml)

<!-- pom.xml: Streamable HTTP 模式 -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
# application-prod.yml
spring:
  ai:
    mcp:
      server:
        stdio: false
        protocol: STREAMABLE
server:
  port: 8080

💡 最省心的做法:直接用 Stdio 做本地开发,生产部署时换 starter 和配置。两个 starter 不冲突,可以同时存在于依赖中,通过 profile 控制激活哪个配置。


八、MCP 的安全模型

8.1 传输安全

传输方式 安全机制
Stdio 本地进程隔离,依赖操作系统权限
Streamable HTTP OAuth 2.0 / Bearer Token / API Key

对于远程 MCP Server,推荐使用 OAuth 2.0 获取凭证,然后通过 Bearer Token 认证每个请求:

spring:
  ai:
    mcp:
      client:
        streamable-http:
          connections:
            secure-service:
              url: https://internal.company.com/mcp
              headers:
                Authorization: "Bearer ${MCP_AUTH_TOKEN}"

8.2 授权控制

Spring AI 2.0 的 MCP Server 支持通过 TransportContextExtractor 获取请求上下文(如 HTTP Header),然后在 Tool 内部做授权判断:

@Component
public class SecureOrderTools {

    @McpTool(name = "query_orders", description = "查询订单(需要授权)")
    public List<Order> queryOrders(
            McpSyncRequestContext requestContext,
            @McpToolParam(description = "用户ID") Long userId) {

        // 从请求上下文中提取认证信息
        McpTransportContext ctx = requestContext.transportContext();
        String token = (String) ctx.get("authorization");

        // 简单的 RBAC 校验
        if (!hasPermission(token, "order:read")) {
            throw new SecurityException("无订单查询权限");
        }

        return orderRepository.findByUserId(userId);
    }
}

在 Server 端配置 TransportContextExtractor 来提取 HTTP 请求头中的认证信息:

@Bean
public WebMvcStreamableServerTransportProvider transportProvider() {
    return WebMvcStreamableServerTransportProvider.builder()
        .contextExtractor(serverRequest -> {
            String auth = serverRequest.headers().firstHeader("Authorization");
            return McpTransportContext.create(Map.of("authorization", auth));
        })
        .build();
}

8.3 最佳实践

  • 最小权限原则:每个 MCP Server 只暴露必要的数据和操作
  • 只读属性标记:利用 readOnlyHint = true 让 AI 知道哪些工具不会修改数据
  • 敏感数据隔离:涉及 PII 或商业敏感数据的工具需要额外的认证层
  • 审计日志:所有工具调用记录日志,便于追踪和排查

九、MCP vs Function Calling vs Agent API——一张表说清楚

很多读者会问:MCP 和 OpenAI Function Calling 有什么区别?有了 MCP 还要写 Agent 吗?

9.1 核心区别

维度 MCP Function Calling Agent API
定位 开放协议标准 模型厂商 API 特性 厂商级 Agent 框架
厂商绑定 无(开放协议) 强绑定(每个厂商不同) 强绑定
工具注册 静态配置 + 动态发现 每次请求传 JSON Schema 平台侧注册
传输方式 Stdio / HTTP 可切换 仅 API 调用 仅平台 API
服务端实现 任意语言(有 SDK) 不需要(纯客户端) 平台托管
跨模型兼容 ✅ 完全兼容 ❌ 不兼容 ❌ 不兼容
社区生态 MCP Registry(公开市场) 厂商应用商店
适合谁用 工具/数据提供方 AI 应用消费者 第三方开发者

9.2 什么时候用什么?

你的角色是...
├── 工具/服务提供方(暴露 API 给 AI 消费)
│   └── ✅ MCP Server(一次开发,所有 AI 平台可用)
├── AI 应用开发者(在自己的 App 里集成 AI)
│   ├── 只用单一模型 → Function Calling 够用
│   └── 多模型或开放生态 → ✅ MCP Client
└── AI 平台方(做大模型应用平台)
    └── ✅ 同时支持 MCP 和自家 Agent API

9.3 MCP 不取代 Agent 框架

MCP 解决的是 工具与 AI 的连接标准化,不解决 Agent 的编排逻辑:

  • MCP = 基础设施层(连接标准)
  • Agent 框架 = 编排层(决策、规划、记忆)
  • 两者互补,不是替代关系

你可以用 Spring AI 的 ChatClient + MCP Tools 构建 Agent,也可以用 LangChain4j + MCP,甚至手写 Agent 逻辑。


十、2026 年 MCP 生态全景

10.1 支持 MCP 的客户端(Host)

客户端 类型 MCP 支持情况
Claude Code AI 编程助手 原生支持,经验最丰富
Claude Desktop AI 桌面应用 原生支持
ChatGPT AI 对话 全面支持 MCP Server 连接
VS Code Copilot IDE 插件 支持配置 MCP Server
Cursor AI 编辑器 支持 MCP
MCPJam MCP 专用客户端 全功能支持
Visual Studio IDE 2026 年新增支持

10.2 官方 SDK 矩阵

截至 2026 年 7 月,MCP 官方 SDK 分为三个 Tier:

Tier SDK 维护方 完备度
Tier 1 TypeScript, Python, C#, Go 官方核心团队 全功能
Tier 2 Java, Rust 社区合作 核心功能完备
Tier 3 Swift, Ruby, PHP, Kotlin 社区维护 基础功能

Java SDK 虽然是 Tier 2,但由 Spring AI 团队(Christian Tzolov 等)主力维护,与 Spring Boot 深度集成,生产可用度非常高。Server 端 40/40 全量通过官方一致性测试,Client 端 9/10 通过。

10.3 MCP Registry

2026 年,MCP Registry 已经发展为一个公开的 MCP Server 市场,类似于 Docker Hub 之于容器:

  • 发布你的 MCP Server 供他人消费
  • 发现社区已有的工具(数据库连接器、云服务工具等)
  • 版本管理和兼容性追踪

十一、从架构师视角看 MCP 的定位

作为 Java 后端架构师,如何看待 MCP 在系统中的位置?

11.1 MCP 在微服务架构中的角色

                    ┌─────────────┐
                    │  AI Agent   │
                    │  (Host)     │
                    └──────┬──────┘
                           │
              ┌────────────┼────────────┐
              │            │            │
        ┌─────▼────┐ ┌────▼───┐ ┌─────▼────┐
        │  MCP     │ │  MCP   │ │  MCP     │
        │  Client  │ │ Client │ │  Client  │
        └────┬─────┘ └───┬────┘ └────┬─────┘
             │           │           │
        ┌────▼───┐ ┌────▼───┐ ┌─────▼────┐
        │ 订单    │ │ 支付   │ │  用户    │
        │ MCP    │ │ MCP    │ │  MCP     │
        │ Server │ │ Server │ │  Server  │
        └───┬────┘ └───┬────┘ └────┬─────┘
            │          │           │
        ┌───▼────┐ ┌──▼────┐ ┌───▼─────┐
        │ 订单   │ │ 支付  │ │ 用户    │
        │ 微服务  │ │ 微服务│ │ 微服务  │
        └────────┘ └───────┘ └─────────┘

关键设计思想:MCP Server 可以作为微服务的"AI 网关层",每个领域微服务暴露出专属的 MCP Server,AI Agent 通过 MCP Client 按需发现和调用。

11.2 演进路径

第一阶段:单体 MCP Server
├── 一个 Spring Boot 应用
├── 暴露当前系统所有 MCP Tool
└── 适合小团队快速验证

第二阶段:领域 MCP Server 集群
├── 每个领域一个独立的 MCP Server
├── 订单领域、支付领域、用户领域
├── 各自独立部署和扩展
└── 适合中大型团队

第三阶段:MCP Mesh
├── MCP Server 注册到 Registry
├── 服务网格级别的 MCP Gateway
├── 统一的认证、限流、监控
└── 适合企业级 AI 平台

11.3 架构决策清单

如果要在你的项目中引入 MCP,建议回答这几个问题:

  1. 哪些系统能力需要暴露给 AI?(不要全部暴露,从小做起)
  2. 谁可以调用这些能力?(权限模型)
  3. 用 Stdio 还是 Streamable HTTP?(开发 vs 生产)
  4. MCP Server 的部署密度?(一个服务一个 Server?还是合并?)
  5. 如何与现有的认证体系集成?(OAuth 2.0?内部 SSO?)

十二、避坑指南(来自实际踩坑)

坑 1:JSON-RPC 版本不匹配

MCP 每个请求都携带协议版本。如果 Client 和 Server 的协议版本不兼容,握手会失败。

解决:确保双方使用相同版本的 SDK。Java SDK 2.0.0 对应协议版本 2026-07-28

坑 2:Tool 命名冲突

多个 MCP Server 暴露同名 Tool(如 query_orders),Client 端不知道调用哪个。

解决:使用 toolNamePrefix 为每个 Server 的工具名加前缀:

spring:
  ai:
    mcp:
      client:
        streamable-http:
          connections:
            order-service:
              url: http://localhost:8080/mcp
              tool-name-prefix: "order_"   # 工具名变为 order_query_orders
            payment-service:
              url: http://localhost:8081/mcp
              tool-name-prefix: "payment_"

坑 3:长耗时 Tool 的 Timeout

某些 Tool(如数据分析、报表生成)可能执行超过 30 秒,触发 Client 超时。

解决

  • 配置合理的 request-timeout
  • 对长任务使用异步模式,先返回 taskId,再轮询结果
  • 考虑使用 MCP 的 Progress Tracking 机制

坑 4:Windows 上 Stdio 无法启动

Windows 上 npxnpm 等是 .cmd 批处理文件,不是原生可执行文件。Java 的 ProcessBuilder 无法直接执行。

解决:用 cmd.exe /c 包装:

{
  "mcpServers": {
    "filesystem": {
      "command": "cmd.exe",
      "args": ["/c", "npx", "-y", "@modelcontextprotocol/server-filesystem", "."]
    }
  }
}

坑 5:Stdio Server 进程管理

Stdio 模式下,Client 直接启动 Server 子进程。如果 Client 异常退出,子进程可能变成僵尸进程。

解决:实现 shutdown hook 优雅清理:

@PreDestroy
public void cleanup() {
    // 关闭 MCP Client 时自动关闭关联的 Stdio 子进程
    mcpClient.close();
}

Spring AI Client Starter 默认已经处理了生命周期管理,但自己手写 Client 时要注意。

坑 6:过度暴露

新手最容易犯的错误:把所有数据库表都暴露为 MCP Tool,包括敏感字段。

解决

  • 每个 Tool 只在返回值中包含必要的字段
  • @McpToolParamdescription 不要暴露实现细节
  • 敏感操作必须走额外的授权层

十三、总结与行动清单

13.1 核心结论

  1. MCP 是 2026 年 AI Agent 基础设施层的核心协议,类似于 HTTP 之于 Web、USB-C 之于外设
  2. 它不是替代 Function Calling,而是更上层的标准化——跨模型、跨平台、跨语言
  3. Java 生态已经准备就绪——Spring AI 2.0 + MCP Java SDK 2.0 提供了生产级支持
  4. 对于后端开发者,MCP 是"把自己系统的能力开放给 AI"的标准方式

13.2 三步上手指南

第 1 步:理解协议(30 分钟)
├── 阅读本文第四节的三大原语
├── 理解 discovery → list → call 的交互流程
└── 打开 MCP Inspector 看一个真实 Server 的响应

第 2 步:跑通 Demo(2 小时)
├── 用 Spring Initializr 创建项目
├── 写一个 @McpTool 注解的方法
├── 用 MCP Inspector 测试
└── 让 Claude Code / ChatGPT 连上来调用

第 3 步:接入生产(2 天)
├── 选择传输方式(推荐 Streamable HTTP)
├── 配置认证和授权
├── 部署到测试环境
└── 用实际业务场景验证

13.3 参考资料

资源 地址
MCP 官方网站 https://modelcontextprotocol.io
MCP Java SDK https://github.com/modelcontextprotocol/java-sdk
Spring AI MCP 文档 https://docs.spring.io/spring-ai/reference/api/mcp/mcp-overview.html
MCP 规范 https://modelcontextprotocol.io/specification/latest
MCP Registry https://registry.modelcontextprotocol.io
Spring Initializr https://start.spring.io

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐