07 · 如何让 Codex 调用工具和访问数据
任务:"给我看下 Stripe 的最新 API,按它写一个支付接入"。
⏱️ 预计阅读 13 分钟 | 🎯 目标:把 Codex 从"只会读项目文件"变成"能用工具去外部世界查、做、验证"
上一篇讲 4 个入口怎么选。这一篇讲 Codex 在每个入口里能调用哪些工具 —— 文件系统、shell、浏览器、外部 API、数据库……都通过同一套机制接进来:MCP(Model Context Protocol,模型上下文协议)。
🎬 没有工具的 Codex 能干什么?
任务:"给我看下 Stripe 的最新 API,按它写一个支付接入"。
| 没有工具 | 有工具 |
|---|---|
| Codex 凭训练数据回忆 Stripe API(可能已过时) | 通过 MCP 连 Stripe 文档,实时读最新 API |
| 写完代码不能跑 | 通过 shell 工具跑测试 + 看实际响应 |
| 改完页面不知道效果 | 通过浏览器工具真的打开页面截图验证 |
| 数据库结构靠你贴出来 | 通过 MCP 连数据库,自己 SELECT 看结构 |
💡 工具决定 Codex 能触达的世界有多大。 没工具 = 它只能在自己脑子里写代码;有工具 = 它能像你一样跑测试、查文档、点页面、读数据库。
🧱 Codex 工具栈:4 层能力
按"接的是什么"分四层:
flowchart TB
subgraph L1["1️⃣ 内置基础层 —— Codex 自带"]
File[📁 文件读写]
Shell[🖥️ Shell 命令]
Search[🔎 代码搜索]
end
subgraph L2["2️⃣ 浏览器层 —— App / IDE 内置"]
Browser[🌐 内置浏览器<br/>开页面、点击、截图]
end
subgraph L3["3️⃣ MCP 层 —— 接外部工具的标准协议"]
Stripe[💳 Stripe MCP]
GitHub[🐙 GitHub MCP]
DB[🗄️ Database MCP]
Figma[🎨 Figma MCP]
end
subgraph L4["4️⃣ Skills 层 —— 把多步流程打包成一个动作"]
Skill1[🔧 PR Review Skill]
Skill2[📝 文档生成 Skill]
end
L1 --> L2 --> L3 --> L4 --> Codex[🤖 Codex 调度]
style L1 fill:#dcfce7,stroke:#22c55e
style L2 fill:#dbeafe,stroke:#3b82f6
style L3 fill:#fef3c7,stroke:#f59e0b
style L4 fill:#f3e8ff,stroke:#a855f7
| 层 | 是什么 | 解决的问题 |
|---|---|---|
| 1️⃣ 内置基础层 | 文件读写、shell 命令、代码搜索 | Codex 在你项目里"动手"的最低能力 |
| 2️⃣ 浏览器层 | App / IDE 内置浏览器 | UI 验收、复现 bug、看页面渲染 |
| 3️⃣ MCP 层 | 对接外部系统的标准协议 | 接 Stripe / GitHub / 数据库 / Figma / 任意第三方 |
| 4️⃣ Skills 层 | 多步流程打包 | "PR review" 这种重复 5+ 步的工作流,做成一键 |
🎯 加工具不是"装得越多越好":先把 1-2 层用熟(默认就在),再按真实需求往 3-4 层加。
🔌 MCP 是什么?为什么它最重要
MCP(Model Context Protocol)= AI 工具的 USB 接口。
sequenceDiagram
participant Codex
participant MCP as 🔌 MCP 层
participant Stripe as 💳 Stripe MCP Server
participant API as 🌐 Stripe API
Codex->>MCP: 问 最新支付接入文档
MCP->>Stripe: 转发请求
Stripe->>API: 调真实 Stripe Docs API
API-->>Stripe: 返回最新文档
Stripe-->>MCP: 结构化响应
MCP-->>Codex: 你想要的最新文档
为什么不直接让 Codex 调 API?
| 直接调 API | 通过 MCP |
|---|---|
| ❌ 每个工具一种接法 | ✅ 一套协议接所有工具 |
| ❌ 凭据散落各处 | ✅ MCP 管认证(bearer token / 环境变量) |
| ❌ 接错版本要 Codex 自己处理 | ✅ MCP 服务端版本统一 |
| ❌ Codex / Cursor / Claude 各写一份 | ✅ 同一个 MCP server 跨 Agent 复用 |
MCP 服务器两种类型
| 类型 | 启动方式 | 适合 |
|---|---|---|
| 🖥️ STDIO | Codex 启动一个本地命令做子进程 | 私有数据 / 本地工具 / 文件系统访问 |
| 🌐 Streamable HTTP | 连一个 URL | 公共服务 / 团队共享 / 跨机器访问 |
配置在哪?
config.toml 里加 [mcp_servers.{名字}]:
# ~/.codex/config.toml (全局) 或 .codex/config.toml (项目级)
[mcp_servers.github]
type = "http"
url = "https://api.github.com/mcp"
bearer_token_env_var = "GITHUB_TOKEN" # 从环境变量读 token
[mcp_servers.local-db]
type = "stdio"
command = "uvx"
args = ["mcp-postgres", "--db-url", "postgres://localhost/mydb"]
startup_timeout_sec = 10 # 默认 10 秒
tool_timeout_sec = 60 # 默认 60 秒
enabled = true # 临时关掉就 false
required = false # true = 启动失败就报错💡 CLI 和 IDE 扩展共享同一份
config.toml—— 配一次两边都能用。
🎯 怎么挑一个 MCP 服务器?3 步法
第 1 步 · 看你的痛点
| 痛点 | 推荐 MCP |
|---|---|
| Codex 用过期 API 写错代码 | 📚 文档 MCP(接官方文档) |
| 老让你贴数据库结构 | 🗄️ Postgres / MySQL / SQLite MCP |
| 改 UI 看不到效果 | 🌐 Browser MCP / Playwright MCP |
| 团队代码评审重复劳动 | 🐙 GitHub MCP |
| 设计稿落地组件 | 🎨 Figma MCP |
第 2 步 · 看安全边界
flowchart TD
A["🤔 这个 MCP 要访问什么"]
A --> Q1{涉及生产数据吗}
Q1 -->|是| Read["✅ 用 read-only 凭据"]
Q1 -->|否| Q2{涉及钱 / 权限}
Q2 -->|是| Manual["🛑 不接 MCP 人工操作"]
Q2 -->|否| Free["✅ 可接"]
style Manual fill:#fee2e2,stroke:#ef4444
style Read fill:#fef3c7,stroke:#f59e0b
第 3 步 · 配最小权限
✅ 所有 token 走环境变量(bearer_token_env_var),不直接写 config.toml
✅ 数据库连 read-only 只读账号
✅ required = false:MCP 挂了别让 Codex 整个跑不起来
🌐 浏览器工具:让 Codex 真的"看"页面
典型场景:
- 🐛 复现 bug:让 Codex 自己点几下页面,截图说明 bug 长什么样
- ✅ UI 验收:改完组件后,让它去页面上看渲染对不对
- 📱 响应式检查:375px 看一遍 + 1440px 看一遍
- 🔑 登录态测试:用测试账号登入后跑场景
何时用浏览器工具,何时不用:
| 用 | 不用 |
|---|---|
| ✅ UI 改动需要视觉验收 | ❌ 纯逻辑 / 算法(跑测试就够) |
| ✅ 复现交互 bug | ❌ 后端 API 改动(用 curl / MCP) |
| ✅ 验证表单流程 | ❌ 改 README(不需要打开页面) |
🛠️ Shell 工具:让 Codex 跑命令
Codex 自带跑 shell 命令的能力(在 sandbox 里),这是最朴素也最强的工具。
典型用法:
让 Codex 跑:
- pnpm test 运行测试
- pnpm typecheck 类型检查
- pnpm build 构建
- git diff 看改动
- curl ... 调 API
- python script.py 跑脚本⚠️ 回顾上篇:shell 命令在 sandbox 里跑,受
workspace-write/network=off限制。要联网或动 workspace 外的文件,触发 approval。
📊 4 类工具的真实对比
| 类别 | 是什么 | 代表场景 | 配置位置 | 何时启用 |
|---|---|---|---|---|
| 📁 文件 + Shell | Codex 自带 | 读项目、跑测试、跑构建 | 无需配置 | 默认开 |
| 🌐 浏览器 | App / IDE 内置 | UI 验收、复现 bug | App / IDE 设置面板 | 需要时开 |
| 🔌 MCP 服务器 | 外部工具协议 | 接 Stripe / 数据库 / Figma | config.toml 里 [mcp_servers.X] | 按需逐个加 |
| 🛠️ Skills | 多步工作流打包 | PR review / 文档生成 | ~/.codex/skills/ 或 .agents/skills/ | 下篇详讲 |
🎯 判断口诀:默认靠文件 + Shell;UI 任务才开浏览器;接外部系统才上 MCP;流程重复 5+ 次才做 Skill。
🚫 常见误解 → ✅ 正确理解
| ❌ 误解 | ✅ 正解 |
|---|---|
| MCP 越多越强 | 每个 MCP 都吃上下文窗口;只接当前真用得上的 |
| MCP token 写 config.toml 里方便 | 必须走环境变量(bearer_token_env_var),明文 token 是事故源 |
| 所有 MCP 都开 read+write 权限 | 能 read-only 就 read-only;尤其生产数据库 |
| 浏览器工具适合所有任务 | 纯逻辑改动跑单测就够,开浏览器是浪费 |
| Codex 装了 MCP 就会自动用 | 它会按需选择;提示词里点名(用 GitHub MCP 查 PR)更稳 |
🔍 想再深一层(点击展开)
📋 完整 MCP 配置示例(含认证 / 超时 / 故障策略)
# ~/.codex/config.toml
# === 公共 HTTP MCP(GitHub)===
[mcp_servers.github]
type = "http"
url = "https://api.github.com/mcp"
bearer_token_env_var = "GITHUB_TOKEN"
http_headers = { "X-API-Version" = "2026-01-01" }
startup_timeout_sec = 15 # 慢网络下加大
tool_timeout_sec = 60
required = false # 挂了不影响 Codex 启动
# === 私有 STDIO MCP(本地数据库)===
[mcp_servers.prod-db]
type = "stdio"
command = "uvx"
args = ["mcp-postgres", "--db-url-env", "PROD_DB_URL"]
enabled = true
# === 临时禁用某个 MCP(不删配置)===
[mcp_servers.figma]
type = "http"
url = "..."
enabled = false # 暂时关📖 完整配置项参考:Configuration Reference
🎭 把 Codex 自己做成 MCP server
冷知识:Codex 本身可以作为 MCP server 嵌入其他 Agent。
典型场景:
你的主 Agent (Claude / Cursor / 别的)
↓ 通过 MCP 调
Codex (作为 MCP server)
↓ 干编程任务
返回结果这让 Codex 的编程能力可以嵌入任何支持 MCP 的 Agent 系统,做你架构里的"专门写代码的部门"。
启动方式:
codex mcp serve📖 来源:Codex MCP
🔐 工具调用的安全边界回顾
加工具会扩大 Codex 的影响半径。回顾第 5 篇的 sandbox + approval:
| 工具类型 | 风险 | 防御 |
|---|---|---|
| 📁 文件 | 写错文件 | sandbox workspace-write |
| 🖥️ Shell | 跑危险命令 | approval on-request |
| 🌐 浏览器 | 在 web 中遇到 prompt injection | 隔离上下文 / 缓存索引 |
| 🔌 MCP(HTTP) | 联网 / token 泄露 | 环境变量 + 域名白名单 |
| 🔌 MCP(STDIO) | 本地命令注入 | 只用可信的 MCP 包 |
核心原则:每加一个工具,都重新评估 sandbox / approval 策略。
📖 术语速查表
| 英文 / 缩写 | 中文 | 一句话解释 |
|---|---|---|
| MCP | 模型上下文协议 | Model Context Protocol,AI 接外部工具的标准 |
| STDIO server | 标准输入输出服务器 | 通过本地进程通信的 MCP server |
| Streamable HTTP | 流式 HTTP | 通过 HTTP 长连接通信的 MCP server |
| bearer_token_env_var | 鉴权令牌环境变量 | 从环境变量读 Bearer token,避免明文 |
| startup_timeout_sec | 启动超时秒数 | MCP server 起不来超过这个时间就放弃 |
| tool_timeout_sec | 工具调用超时 | 单次 MCP 调用的最长等待时间 |
| Skills | 技能 | 把多步流程打包成可复用动作(下篇详讲) |
| Plugin | 插件 | Skills 的可分发包装 |
apply_patch | 应用补丁 | Codex 改文件的内置工具 |
📖 官方文档来源:
📝 本章自检
| # | 问题 | 对应章节 | 自检 |
|---|---|---|---|
| 1 | Codex 工具栈 4 层是什么?为什么按这个顺序? | 🧱 4 层能力 | ☐ |
| 2 | MCP 两种服务器类型分别适合什么场景? | 🔌 MCP | ☐ |
| 3 | 接 MCP 时怎么放 token 才安全?为什么? | 🎯 3 步法 § 第 3 步 | ☐ |
✅ 过关标准:能用一句话说清 —— "工具决定 Codex 能触达的世界有多大;MCP 是接外部工具的标准接口。"
📚 下一篇
- ➡️ 08 · Skills、Subagents、Hooks 解决什么问题 —— 复用 / 分工 / 自动检查的边界
- 📖 接入 MCP 工具和上下文
- 🛠️ 让 Codex 能调用你的命令行工具
- 📊 用 Codex 查询表格数据
- 🌐 用内置浏览器验收页面
🧭 一句话记住
工具决定 Codex 能触达的世界有多大。MCP 是 AI 工具的 USB —— 一套协议接所有外部系统。