内容
# Frenemy: Claude ↔ Codex
让 Claude 和 Codex 相互调用,这样你就不需要在它们之间复制/粘贴。
在 **Claude 和 ChatGPT 订阅**上运行。无需 API 密钥。
由 **Zakariya Syed** 创建:
[YouTube](https://youtube.com/@noblehacksacademy) ·
[LinkedIn](https://www.linkedin.com/in/zakariya-syed/) ·
[X](https://x.com/ZakariyaHacks) ·
[GitHub](https://github.com/noblehacks)
与 OpenAI 或 Anthropic 无关。MIT 许可(参见 LICENSE)。
两个方向在一个小文件中,无依赖。默认只读。文件编辑存放在一个单独的工具中,永远不会自动批准。
**先决条件:** `node`(18 或更新版本),`claude` CLI 和 `codex` CLI,均已安装,在 `PATH` 中,并已登录(分别运行 `claude` 和 `codex` 一次以登录)。
## 如何使用它
**在 Claude 聊天中**,Claude 调用 `codex exec`:
> “让 Codex 生成一个英雄图像并将其放在页面中。”
> “让 Codex 审查此差异。”
**在 Codex 聊天中**,Codex 调用 `ask_claude` 工具:
> “让 Claude 审查 app.py。”
> “让 Claude 重构此文件。”(使用 `ask_claude_write`,参见下面的批准说明)
就是这样。
## 实际安装的内容
| 组件 | 功能 |
|---|---|
| `ask-claude-mcp.mjs`(此文件夹) | Frenemy 本身。给予 Codex 两个工具:`ask_claude`(只读)和 `ask_claude_write`(可能编辑文件)。 |
| `install.sh` / `install.ps1`(此文件夹) | 一键安装程序(Mac/Linux 和 Windows)。它们为您配置线路。 |
| `codex` CLI(测试版本为 v0.144.1) | `codex exec` 是 Claude 驱动 Codex 的方式。 |
| `codex-plugin-cc`(可选) | OpenAI 官方的 Claude Code 插件:`/codex:review`,`/codex:transfer`,`/codex:rescue`。不包含在内。通过 Claude Code 的插件市场安装。 |
## 安装(一条命令)
将此文件夹放在一个永久位置,在里面打开一个终端,然后运行:
**Mac / Linux:**
```bash
bash install.sh
```
**Windows (PowerShell):**
```powershell
.\install.ps1
```
(如果 Windows 阻止脚本:`powershell -ExecutionPolicy Bypass -File install.ps1`)
无需 sudo/admin 权限。它只写入您主文件夹中的配置文件。它检查 `node`、`claude` 和 `codex` 是否已安装,连接双方的继电器,并(在 Mac/Linux 上)提供可选的图像脚本。安全运行两次。完成后,重启 Codex。
**安装后不要移动或删除此文件夹。** Codex 的配置指向它。
<details>
<summary>手动安装(如果您愿意手动操作,脚本会执行以下操作)</summary>
**1.** 将以下内容添加到 `~/.codex/config.toml`(替换两个路径:`which node` 打印第一个路径;第二个路径是您放置此文件夹的位置。两个路径都必须为绝对路径;在 Windows 上使用正斜杠)。两个块都是必需的;有关原因,请参见下面的“关键配置行”:
```toml
[mcp_servers.claude]
command = "/ABSOLUTE/PATH/TO/node"
args = ["/ABSOLUTE/PATH/TO/frenemy/ask-claude-mcp.mjs"]
tool_timeout_sec = 600
[mcp_servers.claude.tools.ask_claude]
approval_mode = "approve"
```
(`tool_timeout_sec = 600` 很重要:如果没有它,Codex 只给 MCP 工具一个很短的默认超时时间,Claude 的长答案会在客户端被截断。)
**2.** 将 `CLAUDE-codex-section.md`(在此文件夹中)的内容追加到您的 `~/.claude/CLAUDE.md` 中。这就是 Claude 学习如何安全调用 Codex 的方法。
**3. (可选,仅适用于图像生成;仅限 Mac/Linux)** 将 `genimg.sh` 复制到 `~/.claude/scripts/genimg.sh` 并使其可执行。它是一个一次性包装器,Claude 使用它可靠地生成图像(gpt-image-2),并带有正确的沙盒标志和引号。
</details>
## 烟雾测试:验证它在您的机器上是否有效
- Codex → Claude:在 Codex 聊天中,说“让 Claude 审查此存储库中的任何文件。”您应该在不亲自触摸 Claude 的情况下获得 Claude 的审查。
- Claude → Codex:在 Claude 聊天中,说“让 Codex 生成一个 512×512 蓝色圆圈 PNG 到此文件夹中。”图像应**直接出现在项目文件夹中**。
## 细则(点击任意行展开)
<details>
<summary><b>为什么使用自定义文件而不是 <code>claude mcp serve</code></b></summary>
明显的方法是 `codex mcp add claude -- claude mcp serve`,**这不是您想要的。** `claude mcp serve` 提供 Claude 的*原始工具*(读取、bash、代理)。没有“将此提示发送到 Claude 并获取答案”的操作, 需要许可的工具可能会停滞等待不会给予的批准。
`ask-claude-mcp.mjs` 通过公开由 `claude -p`(Claude 的无头模式)支持的普通工具来解决这个问题。`claude -p` 回答问题然后退出。它从不提示。
</details>
<details>
<summary><b>关键配置行(安装程序为您添加;如果您手动安装,请阅读此内容)</b></summary>
(不是秘密或 API 密钥,只是一行配置,整个过程都依赖于它。安装程序为您添加。)
无头 `codex exec` 自动拒绝 MCP 工具调用(`user cancelled MCP tool calls`),除非您设置了**每个工具**的批准模式。**全局**批准设置(`approval_policy=never`,`approval_policy={granular=...}`)**不**起作用。这让人们感到困惑,通常人们会想到一个“修复”方法,即 `--dangerously-bypass-approvals-and-sandbox`,这会丢弃沙盒。您不需要它。真正的答案是安装步骤 1 中添加的第二个块:
```toml
[mcp_servers.claude.tools.ask_claude]
approval_mode = "approve"
```
有了这一行,`codex exec` 可以在没有任何额外标志的情况下调用 Claude 读取内容。要准确说明这意味着什么:Codex 围绕*shell 命令*的沙盒保持完整,但中继本身在沙盒**外部**运行(这就是全部内容:沙盒命令无法访问 Claude 的登录)。自动批准 `ask_claude` 意味着您信任此工具在墙外运行。它被强制为只读并有上限,但这是一个真正的信任决定。
**故意不自动批准:** `ask_claude_write`(文件编辑变体)。在交互式 Codex 会话中,您将获得批准提示。 这就是目的。 自动批准一个可以编辑文件的工具意味着 Codex 读取的内容(网页、README)可以悄悄触发代码编辑。 只有您完全接受这种风险时,才为其添加批准模式。
</details>
<details>
<summary><b>安全性:什么被锁定</b></summary>
- Claude 在 MCP 服务器的启动工作目录(通常是 Codex 工作区)中运行。 工具调用者无法更改该目录。 (Claude 自己的文件权限规则决定了它可以读取哪些路径。)
- 只读**强制执行**:`ask_claude` 在 `--safe-mode`(禁用您的所有自定义:钩子、插件、MCP 服务器、CLAUDE.md、技能)下运行,同时禁用副作用工具(文件编辑、shell 和网络获取/搜索),即使您的设置允许它们。 子代理可用并继承相同的禁止。 编辑需要单独的、默认不批准的 `ask_claude_write` 工具。
- `ask_claude_write` 仅加载您的**用户级**设置(`--setting-sources user`)。 克隆存储库在其项目设置中附带的钩子、插件或 MCP 服务器将被忽略,因此随机存储库无法将其自己的自动化注入中继。
- 卡住的 `claude` 调用在 10 分钟后被终止;输出被限制在 ~2 MB;最多同时运行 4 个 Claude 调用。
- 提示通过 stdin 传递,而不是命令行参数,因此它们不会出现在进程列表中。
</details>
<details>
<summary><b>已知限制</b></summary>
- **Codex 编辑文件** 当给定 `--sandbox workspace-write` 时。 在一个分支上工作。
- **Codex → Claude 调用是单次且阻塞的。** 每个 `ask_claude` 或 `ask_claude_write` 调用都启动一个新的 Claude 会话,没有内存,没有流式传输,也没有进度输出。 没有后台作业句柄,也没有取消; Codex 获得一个最终答案, 调用卡住后 10 分钟后被终止。
- **Claude → Codex 是指令驱动的,而不是强制执行的边界。** `CLAUDE-codex-section.md` 教会 Claude 使用哪些 `codex exec` 标志,但没有任何东西强制执行它们。 Frenemy 适用于本地、单用户使用。 审查写入批准,不要将存储库内容或模型输出视为受信任的指令。
- **有限的递归保护。** `ask_claude` 在安全模式下运行,因此 Claude 甚至不知道 Codex 的存在,无法调用它。 但是 `ask_claude_write` 加载您的用户级配置(包括 CLAUDE.md Codex 部分),Claude→Codex→Claude 链可能会耗尽两个订阅的速率限制。 每个跳跃都受 10 分钟超时限制,但不要让它们玩乒乓球。
- **重新运行安装程序会跳过,而不是升级。** 如果您安装了此软件包的新版本,请删除旧的 `[mcp_servers.claude]` 块和旧的“# Codex 始终可用”部分,然后重新运行安装程序。 这也会获取配置改进(例如固定的绝对 `node` 路径),而跳过的运行会将其遗留下来。
- **Windows 需要原生 Claude 安装程序** (`claude.exe`)。 npm 安装的 `claude.cmd` 伪影不会启动。 这是故意的:通过 shell 启动会导致恶意存储库植入假的 `claude.cmd` 并劫持中继。
- **速率限制是共享的。** Codex CLI、IDE 窗格和 ChatGPT 网页都来自同一个滚动 5 小时 ChatGPT 限制。 委托很多会消耗您的正常使用量。
- **无视频。** Codex 生成图像(gpt-image-2),不是视频。 Sora 无法通过此方式访问。
- **推理努力不会改变图片太多。** 图像始终来自 gpt-image-2; 文本模型仅驱动工具。 降低努力会节省*其*成本,而不是图像成本, 并且图像不保证相同。
</details>
## 常见问题(点击问题获取答案)
<details>
<summary><b>Claude 让我运行 <code>/doctor</code> 或运行 <code>claude install</code>。 我该怎么办?</b></summary>
Claude Code 正在逐步淘汰 npm 安装程序。 运行 `claude install` 一次以切换到原生版本。 Frenemy 与 Mac/Linux 上的任一版本配合使用; Windows 需要原生版本。
</details>
<details>
<summary><b>图像脚本在 <code>--ephemeral</code> 上失败,或者 Codex 工具调用表现异常。 为什么?</b></summary>
您的 Codex CLI 版本太旧。 Frenemy 在 Codex 0.144 及更新版本上经过测试。 使用 `codex --version` 检查,使用 `npm install -g @openai/codex@latest` (或 `brew upgrade codex`)更新,然后重启 Codex。
</details>
<details>
<summary><b><code>npm install -g</code> 失败,权限被拒绝(EACCES)。 怎么办?</b></summary>
在许多机器上,npm 的全局文件夹归 root 所有。 重新运行相同的命令,并在前面加上 `sudo`(仅限于您信任的软件包;npm 安装脚本以 root 身份运行)。 为了以后不再需要 sudo,请使用 nvm 等版本管理器安装 Node。
</details>
<details>
<summary><b>图像生成(或任何 <code>codex exec</code> 运行)失败,出现“模型被拒绝”的错误,但交互式 Codex 工作正常。 为什么?</b></summary>
您的 `~/.codex/config.toml` 锁定了一个 OpenAI 已弃用的模型。 交互式 Codex 在 UI 中选择其模型,因此它不会注意到; `codex exec` 遵循过时的锁定并失败。 修复:从 `~/.codex/config.toml` 中删除 `model = ...` 行并重启 Codex。 没有锁定,Codex 使用其当前默认模型。 (如果安装程序看到锁定,会发出警告。)
</details>