深入理解 MCP 协议:AI 时代的工具集成标准

1 阅读6分钟

深入理解 MCP 协议:AI 时代的工具集成标准

导读:MCP(Model Context Protocol)正在成为 AI 应用集成的"通用语言"。本文深入讲解 MCP 协议的核心架构、消息格式和能力协商机制,配合 Java SDK 代码示例,帮助你从原理层面掌握这一新兴标准。这是 MCP 系列文章的第二篇。


系列回顾

在上一篇文章 《Spring AI MCP 实战:手把手构建 Todo Manager 应用》 中,我们通过一个完整案例了解了如何使用 Spring AI MCP 开发应用。

本文作为系列的第二篇,将深入讲解 MCP 协议本身,帮助你从原理层面理解这一新兴标准。Java SDK 代码仅作为示例使用。


一、MCP 简介

1.1 什么是 MCP

**Model Context Protocol(MCP)**是一个开放的协议标准,用于定义 AI 模型与外部工具、资源之间的交互方式。

简单来说,MCP 想让 AI 模型能够像人类一样"使用工具"—— 只不过人类用鼠标点击,AI 通过协议调用。

1.2 为什么需要 MCP

在 AI 应用开发中,我们面临以下挑战:

挑战描述
工具集成碎片化每个工具都有自己的 API 格式
缺乏统一标准不同 AI 框架使用不同的集成方式
互操作性差跨语言、跨平台调用复杂

MCP 的目标就是解决这些问题。

1.3 MCP 的设计目标

┌─────────────────────────────────────────────┐
│            MCP 设计目标                      │
├─────────────┬─────────────┬─────────────────┤
│   标准化    │  互操作性   │    可扩展      │
│  统一接口   │  跨语言平台  │  按需添加能力  │
│  规范       │  无缝通信   │  灵活扩展      │
└─────────────┴─────────────┴─────────────────┘

1.4 适用场景

场景说明示例
AI 工具集成让 AI 调用外部 API天气查询、数据库操作
资源访问AI 读取外部数据源文件、文档、知识库
提示模板预定义的 Prompt 模板代码审查、文档生成

1.5 与相关技术对比

技术定位与 MCP 的关系
REST API通用 HTTP APIMCP 可基于 HTTP 传输
gRPCRPC 框架不同的抽象层次
OpenAPIAPI 文档规范MCP 包含类似的能力描述

二、核心架构

2.1 Client/Server 模型

MCP 采用经典的客户端 - 服务器架构:

┌─────────────────┐         ┌─────────────────┐
│   MCP Client    │         │   MCP Server    │
│  (请求发起方)    │◄───────►│  (能力提供方)    │
└─────────────────┘  JSON-RPC └─────────────────┘

角色说明

角色职责典型实现
Client发起请求、消费能力AI 应用、Agent 框架
Server暴露能力、响应请求工具服务、数据源

2.2 传输层

MCP 支持多种传输方式:

STDIO 传输
┌──────────┐         ┌──────────┐
│  Client  │ ──stdin─►│  Server  │
│          │ ◄─stdout─│          │
└──────────┘         └──────────┘
  • 基于标准输入/输出
  • 适用于本地进程间通信
  • 无需网络端口
HTTP SSE 传输
┌──────────┐         ┌──────────┐
│  Client  │ ──HTTP─►│  Server  │
│          │ ◄──SSE──│          │
└──────────┘         └──────────┘
  • Server-Sent Events 单向推送
  • 适用于远程服务
  • 需要 HTTP 端口
Streamable HTTP 传输(推荐)
┌──────────┐         ┌──────────┐
│  Client  │ ◄──────►│  Server  │
│          │  双向流  │          │
└──────────┘         └──────────┘
  • 双向流式通信
  • 高效、低延迟
  • 支持连接恢复

2.3 JSON-RPC 消息格式

MCP 基于 JSON-RPC 2.0 规范定义消息格式。

请求消息
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list",
  "params": {}
}
响应消息
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": [...]
  }
}
错误响应
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32600,
    "message": "无效请求"
  }
}

三、服务器能力

MCP 服务器可以暴露以下几种能力:

3.1 Tools(工具)

Tools 是服务器暴露给客户端的可调用功能。

工具发现

客户端请求工具列表:

// 请求
{
  "method": "tools/list",
  "params": {}
}

// 响应
{
  "tools": [
    {
      "name": "create_todo",
      "description": "创建一个新的待办事项",
      "inputSchema": {
        "type": "object",
        "properties": {
          "title": {"type": "string", "description": "待办标题"},
          "description": {"type": "string", "description": "待办描述"}
        },
        "required": ["title"]
      }
    }
  ]
}
工具调用
// 请求
{
  "method": "tools/call",
  "params": {
    "name": "create_todo",
    "arguments": {
      "title": "学习 MCP",
      "description": "阅读协议文档"
    }
  }
}

// 响应
{
  "content": [
    {
      "type": "text",
      "text": "✓ 待办已创建\n  ID: 550e8400-e29b-41d4-a716-446655440000"
    }
  ]
}
Java SDK 示例
// Server 端注册工具
@Bean
public McpServerFeatures.SyncToolSpecification createTodoTool() {
    return SyncToolSpecification.builder()
        .tool(McpSchema.Tool.builder()
            .name("create_todo")
            .description("创建待办事项")
            .inputSchema(...) // JSON Schema 定义
            .build())
        .callHandler((exchange, request) -> {
            // 处理工具调用
            return McpSchema.CallToolResult.builder()...;
        })
        .build();
}

3.2 Resources(资源)

Resources 是服务器暴露的数据源,通过 URI 访问。

资源发现
// 请求
{"method": "resources/list"}

// 响应
{
  "resources": [
    {
      "uri": "todo://all",
      "name": "所有待办",
      "mimeType": "application/json"
    }
  ]
}
资源读取
// 请求
{
  "method": "resources/read",
  "params": {"uri": "todo://all"}
}

// 响应
{
  "contents": [
    {
      "uri": "todo://all",
      "text": "[{\"id\":\"1\",\"title\":\"学习 MCP\"}]"
    }
  ]
}
资源订阅
// 订阅
{
  "method": "resources/subscribe",
  "params": {"uri": "todo://all"}
}

// 变更通知(服务器主动推送)
{
  "method": "notifications/resources/updated",
  "params": {"uri": "todo://all"}
}

3.3 Prompts(提示模板)

Prompts 是预定义的提示词模板。

// 获取 Prompt
{
  "method": "prompts/get",
  "params": {
    "name": "code_review",
    "arguments": {"language": "java"}
  }
}

// 响应
{
  "messages": [
    {
      "role": "user",
      "content": {
        "type": "text",
        "text": "请审查以下 Java 代码..."
      }
    }
  ]
}

3.4 其他能力

能力说明
Completions自动补全,类似 IDE 的智能提示
Logging结构化日志,便于调试和监控

四、客户端能力

MCP 客户端也可以向服务器提供能力:

4.1 Roots(根目录)

Roots 定义服务器可访问的文件系统边界。

// 获取 Roots
{"method": "roots/list"}

// 响应
{
  "roots": [
    {"uri": "file:///project/src", "name": "源代码"}
  ]
}

4.2 Sampling(LLM 采样)

客户端提供 LLM 生成能力给服务器使用:

{
  "method": "sampling/createMessage",
  "params": {
    "messages": [...],
    "maxTokens": 100,
    "modelPreferences": {"hints": ["claude-sonnet"]}
  }
}

4.3 Elicitation(用户输入)

服务器通过客户端请求用户输入:

{
  "method": "elicitation/create",
  "params": {
    "message": "请选择操作类型",
    "requestedSchema": {
      "type": "object",
      "properties": {
        "action": {"type": "string", "enum": ["create", "update", "delete"]}
      }
    }
  }
}

五、消息协议详解

5.1 初始化握手

MCP 连接建立需要完成握手流程:

Client                          Server
  │                              │
  │──── initialize ────────────►│
  │                              │
  │◄───── initialize ───────────│
  │                              │
  │──── initialized ───────────►│
  │                              │
  │         连接建立完成          │

initialize 请求示例

{
  "method": "initialize",
  "params": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "roots": {"listChanged": true}
    },
    "clientInfo": {
      "name": "mcp-client",
      "version": "1.0.0"
    }
  }
}

5.2 能力协商

客户端和服务器在初始化时交换各自支持的能力:

// 服务器能力
{
  "capabilities": {
    "tools": {"listChanged": true},
    "resources": {"subscribe": true, "listChanged": true},
    "prompts": {}
  }
}

5.3 错误处理

标准 JSON-RPC 错误码:

错误码含义
-32700解析错误
-32600无效请求
-32601方法不存在
-32602参数无效
-32603内部错误

六、Java SDK 快速上手

6.1 添加依赖

<dependency>
    <groupId>io.modelcontextprotocol.sdk</groupId>
    <artifactId>mcp</artifactId>
    <version>1.0.0</version>
</dependency>

6.2 创建客户端

// 创建传输层
McpAsyncTransport transport = new WebFluxSseClientTransport(
    "http://localhost:8080"
);

// 创建客户端
McpSyncClient client = McpClient.sync(transport).build();

// 初始化握手
client.initialize();

// 列出工具
var tools = client.listTools();

// 调用工具
var result = client.callTool(
    new CallToolRequest("create_todo",
        Map.of("title", "学习 MCP"))
);

6.3 创建服务端

// 创建传输层
WebFluxSseServerTransportProvider transport =
    new WebFluxSseServerTransportProvider();

// 创建服务端
McpSyncServer server = McpServer.sync(transport).build();

// 注册工具
server.addTool(toolSpec);

总结

本文系统讲解了 MCP 协议的核心内容:

  1. 架构设计:Client/Server 模型 + 多种传输方式
  2. 消息格式:基于 JSON-RPC 2.0
  3. 服务器能力:Tools、Resources、Prompts
  4. 客户端能力:Roots、Sampling、Elicitation
  5. 握手协商:initialize 流程 + 能力交换

MCP 作为 AI 应用集成的新标准,其设计思想值得深入学习。掌握 MCP 协议,有助于我们更好地理解 AI Agent 生态的发展趋势。


系列导航


参考资料


作者:[你的名字] 关注我:获取更多 Spring AI 和 MCP 相关内容 欢迎点赞👍 收藏⭐ 评论💬