Codex MCP 服务器集成实战指南:用 MCP 协议扩展 AI 编程助手的边界

引言

Codex 作为 OpenAI 开源的终端 AI 编程助手,本身已经具备了强大的代码读写、Shell 命令执行、文件操作等能力。但当面对外部 API 调用、数据库查询、第三方平台交互等场景时,仅靠内置工具就显得捉襟见肘了。万幸的是,Codex 深度集成了 MCP(Model Context Protocol) 协议,通过配置 MCP 服务器,你可以让 Codex 获得任意自定义工具能力——从操作 Notion、查询数据库,到调用企业内部 API,一切都可以通过 MCP 服务器无缝衔接到你的工作流中。

本文将带你从零开始,掌握在 Codex 中使用 MCP 服务器的全部技能。

MCP 协议简介

MCP(Model Context Protocol)是由 Anthropic 开源的一种标准化协议,用于在 AI 模型和外部工具/数据源之间建立通信。一个 MCP 服务器可以暴露一组 Tools(工具)、Resources(资源)和 Resource Templates(资源模板),AI 模型可以按需调用这些能力。

在 Codex 的上下文中,MCP 服务器被视作"工具提供商"——Codex 在启动和运行时连接配置好的 MCP 服务器,将其提供的 Tools 注册到模型上下文中,并能够通过标准的 Function Call 机制调用它们。

核心架构:Codex 如何管理 MCP 连接

Codex 的 MCP 子系统(位于 codex-rs/codex-mcp 目录下)是一套完整的 MCP 客户端运行时,包含以下几个关键模块:

| 模块 | 功能 |
|------|------|
| connection_manager | 管理与多个 MCP 服务器的并发连接、重连、超时处理 |
| catalog | MCP 服务器注册表,负责发现、解析和去重服务器配置 |
| runtime | MCP 运行时,封装单次会话级别的连接生命周期 |
| binding | 将 MCP 工具绑定到 OpenAI Responses API 的 function call 格式 |
| elicitation | 处理 MCP 服务器发起的交互请求(如用户确认) |
| auth_elicitation | 处理 OAuth 和 ChatGPT 认证流程 |

当 Codex 启动一个会话时,它会:

解析 config.toml 中的 mcp_servers 配置

根据服务器类型(stdio / HTTP)建立连接

初始化 MCP 会话,获取服务器的 Tools 列表

将工具名称转换为 mcp__<server>__<tool> 格式注册到模型

配置 MCP 服务器

基础配置格式

config.toml 中通过 [mcp_servers] 小节定义你的 MCP 服务器:

[mcp_servers.postgres]
command = "npx"
args = ["-y", "@anthropic/mcp-server-postgres"]
env = { DATABASE_URL = "postgresql://user:pass@localhost:5432/mydb" }

[mcp_servers.notion]
url = "https://mcp.notion.com/api/mcp"
auth = "oauth"

两种传输类型

Codex 支持两种 MCP 传输方式,根据场景选择:

#### 1. Stdio 传输(子进程模式)

Codex 启动一个子进程,通过标准输入/输出与 MCP 服务器通信。适用于本地命令行工具类服务器。

[mcp_servers.github]
command = "npx"
args = ["-y", "@anthropic/mcp-server-github"]
cwd = "/home/user/projects"
env = { GITHUB_TOKEN = "ghp_xxxxx" }
startup_timeout_sec = 30
tool_timeout_sec = 60

关键字段说明:

  • command:要执行的命令(会在 PATH 中查找,也可用绝对路径)
  • args:命令参数列表
  • cwd:子进程的工作目录
  • env:注入的环境变量(键值对格式)
  • env_vars:更精细的环境变量控制,支持 { name = "VAR_NAME", source = "local" } 格式
  • startup_timeout_sec:启动超时,默认 30 秒
  • tool_timeout_sec:单个工具调用超时

#### 2. Streamable HTTP 传输(远程模式)

Codex 通过 HTTP 连接到远端 MCP 服务器。适用于部署在远程的 MCP 服务。

[mcp_servers.enterprise_api]
url = "https://api.mycompany.com/mcp"
http_headers = { "X-API-Version" = "2025-01" }
bearer_token_env_var = "ENTERPRISE_API_TOKEN"
auth = "oauth"
startup_timeout_sec = 15

关键字段说明:

  • url:MCP 服务器的 HTTP 端点地址
  • http_headers:额外的自定义请求头
  • bearer_token_env_var:从环境变量中读取 Bearer Token 的变量名
  • auth:认证方式,"oauth""chatgpt"
  • env_http_headers:通过环境变量值注入的请求头

认证配置

Codex 的 MCP 支持三种认证方式:

# 1. Bearer Token 认证(最简单)
[mcp_servers.api_with_token]
url = "https://api.example.com/mcp"
bearer_token_env_var = "MY_API_TOKEN"

# 2. OAuth 认证(适合第三方服务)
[mcp_servers.third_party]
url = "https://mcp.third-party.com/api"
auth = "oauth"
oauth = { client_id = "my-registered-client-id" }
scopes = ["read", "write"]

# 3. ChatGPT 认证(OpenAI 第一方服务)
# 仅适用于 chatgpt.com 域下的 MCP 服务,由 Codex App 功能自动提供
[mcp_servers.codex_apps]
url = "https://chatgpt.com/backend-api/ps/mcp"
auth = "chatgpt"

认证优先级:Bearer Token > HTTP Headers > OAuth > 未认证连接

工具级别控制

你可以精确控制每个 MCP 服务器中哪些工具可用、如何审批:

[mcp_servers.database]
command = "python"
args = ["-m", "my_mcp_server"]
# 启用/禁用整个服务器
enabled = true
# 对整个服务器的工具使用"写入需要审批"的模式
default_tools_approval_mode = "writes"
# 只允许特定工具
enabled_tools = ["query", "list_tables"]
# 显式禁止特定工具
disabled_tools = ["drop_table", "truncate"]
# 对特定工具设置独立审批策略
[mcp_servers.database.tools.drop_table]
approval_mode = "prompt"   # 始终弹出确认
[mcp_servers.database.tools.query]
approval_mode = "auto"     # 自动通过(只读查询)

审批模式说明:

  • auto:自动通过,无需用户干预
  • prompt:始终弹出确认对话框
  • writes:只在有写操作时弹出确认
  • approve:预先批准模式(管理员配置)

实践案例

案例一:接入 GitHub MCP 服务器

以下配置让 Codex 能直接操作 GitHub Issues、PR、仓库等:

[mcp_servers.github]
command = "npx"
args = ["-y", "@anthropic/mcp-server-github"]
cwd = "/home/user/projects"
env = { GITHUB_TOKEN = "ghp_your_personal_access_token" }
startup_timeout_sec = 30
tool_timeout_sec = 60
# GitHub 工具可能有写操作,使用 writes 模式
default_tools_approval_mode = "writes"

配置后,你可以在 Codex 中这样说:
> "帮我在 myorg/myproject 仓库中创建一个 Issue,标题是'升级 Node.js 依赖'"

Codex 将调用 mcp__github__create_issue 工具完成操作。

案例二:接入本地 SQLite 数据库

使用 uvx 启动官方 SQLite MCP 服务器:

[mcp_servers.sqlite]
command = "uvx"
args = ["mcp-server-sqlite", "--db-path", "/path/to/database.db"]
tool_timeout_sec = 30
default_tools_approval_mode = "auto"

配置后,Codex 可以直接执行 SQL 查询:
> "查询 employees 表中所有部门为 'Engineering' 的员工姓名和入职日期"

案例三:接入企业内部 REST API

你可以自己开发一个 MCP 服务器来封装企业内部 API。一个最小的 Python MCP 服务器示例:

# my_api_mcp_server.py
import json
import sys
import requests
from mcp.server import Server, StdioServerTransport
from mcp.types import Tool, TextContent

API_BASE = "https://api.internal.company.com/v1"
API_KEY = "your-api-key"

app = Server("internal-api")

@app.list_tools()
async def list_tools():
    return [
        Tool(
            name="get_user_info",
            description="获取用户基本信息",
            inputSchema={
                "type": "object",
                "properties": {
                    "user_id": {"type": "string", "description": "用户ID"}
                },
                "required": ["user_id"]
            }
        ),
        Tool(
            name="search_products",
            description="搜索产品信息",
            inputSchema={
                "type": "object",
                "properties": {
                    "keyword": {"type": "string", "description": "搜索关键词"},
                    "page": {"type": "integer", "default": 1}
                },
                "required": ["keyword"]
            }
        )
    ]

@app.call_tool()
async def call_tool(name: str, arguments: dict):
    if name == "get_user_info":
        resp = requests.get(
            f"{API_BASE}/users/{arguments['user_id']}",
            headers={"Authorization": f"Bearer {API_KEY}"}
        )
        return TextContent(type="text", text=json.dumps(resp.json(), ensure_ascii=False))
    elif name == "search_products":
        resp = requests.get(
            f"{API_BASE}/products/search",
            params={"q": arguments["keyword"], "page": arguments.get("page", 1)},
            headers={"Authorization": f"Bearer {API_KEY}"}
        )
        return TextContent(type="text", text=json.dumps(resp.json(), ensure_ascii=False))

if __name__ == "__main__":
    transport = StdioServerTransport()
    asyncio.run(app.run(transport))

config.toml 中配置:

[mcp_servers.internal_api]
command = "python"
args = ["/path/to/my_api_mcp_server.py"]
env = { INTERNAL_API_KEY = "sk-xxxxx" }
default_tools_approval_mode = "prompt"

高级特性

插件 MCP 服务器

Codex 插件可以声明自己的 MCP 服务器配置。当用户安装并启用一个插件后,插件清单中的 mcpServers 定义会自动加入 Codex 的 MCP 服务器目录:

// 插件 manifest.json 中
{
  "mcpServers": {
    "my_plugin_tools": {
      "command": "node",
      "args": ["./mcp-server/index.js"],
      "type": "stdio"
    }
  }
}

用户可以通过 [plugin_mcp_servers.my_plugin_tools] 覆盖插件的 MCP 服务器策略设置(如启用/禁用、审批模式等),但传输配置(command、args 等)归插件所有。

MCP 资源读取

除了 Tools,MCP 服务器还可以暴露 Resources——结构化的只读数据。Codex 可以通过 /mcp resources 命令列出和读取 MCP 资源:

/mcp resources list
/mcp resources read <server> <uri>

这允许你为 AI 提供静态参考数据,如 API 文档、配置模板、Schema 定义等。

Codex Apps MCP(内置)

Codex 内置了一个名为 codex_apps 的第一方 MCP 服务器,连接到 OpenAI 的 ChatGPT 后端。它由 apps_enabled 配置项控制,并需要有效的 ChatGPT 登录态。该服务器提供了如 Web 搜索、OpenAI 内部工具等能力。

你可以通过以下配置来控制它:

[mcp_servers.codex_apps]
enabled = true
default_tools_approval_mode = "prompt"

MCP 工具名称空间

默认情况下,MCP 工具在模型上下文中以 mcp__<server_name>__<tool_name> 格式出现(例如 mcp__github__create_issue)。这个 mcp__ 前缀有助于模型区分 MCP 工具和内置工具。

如果你不希望某些服务器的工具带前缀,可以配置:

[features.non_prefixed_mcp_tool_names]
enabled = true
servers = ["my_local_db"]

远程执行与沙箱

当 Codex 运行在远程执行模式(如通过 App Server/Exec Server)时,MCP 服务器可以在远程环境中启动。对于 stdio 类型的 MCP 服务器,Codex 会自动处理 cwd 的远程路径映射和环境变量绑定。

此外,MCP 工具调用也可以受 Codex 的沙箱策略约束,确保即使 MCP 服务器本身不受限,其工具调用的效果仍在合理的安全边界内。

调试与故障排除

查看 MCP 服务器状态

使用 /mcp servers 命令查看已连接服务器及其工具列表:

/mcp servers

输出示例:

┌──────────────────────┬──────────┬─────────┬──────────────────┐
│ Server               │ Status   │ Tools   │ Auth             │
├──────────────────────┼──────────┼─────────┼──────────────────┤
│ github               │ ✅ 连接  │ 12      │ Authenticated    │
│ sqlite               │ ✅ 连接  │ 3       │ None             │
│ enterprise_api       │ ❌ 超时  │ —       │ —                │
└──────────────────────┴──────────┴─────────┴──────────────────┘

诊断连接问题

如果 MCP 服务器无法连接,尝试以下步骤:

检查命令行:手动运行 command + args,确保命令能正常启动

```bash
npx -y @anthropic/mcp-server-github
```

验证环境变量:确保 env 中的变量值正确且可访问

```bash
echo $GITHUB_TOKEN # Linux/macOS
```

增加启动超时:某些 MCP 服务器首次启动可能需要更多时间

```toml
startup_timeout_sec = 60
```

检查日志:Codex 的日志(一般在 ~/.codex/logs/)中包含 MCP 连接的详细错误信息

常见配置错误

| 错误 | 原因 | 解决 |
|------|------|------|
| command not found | command 不在 PATH 中 | 使用绝对路径或确保命令已安装 |
| Connection refused | URL 错误或远程服务未启动 | 检查 URL 格式和服务器状态 |
| Authentication failed | Token 无效或过期 | 刷新 Bearer Token 或重新 OAuth |
| Tool timed out | 工具执行超时 | 增加 tool_timeout_sec |

总结

MCP 服务器是 Codex 扩展能力的核心机制。通过配置 MCP 服务器,你可以让 Codex 无缝接入 GitHub、数据库、第三方 API 等任意外部系统,真正实现"一个终端,搞定一切"的开发体验。

核心要点回顾:

  • Stdio 模式适合本地命令行类 MCP 服务器;HTTP 模式适合远程服务
  • 三种认证方式:Bearer Token、OAuth、ChatGPT Session
  • 工具级别审批控制,灵活平衡自动化与安全
  • 插件可声明自己的 MCP 服务器,自动集成
  • 通过 /mcp servers 命令查看连接状态

配置好 MCP 之后,试试对你刚刚接入的数据库 MCP 服务器说一句"帮我查一下今天有多少活跃用户",你会感受到 AI 编程助手的能力边界确实被大幅拓宽了。