JSON-RPC 2.0、Codex、MCP Client 和 MCP Server 是什么关系?以调用 GitHub 工具为例

当我们使用 Codex 时,可以直接告诉它:"帮我查看 GitHub 上 openai/codex 仓库的 README.md,总结这个项目是做什么的。"

Codex 本身是一个 AI 编程助手,但它为什么能够访问 GitHub?它是否直接调用 GitHub API?MCP Client 和 MCP Server 分别在哪里?JSON-RPC 2.0 又起什么作用?

本文从几个概念入手,最后用 Codex 调用 GitHub MCP Server 的 get_file_contents 工具串起完整流程。

Codex 作为 MCP Host 管理 MCP Client;Client 按 MCP 协议与 Server 通信;Server 提供工具并连接 GitHub 等外部系统;MCP 的消息建立在 JSON-RPC 2.0 之上。

1. 什么是 JSON-RPC 2.0?

JSON-RPC 2.0 是一种基于 JSON 的远程过程调用协议(Remote Procedure Call)。简单来说,调用方不需要知道另一端函数的内部实现,只需要按照约定发送一条 JSON 请求,就能让对方执行某个方法,并拿到结果。

例如,一次抽象的加法远程调用:

json 复制代码
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "add",
  "params": {"a": 10, "b": 20}
}

对方执行完成后返回:

json 复制代码
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": 30
}

其中,jsonrpc 声明协议版本;method 表示调用什么方法;params 携带参数;id 将一次请求与它的响应关联起来;成功响应中使用 result,失败时则使用 error。id 只是本次 JSON-RPC 请求的关联标识,不是 GitHub Issue ID,也不是业务用户 ID。

另外,如果消息没有 id,它在 JSON-RPC 中通常属于通知(Notification),接收方不需要返回响应。MCP 也利用通知进行协议生命周期管理。

特别注意:JSON-RPC 定义的是消息格式与调用约定,并不规定只能通过 HTTP 发送。 它可以搭配不同传输方式。

2. 什么是 MCP?它和 JSON-RPC 2.0 有什么关系?

MCP(Model Context Protocol,模型上下文协议) 是让 AI 应用与外部工具、数据及上下文能力交互的一套开放协议。

可以把它理解成在 JSON-RPC 之上规定了一套适用于 AI 应用的标准操作,例如:

  • initialize:建立会话,协商协议版本和能力。
  • tools/list:获取 Server 暴露的工具列表。
  • tools/call:调用指定工具。
  • resources/list、resources/read:发现、读取服务端提供的资源(如果支持)。
  • prompts/list、prompts/get:发现、获取服务端提供的提示词模板(如果支持)。

两者的区别是:JSON-RPC 2.0 解决"消息怎么表达";MCP 进一步解决"AI 应用和工具服务器具体按什么规则交互"。

例如 tools/call 不是 JSON-RPC 2.0 标准自带的方法,而是 MCP 定义的方法;它用 JSON-RPC 2.0 消息格式传输。

目前主要有两种传输方式:stdio 和 Streamable HTTP。

第九节会介绍

3. MCP Server 是不是一个工具的统一入口?

可以这样理解,但它的能力不止 Tools。

一个 MCP Server 可以提供多个 Tool ,也可以按需提供 Resources 和 Prompts。以 GitHub MCP Server 为例,它可能提供读取文件、搜索仓库、查看 PR、管理 Issue 等不同工具。并不需要每一个 GitHub API 功能都单独运行一个 MCP Server。

需要区分两个层次:

  • MCP Server:负责暴露一组符合 MCP 规范的能力,处理协议消息。
  • 具体 Tool :MCP Server 内的某一个可被调用的功能,例如 get_file_contents。

因此,一个 GitHub MCP Server 可以同时拥有 get_file_contents、list_pull_requests、issue_write 等工具。但某个连接实际能看到哪些工具,还取决于 Server 的版本、启用的 toolsets、访问权限和只读模式等配置。

4. Codex Host、MCP Client、MCP Server 到底是什么关系?

这是理解 MCP 架构最关键的一步。

Codex Host 指的是承载 Agent 工作流程的 Codex 主应用或运行环境,而不是大模型本身。它负责与用户交互、组织模型请求、管理工具、处理安全与权限,并创建 MCP Client 连接外部 Server。

MCP Client 是 Host 内用于与某个 Server 建立连接、交换协议消息的客户端组件。它负责初始化、列出工具、发起工具调用、接收结果等协议工作。

MCP Server 则在另一端实现工具、资源等能力。以 GitHub 为例,它接收 Client 的 tools/call,在具备权限时调用 GitHub API,再把结果返回给 Client。

第一,一个 Host 可以管理多个 MCP Client。 Codex 可以同时接入 GitHub、Filesystem 等多个 MCP Server。

第二,一个 MCP Client 实例通常与一个特定 MCP Server 建立一对一连接。 并不是Codex 整个程序只注册一个 Client,然后由它连接所有 Server。

text 复制代码
Codex Host
├── MCP Client ① ── GitHub MCP Server
│                       ├── get_file_contents
│                       ├── list_pull_requests
│                       └── issue_write
│
└── MCP Client ② ── Filesystem MCP Server
                        ├── read_file
                        └── list_directory

这里的一对一说的是MCP Client 实例到特定 Server 的逻辑连接/会话关系,不是说一个 MCP Server 只能服务一个用户,也不是说 Codex 只能连接一个 Server。

5. Codex 为什么称为 Host,而不是 MCP Client?

因为 Codex 做的事情比协议通信多得多。

用户发起任务以后,Codex 要协调 LLM 的推理与工具使用、决定是否允许某个操作、维护对话上下文、处理结果,再形成最终回答。这些都是 Host 的职责。

而 MCP Client 只负责其中一段:通过 MCP 协议与外部 Server 通信。

因此,说Codex 是 MCP Client只能粗略表达Codex 支持连接 MCP,技术上更准确的说法是:

Codex 是 MCP Host,它在内部创建或管理 MCP Client,通过这些 Client 连接不同 MCP Server。

6. 实例:让 Codex 读取 GitHub 仓库的 README

接下来假设用户对 Codex 说:

帮我读取 GitHub 上 openai/codex 仓库的 README.md,然后总结项目主要功能。

这里我们选择 GitHub MCP Server 实际提供的 get_file_contents 工具。它接受 owner、repo、path 等参数。以下是解释调用原理的示意流程,不代表本文真的执行了这次 GitHub 读取。

6.1 首先,Codex 需要连接并初始化 MCP Server

Codex Host 根据配置创建 GitHub MCP Client。客户端与服务端首先协商版本和能力,典型会话包括 initialize 请求及响应,之后客户端发送 notifications/initialized 通知。

简化流程:

text 复制代码
Codex Host 创建 GitHub MCP Client
               ↓
       连接 GitHub MCP Server
               ↓
             initialize
               ↓
       协商协议版本、能力
               ↓
       notifications/initialized

所以,并不是一启动就直接调用 GitHub 的 get_file_contents;一般要先建立可用的 MCP 会话。

6.2 然后,通过 tools/list 发现工具

GitHub MCP Client 发送:

json 复制代码
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list",
  "params": {}
}

Server 会返回当前允许使用的工具清单。下面只是一个删减后的示例:

json 复制代码
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": [
      {
        "name": "get_file_contents",
        "description": "Get file or directory contents",
        "inputSchema": {
          "type": "object",
          "properties": {
            "owner": {"type": "string"},
            "repo": {"type": "string"},
            "path": {"type": "string"}
          },
          "required": ["owner", "repo"]
        }
      }
    ]
  }
}

这里的 inputSchema 通常使用 JSON Schema 描述参数。Codex 就能知道:这个工具叫 get_file_contents,调用它需要什么参数,以及它大概能做什么。

6.3 LLM 判断应该调用哪个工具

模型看到用户要求"读取 GitHub 仓库的 README",再结合工具描述,就可能决定使用 get_file_contents。

这里有一个非常容易混淆的点:不是大模型亲自向 GitHub MCP Server 发送 JSON-RPC。 模型在 Codex 的工具调用机制中表达"想使用哪个工具和参数",真正构造并发送 MCP 请求的是 Codex 的工具执行层和对应的 MCP Client。

6.4 MCP Client 通过 tools/call 发出请求

示例请求:

json 复制代码
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "get_file_contents",
    "arguments": {
      "owner": "openai",
      "repo": "codex",
      "path": "README.md"
    }
  }
}

最重要的是分清楚 method 和 name:

  • method: "tools/call" 表示正在执行 MCP 的"调用工具"操作。
  • params.name: "get_file_contents" 表示具体调用哪个 GitHub 工具。
  • arguments 是这个工具需要的业务参数。
  • id: 2 用于把该次请求与后面的 JSON-RPC 响应匹配。

所以 MCP 中的 tools/call 和 GitHub 工具名不是同一层的概念。

6.5 GitHub MCP Server 真正执行工具

GitHub MCP Server 收到请求后,会定位到 get_file_contents 对应的处理逻辑,检查参数与权限,在后台访问 GitHub API 获取仓库文件内容。

也就是说:

text 复制代码
Codex MCP Client
      ↓ MCP / JSON-RPC
GitHub MCP Server
      ↓ GitHub API
GitHub 平台

Codex 与 GitHub MCP Server 之间使用 MCP;GitHub MCP Server 与 GitHub 平台之间使用 GitHub 的 API。 这两段不是同一个协议层次。

6.6 结果返回 Codex,再由模型组织答案

成功响应可能像这样(text 内容只作示意):

json 复制代码
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "README.md 的文件内容......"
      }
    ],
    "isError": false
  }
}

MCP Client 接收响应,把工具结果交给 Codex Host。Host 再把必要的文件内容放入模型可使用的上下文中,让模型根据实际 README 内容生成中文总结。

至此才完成一个完整的:用户提问 → 模型选工具 → MCP 工具调用 → GitHub API → 工具结果 → 模型回答 的闭环。

7. MCP Client 为什么不是只有一个?

假设 Codex 还需要执行另一项任务:"读取本地项目配置,然后结合 GitHub 仓库代码给出修改建议。"

它可能同时需要:

  • GitHub MCP Client:连接 GitHub MCP Server,读取 GitHub 仓库。
  • Filesystem MCP Client:连接 Filesystem MCP Server,读取本地文件。

一个 Host 可以维护这些不同的 Client 连接,并把不同来源的结果汇总到同一个 Agent 任务中。但每个 Server 不会因为连进 Codex,就自动获得完整对话或其他 Server 的私有数据;Host 仍然需要负责权限与上下文隔离。

因此,应该记成 一个 Host → 多个 Client → 各自连接 Server,而不是 一个 Codex → 一个全局 Client → 所有 Server。

8. JSON-RPC、MCP、Function Calling 到底有什么区别?

这几个概念经常一起出现,但分工不同。

概念 主要解决什么问题 在这次例子中的作用
JSON-RPC 2.0 请求、响应、通知怎么表示 定义 jsonrpc/id/method/params/result
MCP AI 应用如何发现和调用外部能力 定义 initialize、tools/list、tools/call 等
MCP Client 与 Server 建立会话、收发协议消息 GitHub 专用连接组件
MCP Server 暴露工具,并完成实际工具处理 提供 get_file_contents 等工具
Codex Host 协调用户、模型、工具与权限 调度整个任务
Function/Tool Calling 模型向 Host 表达需要调用工具的意图 选择 get_file_contents 和参数

这里尤其要注意:模型产生的 Tool Calling 请求,和 MCP Client 发出的 JSON-RPC 请求,不一定是同一个 JSON 结构,也不是同一层协议。 Host 需要负责把模型层的工具调用意图转换成实际可执行的 MCP 调用。

9. JSON-RPC 等于 HTTP 吗?stdio 又是什么?

不等于。JSON-RPC 规定消息结构,MCP 则规定应用层交互与支持的传输方式。

MCP 常见传输方式包括:

stdio: Host 启动本地 MCP Server 子进程,通过标准输入/输出交换协议消息。适合本地开发工具、文件系统工具等。

Streamable HTTP: Client 通过 HTTP 与 MCP Server 通信,适合远程服务。例如 GitHub 托管的 MCP Server 可使用这种方式。

在这两种方式下,MCP 的 tools/list、tools/call 依然采用 JSON-RPC 消息结构,只是消息在底层怎样传输不同。

10. 如果不用 MCP,Codex 能不能直接调用 GitHub API?

技术上可以。只要 Host 自己集成了 GitHub API 客户端、身份认证和工具逻辑,就不一定非得通过 MCP。

MCP 的价值主要在于:把"外部服务提供什么工具、参数如何描述、调用结果怎么返回"等能力标准化。 这样,支持 MCP 的 Host 不必为每一个服务都重新设计一套工具接入协议。

但这不表示 MCP Server 是万能代理,更不意味着所有工具都会被自动开放给模型。权限控制、工具描述、错误处理和安全边界仍然非常重要。

11. 最容易混淆的六个问题

① Codex Host 是不是大模型? 不是。Host 是运行和协调 Agent 的应用层;LLM 是其中用于理解和决策的模型。

② Codex 里是不是只有一个 MCP Client? 不是。一个 Host 可以管理多个 Client 实例,通常每个 Client 对应一个 Server 连接。

③ 一个 MCP Server 是不是只能提供一个工具? 不是。一个 Server 可以同时提供多个 Tools,还可以提供 Resources、Prompts。

④ tools/call 是不是某个 GitHub 工具? 不是。tools/call 是 MCP 定义的通用调用方法;get_file_contents 才是这次调用的具体工具名。

⑤ 是不是大模型直接发送 JSON-RPC? 通常不是。模型提出工具调用意图,由 Host 和 MCP Client 负责执行协议通信。

⑥ MCP 是不是 JSON-RPC 的另一个名字? 不是。JSON-RPC 定义消息格式,MCP 在它之上提供 AI 工具发现、调用、资源访问和生命周期等规范。

总结

text 复制代码
用户:帮我读取 GitHub README
             ↓
        Codex Host
    (管理任务、LLM 与工具)
             ↓
       GitHub MCP Client
             ↓
    MCP / JSON-RPC 2.0
             ↓
       GitHub MCP Server
             ↓
      get_file_contents
             ↓
          GitHub API
             ↓
      GitHub README 文件
             ↓
  结果沿原路返回 → LLM 总结

一个 Codex Host 可以管理多个 MCP Client;一个 MCP Client 通常对应一个 MCP Server 连接;一个 MCP Server 可以提供多个 Tools。

JSON-RPC 2.0 是它们之间收发 MCP 消息时使用的基础格式,而 Codex 作为 Host 则负责把用户任务、LLM 决策与外部工具连接起来。


参考资料

相关推荐
面包狗AI4S3 小时前
【AI4S】生化环材高可信技术与产业周报(2026-10-03—2026-10-09)
人工智能·深度学习·机器学习·ai
刘科领3 小时前
使用ollama & openweb-ui 本地搭建自己的AI
人工智能·python·ui·ai
不开大的凯20773 小时前
AI权力游戏:同一天,两种答案,一场算力暗战
大数据·人工智能·ai·ai office
全栈练习生3 小时前
模型上下文协议(MCP)
python·ai
木圭的AI时代指南4 小时前
EmbeddingGemma 2 图片检索实测:3 款多模态向量模型在无显卡 Ubuntu 上的完整账本
ai·本地部署·向量模型·图片检索
xrlfreedom4 小时前
MCP 面试高频考点:用 Streamable HTTP 控制返回大小并降低上下文消耗
mcp·mcp client·typescript mcp sdk·streamable http 传输
EatFan4 小时前
2026 后端 AI 工程化:Spring AI 2.0、MCP 协议与 Agent 内嵌如何收进 Java 生产系统
java·人工智能·spring·agent·spring ai·spring boot 3·mcp
JPower_mr.g4 小时前
SmartCall 音色管理技术解析:基于 SPI 的可扩展音色注册架构
java·开发语言·人工智能·ai·架构·开源