MCP

深入理解MCP技术原理(中)

MCP 数据层的标准化 什么是 JSON RPC 协议? 所有工具都必须用统一的格式描述自己——包括工具名、使用说明、参数结构、返回格式等。 这种描述不是随意写的,而是采用严格的 JSON 格式。智能体在连接 MCP Server …

TL;DR

MCP 数据层的标准化 什么是 JSON RPC 协议? 所有工具都必须用统一的格式描述自己——包括工具名、使用说明、参数结构、返回格式等。 这种描述不是随意写的,而是采用严格的 JSON 格式。智能体在连接 MCP Server …

MCP 数据层的标准化

什么是 JSON-RPC 协议?

所有工具都必须用统一的格式描述自己——包括工具名、使用说明、参数结构、返回格式等。 这种描述不是随意写的,而是采用严格的 JSON 格式。智能体在连接 MCP Server 的第一步,就是向其索要所有工具的说明书。这一步在 MCP 中被称为“初始化”,对应一次标准的 JSON-RPC 请求。智能体无需关心工具是谁写的,也无需去理解其内部逻辑,只需要根据“说明书”就能让大模型进行决策判断,并最终发起调用。另外,工具的执行返回也遵循同样的标准格式,因此智能体无需适配不同工具的返回值,也不需要写任何特殊逻辑。 只要按标准写了工具说明书,任何工具就能被任何智能体直接使用,不需要额外的集成成本。 JSON-RPC 就是两个服务之间通过发送 JSON 数据来进行沟通的一种“通用语言”。 - RPC (Remote Procedure Call):就是指远程过程调用。它的核心思想是:我在 A 服务上调用一个函数(比如 getWeather()),但实际上这个函数是在 B 服务上运行的,B 把结果运行完再传回给 A。 - JSON:所有的数据传输都使用最通用的 JSON 格式,这意味着无论你的智能体是用什么编程语言写的,大家都能看懂对方发来的信息,而且这样的请求是非常简洁高效的。 - 无状态 (Stateless):每一次请求都是独立的,就像寄信一样,寄出去一封,收回来一封,协议本身不记忆之前的状态。 相比于复杂的 RESTful API(需要关心 HTTP 方法、URL 路径、Header),JSON-RPC 极其简单粗暴:只关心“需要调用的方法名”和“参数”。这与大模型调用工具的逻辑完美契合。 MCP 中的每一次请求,本质上都是在交换JSON-RPC 2.0 标准的数据包。我们来看一下它的结构是什么样的。 请求体:

{
  "jsonrpc": "2.0",          // 1. 版本号:必须是 "2.0"
  "method": "tools/call",    // 2. 方法名:需要执行的操作
  "params": {                // 3. 参数:执行操作需要的数据
    "name": "get_weather",   // 4. 调用的函数名
    "arguments": {
      "city": "Beijing"      // 5. 函数入参
    }
  },
  "id": 1                    // 6. ID:请求的编号号,用于匹配回信
}

响应体:

{
  "jsonrpc": "2.0",
  "result": {                // 1. 结果:成功时的返回数据
    "content": [
      {
        "type": "text",
        "text": "北京今天晴,气温 25 度"
      }
    ]
  },
  "id": 1                    // 2. ID:对应请求的 ID
}

错误结构:

{
  "jsonrpc": "2.0",
  "error": {                 // 错误对象
    "code": -32601,          // 标准错误码
    "message": "Method not found" // 错误信息
  },
  "id": 1
}

MCP 如何利用 JSON-RPC 工作?

在 MCP 架构中,JSON-RPC 并不是简单的数据传输工具,而是整个工具调用、状态管理和决策执行的核心标准语言。MCP 将智能体(MCP Host)、客户端(MCP Client)和工具服务(MCP Server)的交互完全规范化,使得每一次调用都遵循相同的流程。

初始化阶段:建立连接与能力协商

当 MCP Host(智能体应用)启动时,MCP Client 会向 MCP Server 发起 JSON-RPC 请求,进行初始化。 - 能力协商:客户端和服务端会确认协议版本、功能支持等信息。 - 准备就绪通知:初始化完成后,客户端会发送 notifications/initialized 告知服务器自己已准备好。 - 意义:这一阶段保证双方在同一协议下通信,建立通信基础,为后续工具发现和调用做好准备。 示例请求:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "roots": {
        "listChanged": true
      },
      "sampling": {},
      "elicitation": {}
    },
    "clientInfo": {
      "name": "ExampleClient",
      "title": "Example Client Display Name",
      "version": "1.0.0"
    }
  }
}

初始化成功后,客户端必须发送initialized通知,表明其已准备好开始正常运行: 如果没有这步,服务端会认为客户端并未准备好,所以将禁止后续的其他操作。

{
  "jsonrpc": "2.0",
  "method": "notifications/initialized"
}

工具发现阶段:获取工具说明书

初始化完成后,客户端需要知道服务器上“有哪些工具”可以使用。 - 标准化描述:每个工具都以 JSON 格式描述方法名、参数类型、返回格式和使用说明。 - 无需理解内部逻辑:智能体只需知道工具能做什么、需要哪些参数、返回什么结果,无需关心内部实现。 - 动态发现:工具可能随时变化,每次获取的都是最新工具列表。 MCP Server 对外暴露三类核心能力: - Resources(资源):可供客户端直接读取的外部数据,如文件内容、API 返回结果等。 - Tools(工具):具体执行的工具服务。(核心能力) - Prompts(提示):预定义的提示词模板。 示例请求:

{
  "jsonrpc": "2.0",
  "method": "tools/list",
  "params": {},
  "id": 100
}

响应返回所有工具的说明信息。智能体在拿到这些说明后,就可以利用大模型构建调用策略和决策逻辑。

调用阶段:执行具体工具

当智能体通过大模型决策需要调用某个工具(如 get_weather)时,通过 MCP Client 构建标准 JSON-RPC 请求发送给 MCP Server:

{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": {
      "city": "Beijing"
    }
  },
  "id": 101
}

服务器收到请求后: - 解析工具名和参数:根据 name 找到对应工具执行。 - 执行工具:独立运行工具逻辑,无需 Host 参与内部过程。 - 返回结果:按照 JSON-RPC 的 result 或 error 返回数据。 智能体接收到返回值后,可以直接处理输出、组合多个工具结果,或者继续做下一步决策。整个流程完全无需针对每个工具写不同的适配逻辑。

工具变更阶段:处理工具列表更新

在运行过程中,服务器上的工具可能会发生变更(新增、下线或修改)。MCP 支持客户端实时获知变更: - 变更通知:服务端通过 notifications/tools/list_changed 通知客户端工具列表已更新。 - 重新获取列表:客户端收到通知后会重新请求 tools/list,更新内部工具注册表。 - 保证一致性:智能体始终知道最新的可用工具,实现动态适应和高可扩展性。 示例通知:

{
  "jsonrpc": "2.0",
  "method": "notifications/tools/list_changed",
  "params": {}
}

MCP 通过 JSON-RPC 的各阶段的调用,从而实现了工具的数据层的标准化、模块化和动态扩展能力。

版本提示

模型、框架与接口会持续变化。涉及版本号、参数与生产配置时,请在实践前对照对应官方文档。

LLMentor系统化学习大模型应用工程

内容来自个人课程知识库备份,并经过结构化整理。技术版本持续演进,生产使用前请结合官方文档验证。