<div align="center">
<h1>Codex Proxy</h1>
<h3>您的本地 Codex 编程助手中转站</h3>
<p>将 Codex Desktop 的能力以 OpenAI / Anthropic / Gemini 标准协议对外暴露,无缝接入任意 AI 客户端。</p>
<p>
<img src="https://img.shields.io/badge/Runtime-Node.js_18+-339933?style=flat-square&logo=nodedotjs&logoColor=white" alt="Node.js">
<img src="https://img.shields.io/badge/Language-TypeScript-3178C6?style=flat-square&logo=typescript&logoColor=white" alt="TypeScript">
<img src="https://img.shields.io/badge/Framework-Hono-E36002?style=flat-square" alt="Hono">
<img src="https://img.shields.io/badge/Docker-Supported-2496ED?style=flat-square&logo=docker&logoColor=white" alt="Docker">
<img src="https://img.shields.io/badge/Desktop-Win%20%7C%20Mac%20%7C%20Linux-8A2BE2?style=flat-square&logo=electron&logoColor=white" alt="Desktop">
<img src="https://img.shields.io/badge/License-Non--Commercial-red?style=flat-square" alt="License">
</p>
<p>
<a href="#-快速开始">快速开始</a> •
<a href="#-核心功能">核心功能</a> •
<a href="#-可用模型">可用模型</a> •
<a href="#-客户端接入">客户端接入</a> •
<a href="#-配置说明">配置说明</a> •
<a href="./API_CN.md">API 文档</a> •
<a href="#-贡献致谢">贡献致谢</a>
</p>
<p>
<strong>简体中文</strong> |
<a href="./README_TW.md">繁體中文 (台灣)</a> |
<a href="./README_HK.md">繁體中文 (香港)</a> |
<a href="./README_EN.md">English</a> |
<a href="./README_JA.md">日本語</a>
</p>
<br />
<a href="https://x.com/IceBearMiner"><img src="https://img.shields.io/badge/Follow-@IceBearMiner-000?style=flat-square&logo=x&logoColor=white" alt="X"></a>
<a href="https://github.com/icebear0828/codex-proxy/issues"><img src="https://img.shields.io/github/issues/icebear0828/codex-proxy?style=flat-square" alt="Issues"></a>
<a href="#-赞赏--交流"><img src="https://img.shields.io/badge/赞赏-微信-07C160?style=flat-square&logo=wechat&logoColor=white" alt="赞赏"></a>
<br><br>
<table>
<tr>
<td align="center">
<img src="./.github/assets/donate.png" width="180" alt="微信赞赏码"><br>
<sub>☕ 赞赏</sub>
</td>
<td align="center">
<img src="./.github/assets/tgimage.png" width="180" alt="Telegram 群"><br>
<sub>💬 Telegram</sub>
</td>
</tr>
</table>
</div>
---
---
**Codex Proxy** 是一个轻量级本地中转服务,将 [Codex Desktop](https://openai.com/codex) 的 Responses API 转换为多种标准协议接口(OpenAI `/v1/chat/completions`、Anthropic `/v1/messages`、Gemini、Codex `/v1/responses` 直通,以及可选 Ollama `/api/chat` 兼容桥接)。通过本项目,您可以在 Cursor、Claude Code、Continue、Pi 等任何兼容上述协议的客户端中直接使用 Codex 编程模型。
只需一个 ChatGPT 账号(或接入第三方 API 中转站),配合本代理即可在本地搭建一个专属的 AI 编程助手网关。
## 🚀 快速开始
> **前置条件**:你需要一个 ChatGPT 账号(免费账号即可)。如果还没有,先去 [chat.openai.com](https://chat.openai.com) 注册一个。
<details>
<summary><h3>方式一:桌面应用(推荐新手)</h3></summary>
下载 → 安装 → 打开就能用。
**下载安装包** — 打开 [Releases 页面](https://github.com/icebear0828/codex-proxy/releases),根据系统下载:
| 系统 | 文件 |
|------|------|
| Windows | `Codex Proxy Setup x.x.x.exe` |
| macOS | `Codex Proxy-x.x.x.dmg` |
| Linux | `Codex Proxy-x.x.x.AppImage` |
安装后打开应用,点击登录按钮用 ChatGPT 账号登录。浏览器访问 `http://localhost:8080` 即可看到控制面板。
</details>
<details>
<summary><h3>方式二:No-Node Lite(浏览器/服务器版,适合高级用户)</h3></summary>
如果你已经安装 Node.js,或者需要在服务器、WSL 等没有桌面环境的机器上运行
Codex Proxy,可以选择 No-Node Lite。它使用与 Electron 版相同的后端和控制面板,
但不内置 Node.js,因此包更小,也方便你自行管理运行时;上面的 Electron 安装包不受影响。
正式制品使用 `codex-proxy-<版本>-no-node-lite-all-platforms.zip`,解压后在包根目录运行对应入口:
```bash
# Windows:双击 codex-proxy.exe(无控制台并驻留托盘);codex-proxy.cmd 始终作为脚本 fallback 保留
# macOS/Linux:
./codex-proxy.sh
```
使用前请准备 Node.js 20 或更新版本。Lite 默认使用与 Electron 相同的系统用户数据目录;
只有显式传入 `--portable`(简写为 `-p`)时,才使用发行包目录下的 `data/`。
可以使用 `--mode=server`(`-m server`)只启动服务、`--mode=browser` 强制使用浏览器,
或在 Windows 上使用 `--mode=webview2` 强制使用 WebView2。`--host`、`--port`、
`--webview2-host`、`--node-path` 的简写分别是 `-H`、`-P`、`-w`、`-n`。
Windows 启动器会优先尝试 WebView2;不可用时回退到系统浏览器。缺少 WebView2 运行时
而显式指定 `--mode=webview2` 时,会先询问,确认后自动下载并运行微软官方在线安装器
(约 2MB,已校验微软签名)安装 WebView2,超时或拒绝则退出。原生
`codex-proxy.exe` 使用托盘运行,`codex-proxy.cmd` 作为诊断 fallback 保留。
找不到 Node.js 时会显示安装指引,不会静默下载或捆绑 Node。Lite 的“检查更新”打开最新
Releases 页面,暂不自动覆盖正在运行的包。
Linux x64 Lite 同时包含 glibc 和 musl 两种 TLS native addon,可用于常见 Linux 发行版
以及 Alpine Linux;目前不提供 Linux ARM 等其他架构的 native addon。
</details>
<details>
<summary><h3>方式三:npm 安装(适合已有 Node 的开发者)</h3></summary>
本项目不向 npmjs 公共仓库发布。推荐从 GitHub Release 下载离线包安装(免认证);主包和平台 native addon 也发布在 GitHub Packages,使用该 registry 需要具备 `read:packages` 权限的 GitHub token:
```bash
curl -L https://github.com/icebear0828/codex-proxy/releases/latest/download/codex-proxy-npm.zip -o codex-proxy-npm.zip
unzip codex-proxy-npm.zip -d codex-proxy-npm
cd codex-proxy-npm && node install.mjs
codex-proxy
# 打开 http://localhost:8080 登录
```
Windows 用户直接下载并解压 `codex-proxy-npm.zip`,在解压目录中运行 `node install.mjs` 即可;
安装脚本会按系统自动选择平台组件,完成后全局可用 `codex-proxy` 命令。
如需从 GitHub Packages 安装,请在用户级 npm 配置中设置 registry 和 token(classic PAT 需有 `read:packages` 权限;不要将 token 提交到仓库):
```ini
@icebear0828:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_PACKAGES_TOKEN}
```
设置 `GITHUB_PACKAGES_TOKEN` 环境变量后,可运行 `npm install -g @icebear0828/codex-proxy`。
要求 Node.js 22.13+。运行数据保存在用户数据目录
(Windows `%APPDATA%\@codex-proxy\electron\data`、Linux `~/.config/@codex-proxy/electron/data`、
macOS `~/Library/Application Support/@codex-proxy/electron/data`),更新包不会丢失;
`--portable` 或 `CODEX_PROXY_DATA_DIR` 可自定义位置。更新:离线包重新下载运行 `install.mjs`;GitHub Packages 安装则重跑 `npm install -g @icebear0828/codex-proxy@latest`。
常用参数:`--mode=server`(纯服务器)、`--mode=browser`(强制浏览器)、
`--host` / `--port`。完整参数见 `codex-proxy --help`。
</details>
<details>
<summary><h3>方式四:Docker 部署</h3></summary>
最简单的方式,一条命令即可启动:
```bash
docker run -d --name codex-proxy --restart unless-stopped \
-p 127.0.0.1:8080:8080 \
-v codex-proxy-data:/app/data \
-v codex-proxy-config:/app/config \
ghcr.io/icebear0828/codex-proxy:latest-lite
# 打开 http://localhost:8080 登录
```
> 该镜像基于 Alpine Linux + Node.js,只包含应用本体、前端页面和运行必需的原生组件,编译工具链、依赖缓存等仅构建时使用的内容均已移除;**功能完整**,Web 面板、账号管理、Ollama 桥接等都可正常使用,目前提供 linux/amd64。压缩后拉取约 57MB(另一版本基于 Debian,约 722MB),空闲内存约 40MB。首次启动会自动在 `codex-proxy-config` 卷中生成默认配置,账号数据保存在 `codex-proxy-data` 卷,更新镜像不丢失。需要让局域网其他设备访问时,把端口参数改成 `-p 8080:8080`。
已经在用 `docker-compose.yml`(默认 `:latest` 基于 Debian,含编译工具链,便于在容器内调试或从源码构建)的用户无需迁移:两个镜像的目录布局与 `./data`、`./config` 卷完全一致,把 compose 里的 `image` 换成 `ghcr.io/icebear0828/codex-proxy:latest-lite` 即可。
需要配置环境变量、自动更新等更多选项时,使用 compose 方式:
```bash
mkdir codex-proxy && cd codex-proxy
curl -O https://raw.githubusercontent.com/icebear0828/codex-proxy/main/docker-compose.yml
curl -O https://raw.githubusercontent.com/icebear0828/codex-proxy/main/.env.example
cp .env.example .env
docker compose up -d
# 打开 http://localhost:8080 登录
```
> 账号数据保存在 `data/` 文件夹,重启不丢失。其他容器连本服务用宿主机 IP(如 `192.168.x.x:8080`),不要用 `localhost`。
取消 `docker-compose.yml` 中 Watchtower 的注释即可自动更新。若要在 Docker 中启用 Ollama 兼容桥接,请参考下方 [Ollama Bridge 配置](#ollama-bridge-配置)。
> **内存设置**:`docker-compose.yml` 默认使用 `MEM_LIMIT=768m` 和 `NODE_OPTIONS=--max-old-space-size=512`。在 `.env` 中设置这两个变量即可按机器覆盖默认值。不设这两个参数时,Node/V8 会按**宿主机全部内存**(而不是这个容器实际该用多少)估算堆上限,在内存有限的机器上(尤其是和其他服务共享的 VPS)可能导致内存使用一路涨上去、GC 收得太晚,严重时能把整台宿主机拖垮。请按你机器的实际内存调整这两个值——`mem_limit` 留够给其他服务的余量,`--max-old-space-size` 要明显小于 `mem_limit`(Node 进程的 RSS 不止是 V8 堆)。
</details>
<details>
<summary><h3>方式四:源码运行</h3></summary>
```bash
git clone https://github.com/icebear0828/codex-proxy.git
cd codex-proxy
npm install # 安装后端依赖
cd web && npm install && cd .. # 安装前端依赖
npm run dev # 开发模式(热重载)
# 或: npm run build && npm start # 生产模式
```
> **需要 Rust 工具链**(用于编译 TLS native addon):
>
> ```bash
> # 1. 安装 Rust(如果没有的话)
> curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
> # 2. 编译 TLS addon
> cd native && npm install && npm run build && cd ..
> ```
>
> Docker / 桌面应用已内置编译好的 addon,无需手动编译。
打开 `http://localhost:8080` 登录。
</details>
### 验证
登录后打开控制面板 `http://localhost:8080`,在 **API Configuration** 区域找到你的 API Key,然后:
```bash
# 把 your-api-key 替换成控制面板里显示的密钥
curl http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key" \
-d '{"model":"gpt-5.6-sol","messages":[{"role":"user","content":"Hello!"}],"stream":true}'
```
看到 AI 回复的文字流即部署成功。如果返回 401,请检查 API Key 是否正确。
## 🌟 核心功能
### 🔌 全协议兼容
- 兼容 `/v1/chat/completions`(OpenAI)、`/v1/messages`(Anthropic)、Gemini 格式及 `/v1/responses`(Codex 直通)
- 内置可选 Ollama 兼容桥接,默认监听 `http://127.0.0.1:11434`
- SSE 流式输出,可直接对接所有 OpenAI / Anthropic SDK 和客户端
- 自动完成 Chat Completions / Anthropic / Gemini ↔ Codex Responses API 双向协议转换
- **Structured Outputs** — `response_format`(`json_object` / `json_schema`)和 Gemini `responseMimeType`
- **Function Calling** — 原生 `function_call` / `tool_calls` 支持(所有协议)
- **WebSocket 接口** — `/v1/responses` 支持客户端 WebSocket 流式直连(Bearer 鉴权),HTTP POST + SSE 作为回退保留
- **第三方 API Keys** — 支持多协议、按模型直通
- 📖 完整接口定义与协议说明请查阅 **[API 文档](./API_CN.md)**。
### 🔐 账号管理与智能轮换
- **OAuth PKCE 登录** — 浏览器一键授权,无需手动复制 Token
- **多账号轮换** — `least_used`(最少使用优先)、`round_robin`(轮询)、`sticky`(粘性)三种策略
- **Plan Routing** — 不同 plan(free/plus/team/business)的账号自动路由到各自支持的模型
- **Token 自动续期** — JWT 到期前自动刷新,指数退避重试
- **配额采集** — 默认从上游响应头和 WebSocket rate limit 事件被动更新账号额度;用户手动查询单账号额度时会调用 `/backend-api/wham/usage`,并把 `remaining_percent = 100 - used_percent` 写入缓存。
- **封禁检测** — 上游 403 自动标记 banned;401 token 吊销自动过期并切换账号
- **API Key Provider 池** — 支持通过 Dashboard 管理第三方 API Key、模型列表、导入导出和启停状态。
- **Web 控制面板** — 账号管理、用量统计、批量操作,中英双语;远程访问需 Dashboard 登录门
- **后备上游** — 当所有账号均不可用时,自动启用一个可编辑的兜底 API Key
- **后备状态指示** — 日志与首页明确标注每条请求实际使用的账号,以及进入后备时的状态
### 🌐 代理池
- **Per-Account 代理路由** — 为不同账号配置不同的上游代理
- **四种分配模式** — Global Default / Direct / Auto / 指定代理
- **健康检查** — 定时 + 手动,通过 ipify 获取出口 IP 和延迟
- **不可达自动标记** — 代理不可达时自动排除
### 🛡️ 反检测与协议伪装
- **Rust Native TLS** — 内置 reqwest + rustls native addon,TLS 指纹与真实 Codex 客户端精确一致,跨 Windows / macOS / Linux(含 Alpine)
- **客户端 Profile 预设** — 支持 `codex_cli`(默认,官方 CLI 纯净终端头)、`codex_desktop`(Desktop 完整头)、`opencode`、`pi` 与 `custom`,CLI 模式下自动剔除浏览器特定头(`sec-ch-ua` 等)
- **按账号 Device ID 隔离** — 为每个账号独立派生并持久化专属的 `x-codex-installation-id`,彻底杜绝多账号共享同一设备指纹
- **完整请求头仿真** — `originator`、`User-Agent`、`x-openai-internal-codex-residency`、`x-codex-turn-state`、`x-client-request-id` 等头按选定 profile 真实模拟发送
- **Cookie 持久化** — 自动捕获和回放 Cloudflare Cookie
- **指纹自动更新** — 轮询 Codex 更新源,自动同步 `app_version` 和 `build_number`
<details>
<summary><h2>🏗️ 技术架构</h2></summary>
```
Codex Proxy
┌──────────────────────────────────────────────────────────┐
│ │
│ Client (Cursor / Claude Code / Continue / SDK / ...) │
│ │ │
│ POST /v1/chat/completions (OpenAI) │
│ POST /v1/messages (Anthropic) │
│ POST /v1/responses (Codex 直通) │
│ POST /gemini/* (Gemini) │
│ │ │
│ ▼ │
│ ┌──────────┐ ┌───────────────┐ ┌──────────────┐ │
│ │ Routes │──▶│ Translation │──▶│ Proxy │ │
│ │ (Hono) │ │ Multi→Codex │ │ Native TLS │ │
│ └──────────┘ └───────────────┘ └──────┬───────┘ │
│ ▲ │ │
│ │ ┌───────────────┐ │ │
│ └──────────│ Translation │◀─────────┘ │
│ │ Codex→Multi │ SSE stream │
│ └───────────────┘ │
│ │
│ ┌──────────┐ ┌───────────────┐ ┌──────────────────┐ │
│ │ Auth │ │ Fingerprint │ │ Model Store │ │
│ │OAuth/API │ │ Rust (rustls) │ │ Static + Dynamic │ │
│ │ API Keys │ │ Headers/UA │ │ Plan Routing │ │
│ └──────────┘ └───────────────┘ └──────────────────┘ │
│ │
└──────────────────────────────────────────────────────────┘
│
Rust Native Addon (napi-rs)
reqwest 0.12.28 + rustls 0.23.36
(TLS 指纹 = 真实 Codex Desktop)
│
┌──────┴──────┐
▼ ▼
chatgpt.com 第三方 Provider
/backend-api/codex (第三方 API)
```
</details>
<details>
<summary><h2>📦 可用模型</h2></summary>
| 模型 ID | 推理等级 | 当前上下文 | 最大上下文 | 最大输出 | 输出 | 说明 |
|---------|---------|------------|------------|----------|------|------|
| `gpt-6-astra` | low / medium / high / xhigh / max / ultra | 1,050,000 | 1,050,000 | 128,000 | 文本 | GPT-6 前沿旗舰:复杂推理与端到端 Agent 编码(`gpt-6` 为其别名) |
| `gpt-6-astra-aeon` | low / medium / high / xhigh / max / ultra | 1,050,000 | 1,050,000 | 128,000 | 文本 | GPT-6 长程多 Agent 编排与深度推理变体 |
| `gpt-reserve` | low / medium / high / xhigh / max | 272,000 | 872,000 | 128,000 | 文本 | 快速高性价比 Agent 编码模型(全计划开放) |
| `gpt-5.6-sol` | low / medium / high / xhigh / max / ultra | 1,050,000 | 1,050,000 | 128,000 | 文本 | GPT-5.6 旗舰:复杂推理与编码(默认;`gpt-5.6` 为其别名) |
| `gpt-5.6-terra` | low / medium / high / xhigh / max / ultra | 1,050,000 | 1,050,000 | 128,000 | 文本 | GPT-5.6 智能与成本平衡 |
| `gpt-5.6-luna` | low / medium / high / xhigh / max / ultra | 1,050,000 | 1,050,000 | 128,000 | 文本 | GPT-5.6 高性价比 / 高吞吐 |
| `gpt-5.5` | low / medium / high / xhigh | 272,000 | 272,000 | 128,000 | 文本 | 复杂编码、研究和真实工作流 |
| `gpt-5.4` | low / medium / high / xhigh | 272,000 | 1,000,000 | 128,000 | 文本 | 日常编码强模型 |
| `gpt-5.4-mini` | low / medium / high / xhigh | 400,000 | — | 128,000 | 文本 | 5.4 轻量版 |
| `gpt-5.3-codex` | low / medium / high / xhigh | 400,000 | — | 128,000 | 文本 | 5.3 编程优化模型 |
| `gpt-5.2` | low / medium / high / xhigh | 400,000 | — | 128,000 | 文本 | 专业工作 + 长时间代理 |
| `gpt-5-codex` | low / medium / high | 400,000 | — | 128,000 | 文本 | GPT-5 编程优化模型 |
| `gpt-5-codex-mini` | medium / high | — | — | — | 文本 | 轻量 Codex / CLI 编程模型 |
| `gpt-oss-120b` | low / medium / high | 131,072 | — | — | 文本 | 开源 120B 模型 |
| `gpt-oss-20b` | low / medium / high | 131,072 | — | — | 文本 | 开源 20B 模型 |
| `gpt-image-2` | — | — | — | — | 图像 | 图像生成工具后端(通过 `image_generation` 调用) |
> **后缀**:任意 chat 模型名后追加 `-fast` 启用 Fast 模式,`-high`/`-low`/`-max`/`-ultra` 切换推理等级。例如:`gpt-5.6-sol-fast`、`gpt-5.6-sol-high-fast`、`gpt-5.6-sol-max`、`gpt-5.6-sol-ultra`。图像模型(`gpt-image-2`)不支持后缀。
>
> **Plan Routing**:不同 plan(free/plus/team/business)的账号自动路由到各自支持的模型,模型可用性以登录账号对应的 Codex 后端返回为准,不要按旧的 Plus-only 表理解。模型列表由后端动态获取,自动同步;只要模型出现在 Dashboard / `/v1/models/catalog` 中,就可以作为请求里的 `model` 使用。
>
> **前端模型选择 ≠ 配置文件**:Dashboard 中切换模型只影响前端展示和 API 示例中的模型名,**不会修改** `config/default.yaml` 或 `data/local.yaml` 中的 `model.default`。实际使用哪个模型取决于客户端请求中的 `model` 字段(如 Cursor、Claude Code 等自行指定),配置文件中的 `model.default` 仅在客户端未指定模型时作为兜底。
>
> **Max token 说明**:上表跟随当前 `config/models.yaml` 和 Codex runtime `/v1/models/catalog` 元数据;`—` 表示当前目录未返回该字段,不代表模型不可用。运行时从 Codex 后端拉到的模型信息会覆盖静态值,并保留 `contextWindow`、`maxContextWindow`、`maxOutputTokens`、`truncationPolicyLimit`。请求体里的 `context_window` / `max_context_window` / `truncation_policy` / `max_output_tokens` 都不是可用开关;直接转发给 Codex 原生接口会返回 `400 Unsupported parameter`。
>
> **富元数据**:`/v1/models` 与 `/v1/models/:modelId` 在 OpenAI 标准字段之外附带 Codex 后端返回的富元数据(`display_name`、`description`、`supported_reasoning_efforts`、`input_modalities`、`service_tiers`、`visibility`、`priority` 等,字段缺失时不输出)。OpenAI 客户端会忽略未知字段,行为不受影响。若下游 Codex CLI 需要完整模型目录,可在 provider 配置中把 `model_catalog_url` 指向 `/v1/models/catalog/codex`,该端点返回 CLI 原生解码的 `{models: [ModelInfo]}` 富格式:
>
> ```toml
> [model_providers.codex-proxy]
> name = "codex-proxy"
> base_url = "http://127.0.0.1:8080/v1"
> wire_api = "responses"
> model_catalog_url = "http://127.0.0.1:8080/v1/models/catalog/codex"
> ```
>
> 鉴权:CLI 会以 provider 的 API Key 调用 `model_catalog_url`。若代理设置了 `server.proxy_api_key`,请在 provider 配置中提供同一 Key(如 `env_key = "CODEX_PROXY_KEY"` 并导出该环境变量),否则目录请求会返回 401。
### 🖼️ 图像生成
图像生成走 `/v1/responses` 的 `image_generation` 内置工具,后端固定为 `gpt-image-2`。
**前提**:ChatGPT **Plus 及以上** 账号(free 账号上游会静默剥掉工具,模型会降级用 SVG 文本假装画图)。
```bash
curl -N http://localhost:8080/v1/responses \
-H "Authorization: Bearer $PROXY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.6-sol",
"stream": true,
"input": [{"role":"user","content":"Draw a red circle on white background."}],
"tools": [{"type":"image_generation","size":"3840x2160"}]
}'
```
常用参数:`size`(可请求 1024×1024 / 1024×1536 / 1536×1024 / 2048×2048 / 2048×3072 / 3072×2048 / 3840×2160 / `auto`)、`output_format`(`png` / `jpeg` / `webp`)、`output_compression`(jpeg / webp 可调)、`background`(`auto` / `opaque`)、`moderation`(`auto` / `low`)、`partial_images`(0–3)。一次只能出 1 张图(`n` 固定为 1);`model` 字段不管传什么都会被上游改写为图像工具的实际模型(当前响应回显为 `gpt-image-2-codex`)。详见 [API_CN.md](./API_CN.md#image_generation-工具)。
> **`size`** **不是固定像素保证。** Proxy 会保留并发送客户端填写的值,但当前上游会把 `2048x2048`、`2K`、`4K` 等请求归一化为 `size: "auto"`,再自行决定实际尺寸。2026-08-10 的真实请求中,`size: "2048x2048"` 的工具配置回显为 `auto`,最终 `image_generation_call.size` 和 PNG 像素均为 `1254x1254`。因此不能依靠该字段获得原生、精确的 2K/4K 输出;请以结果 item 的 `size` 或解码后图片像素为准。若业务必须拿到精确 `2048x2048` 文件,需要在生成后使用插值或 AI 超分辨率进行后处理。
事件流里 `image_generation_call` item 的 `result` 字段即 base64 编码的图像;`revised_prompt` 是上游改写后的最终提示词。
**编辑模式**(带参考图):在 user message 的 `content` 里追加 `{"type":"input_image","image_url":"data:image/png;base64,..."}` 即可。
> `/v1/chat/completions` 兼容路径会接受 `image_generation` 工具,避免 OpenAI 客户端因 schema 失败;但图像 payload 只有 `/v1/responses` 会稳定透出 `image_generation_call.result`。需要拿到图片字节时请使用 `/v1/responses`。
</details>
## 🔗 客户端接入
> 所有客户端的 API Key 均从控制面板 (`http://localhost:8080`) 获取。模型名填具体 ID(默认 `gpt-5.6-sol`)或任意 [可用模型](#-可用模型) ID。
<details>
<summary><h3>Claude Code (CLI)</h3></summary>
```bash
export ANTHROPIC_BASE_URL=http://localhost:8080
export ANTHROPIC_API_KEY=your-api-key
# 切换模型: export ANTHROPIC_MODEL=gpt-5.6-sol / gpt-5.6-terra / gpt-5.6-luna / gpt-5.6-sol-fast ...
claude
```
> 控制面板的 **Anthropic SDK Setup** 卡片可一键复制环境变量(含 Opus / Sonnet / Haiku 层级模型配置)。
>
> 推荐模型:Opus → `gpt-5.6-sol`,Sonnet → `gpt-5.6-terra`,Haiku → `gpt-5.6-luna`。
>
> ⚠️ 配置不生效?请参考 **[Claude Code 配置避坑指南](.github/guides/claude-code-setup.md)**(AUTH_TOKEN 劫持、API Key 黑名单等常见问题)。
</details>
<details>
<summary><h3>Codex CLI</h3></summary>
`~/.codex/config.toml`:
```toml
[model_providers.proxy_codex]
name = "Codex Proxy"
base_url = "http://localhost:8080/v1"
wire_api = "responses"
# 直接把 API Key 写进 config(推荐:本地单用户场景)
[model_providers.proxy_codex.http_headers]
Authorization = "Bearer your-api-key"
[profiles.default]
model = "gpt-5.6-sol"
model_provider = "proxy_codex"
```
> 💡 也可以改用环境变量:把 `[model_providers.proxy_codex.http_headers]` 这两行删掉,换成 `env_key = "PROXY_API_KEY"`,然后 `export PROXY_API_KEY=your-api-key && codex`。需要避免密钥落到 config 文件(多人共享 / 开源仓库)时用这个。
</details>
<details>
<summary><h3>Claude Desktop</h3></summary>
1. **开启开发者模式**:点击菜单栏 **Help** → **Troubleshooting** → **Enable Developer Mode**。
2. **配置第三方推理**:点击菜单栏新出现的 **Developer** → **Configure Third-Party Inference...**。
3. **填写配置**:
- **Endpoint**: `http://127.0.0.1:8080`
- **API Key**: 你的 API Key
- **Model**: `claude-opus-4-7` / `claude-sonnet-4-6` / `claude-haiku-4-5`
> 或手动修改配置文件(Windows 下路径通常在 `%APPDATA%\Claude-3p\configLibrary\` 目录下的 JSON 文件,Mac 为 `~/Library/Application Support/Claude-3p/configLibrary/`),添加如下字段:
```json
{
"disableDeploymentModeChooser": true,
"inferenceProvider": "gateway",
"inferenceGatewayBaseUrl": "http://127.0.0.1:8080",
"inferenceGatewayApiKey": "your-api-key",
"inferenceGatewayAuthScheme": "bearer",
"inferenceModels": [
"claude-opus-4-7",
"claude-sonnet-4-6",
"claude-haiku-4-5"
]
}
```
内置 Claude 形态模型名会映射到 Codex 模型。自定义映射请写到 `data/local.yaml`,不要改 `config/models.yaml`:
```yaml
model:
aliases:
claude-opus-4-7: gpt-5.6-sol
claude-sonnet-4-6: gpt-5.6-terra
claude-haiku-4-5: gpt-5.6-luna
my-openai: openai:gpt-4o
my-deepseek: deepseek-chat
```
alias 左边是客户端请求里填写的模型名,右边是真正发给上游的模型名。右侧可以是 Codex 模型 ID、带 provider 前缀的模型(如 `openai:gpt-4o` / `anthropic:claude-sonnet-4-5` / `gemini:gemini-2.5-pro`),也可以是已通过 `model_routing` 绑定到自定义 provider 的模型名(如 `deepseek-chat`)。别名会出现在 `/v1/models`,请求进入直连 provider 时会自动把模型名改写成映射目标。
> 💡 **排查提示 (Windows)**: 如果使用 `127.0.0.1` 时 Claude Desktop 提示 `ERR_CONNECTION_REFUSED`(而使用 `localhost` 提示 URL 格式错误),说明 Node.js 在你的系统上默认只绑定了 IPv6。请进入 Codex Proxy 控制面板的设置页面,将 **Host** 修改为 `127.0.0.1`,或在 `data/local.yaml` 中添加 `server: { host: "127.0.0.1" }` 后重启代理。
>
> 💡 **局域网使用提示 (LAN)**: Claude Desktop 强制校验 API 地址,**只允许** `https://` 开头或 `http://127.0.0.1`。如果你将 Codex Proxy 部署在局域网另一台机器(如 `192.168.x.x`),直接填入会报错。解决方法:
>
> 1. **SSH 隧道 (最简单)**:在客户端机器运行 `ssh -L 8080:127.0.0.1:8080 user@192.168.x.x`,然后在 Claude 里填 `http://127.0.0.1:8080`。
> 2. **反向代理**:使用 Caddy 或 Nginx 配置局域网 HTTPS 证书。
</details>
<details>
<summary><h3>Codex Desktop (官方应用)</h3></summary>
官方客户端与 CLI 共用配置文件,修改后需重启客户端生效。
`~/.codex/config.toml`:
```toml
[model_providers.proxy_codex]
name = "Codex Proxy"
base_url = "http://localhost:8080/v1"
wire_api = "responses"
[model_providers.proxy_codex.http_headers]
Authorization = "Bearer your-api-key"
[profiles.default]
model = "gpt-5.6-sol"
model_provider = "proxy_codex"
```
> 💡 **为什么不用 `env_key`?** macOS / Windows 的 GUI 应用不读 shell 的 `~/.zshrc` / `.bashrc`,光 `export PROXY_API_KEY=...` 在终端里 GUI 进程根本看不到,启动会直接报 `Missing environment variable`。`http_headers` 把 Authorization 写在 config 里,重启 Codex 就能用,不用折腾 `launchctl setenv` 或 LaunchAgent。需要密钥从配置文件解耦时(共享机器 / 仓库提交)再换回 `env_key = "PROXY_API_KEY"` 走环境变量。
>
> ⚠️ 如果你是通过"登录 ChatGPT 账号"方式使用的,客户端可能会忽略此配置——只要 `[model_providers.proxy_codex]` 配上、`profiles.default.model_provider = "proxy_codex"`,新会话就会走 proxy;登录会话仍可能直接走官方上游。
</details>
<details>
<summary><h3>Claude for VSCode / JetBrains</h3></summary>
打开 Claude 扩展设置,找到 **API Configuration**:
- **API Provider**: 选择 Anthropic
- **Base URL**: `http://localhost:8080`
- **API Key**: 你的 API Key
或在 VS Code `settings.json` 中添加:
```json
{
"claude.apiEndpoint": "http://localhost:8080",
"claude.apiKey": "your-api-key"
}
```
</details>
<details>
<summary><h3>Cursor</h3></summary>
1. 打开 Settings → Models
2. 选择 OpenAI API
3. 设置 **Base URL**: `http://localhost:8080/v1`
4. 设置 **API Key**: 你的 API Key
5. 添加模型名 `gpt-5.6-sol`(或其他模型 ID)
</details>
<details>
<summary><h3>Windsurf</h3></summary>
1. 打开 Settings → AI Provider
2. 选择 **OpenAI Compatible**
3. **API Base URL**: `http://localhost:8080/v1`
4. **API Key**: 你的 API Key
5. **Model**: `gpt-5.6-sol`
</details>
<details>
<summary><h3>Cline (VSCode 扩展)</h3></summary>
1. 打开 Cline 侧边栏 → 设置齿轮
2. **API Provider**: 选择 OpenAI Compatible
3. **Base URL**: `http://localhost:8080/v1`
4. **API Key**: 你的 API Key
5. **Model ID**: `gpt-5.6-sol`
</details>
<details>
<summary><h3>Continue (VSCode 扩展)</h3></summary>
`~/.continue/config.json`:
```json
{
"models": [{
"title": "Codex",
"provider": "openai",
"model": "gpt-5.6-sol",
"apiBase": "http://localhost:8080/v1",
"apiKey": "your-api-key"
}]
}
```
</details>
<details>
<summary><h3>aider</h3></summary>
```bash
aider --openai-api-base http://localhost:8080/v1 \
--openai-api-key your-api-key \
--model openai/gpt-5.6-sol
```
或设置环境变量:
```bash
export OPENAI_API_BASE=http://localhost:8080/v1
export OPENAI_API_KEY=your-api-key
aider --model openai/gpt-5.6-sol
```
</details>
<details>
<summary><h3>Cherry Studio</h3></summary>
1. 设置 → 模型服务 → 添加
2. **类型**: OpenAI
3. **API 地址**: `http://localhost:8080/v1`
4. **API Key**: 你的 API Key
5. 添加模型 `gpt-5.6-sol`
</details>
<details>
<summary><h3>Pi Coding Agent (pi)</h3></summary>
[Pi Coding Agent](https://github.com/earendil-works/pi) (`@earendil-works/pi-coding-agent`) 可通过 `~/.pi/agent/models.json` 配置自定义 Provider 接入 Codex Proxy。
<details>
<summary>方式一:OpenAI Completions 协议(推荐)</summary>
编辑 `~/.pi/agent/models.json`:
```json
{
"providers": {
"codex-proxy": {
"baseUrl": "http://localhost:8080/v1",
"api": "openai-completions",
"apiKey": "your-api-key",
"models": [
{
"id": "gpt-5.6-sol",
"name": "Codex GPT-5.6 Sol",
"contextWindow": 1050000,
"maxTokens": 128000,
"input": ["text", "image"]
},
{
"id": "gpt-5.6-terra",
"name": "Codex GPT-5.6 Terra",
"contextWindow": 1050000,
"maxTokens": 128000,
"input": ["text", "image"]
}
]
}
}
}
```
> 💡 `apiKey` 也可配置为 `"$PROXY_API_KEY"`,并在运行终端中通过 `export PROXY_API_KEY=your-api-key` 注入。
</details>
<details>
<summary>方式二:Anthropic Messages 协议</summary>
```json
{
"providers": {
"codex-proxy-anthropic": {
"baseUrl": "http://localhost:8080",
"api": "anthropic-messages",
"apiKey": "your-api-key",
"models": [
{
"id": "gpt-5.6-sol",
"name": "Codex GPT-5.6 Sol",
"contextWindow": 1050000,
"maxTokens": 128000,
"input": ["text", "image"]
}
]
}
}
}
```
</details>
<details>
<summary>方式三:Codex Responses 协议(直通)</summary>
```json
{
"providers": {
"codex-proxy-responses": {
"baseUrl": "http://localhost:8080/v1",
"api": "openai-responses",
"apiKey": "your-api-key",
"models": [
{
"id": "gpt-5.6-sol",
"name": "Codex GPT-5.6 Sol",
"contextWindow": 1050000,
"maxTokens": 128000,
"input": ["text", "image"]
}
]
}
}
}
```
启动运行:
```bash
pi --provider codex-proxy --model gpt-5.6-sol
```
</details>
</details>
<details>
<summary><h3>Ollama 兼容客户端</h3></summary>
在 Dashboard → Settings → **Ollama Bridge** 中启用后,可使用 Ollama 默认地址:
| 设置项 | 值 |
|--------|-----|
| Base URL | `http://localhost:11434` |
| API Key | 不需要,Bridge 内部会使用 Codex Proxy 的密钥访问主服务 |
| Model | `gpt-5.6-sol`(或其他模型 ID) |
```bash
curl http://localhost:11434/api/tags
curl http://localhost:11434/api/chat \
-H "Content-Type: application/json" \
-d '{"model":"gpt-5.6-sol","messages":[{"role":"user","content":"Hello!"}],"stream":true}'
```
> Ollama API 本身没有鉴权。默认仅监听 `127.0.0.1`,不建议暴露到公网或未信任的局域网。
</details>
<details>
<summary><h3>通用 OpenAI 兼容客户端</h3></summary>
任何支持自定义 OpenAI API Base 的客户端均可接入:
| 设置项 | 值 |
|--------|-----|
| Base URL | `http://localhost:8080/v1` |
| API Key | 控制面板获取 |
| Model | `gpt-5.6-sol`(或其他模型 ID) |
**Python**
```python
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8080/v1", api_key="your-api-key")
for chunk in client.chat.completions.create(
model="gpt-5.6-sol", messages=[{"role": "user", "content": "Hello!"}], stream=True
):
print(chunk.choices[0].delta.content or "", end="")
```
**Node.js**
```typescript
import OpenAI from "openai";
const client = new OpenAI({ baseURL: "http://localhost:8080/v1", apiKey: "your-api-key" });
const stream = await client.chat.completions.create({
model: "gpt-5.6-sol", messages: [{ role: "user", content: "Hello!" }], stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content || "");
}
```
</details>
<details>
<summary><h2>⚙️ 配置说明</h2></summary>
> **重要**:不要直接修改 `config/default.yaml`,该文件会在版本更新时被覆盖。自定义配置请通过 Dashboard 设置面板修改(自动保存到 `data/local.yaml`),或手动创建 `data/local.yaml` 写入需要覆盖的字段。`data/` 目录不受更新影响。
> **Docker 部署的差异**:容器启动时只从镜像内的默认配置**按文件补种**缺失项(`cp -rn`,只补不覆盖)。因此升级镜像后新增的默认配置文件(如 `model-pricing.yaml`)会自动出现在已有配置卷中,而你改过的文件不会被覆盖;反过来说,`config/` 卷里已存在的旧默认值也不会随镜像更新。无论哪种部署方式,自定义配置都请写入 `data/local.yaml`。
### CORS 允许主机
通过环境变量 `CORS_ALLOWED_HOSTS` 可以配置允许跨域访问的主机列表,对应配置文件中的 `server.cors` 字段。多个主机名用逗号分隔:
```bash
export CORS_ALLOWED_HOSTS="example.com,another-domain.com"
```
或在 `data/local.yaml` 中配置:
```yaml
server:
cors:
- "https://example.com"
- "https://another-domain.com"
```
默认配置位于 `config/default.yaml`:
| 分类 | 关键配置 | 说明 |
|------|---------|------|
| `server` | `host`, `port`, `proxy_api_key` | 监听地址与 API 密钥 |
| `api` | `base_url`, `timeout_seconds` | 上游 API 地址与超时 |
| `client` | `profile`, `originator`, `app_version`, `build_number`, `platform`, `arch`, `chromium_version` | 客户端指纹预设(`codex_cli` / `codex_desktop` / `opencode` / `pi` / `custom`)及版本参数 |
| `model` | `default`, `default_reasoning_effort`, `default_service_tier`, `aliases`, `custom_models`, `inject_desktop_context` | 默认模型、推理配置、模型映射与自定义模型目录 |
| `auth` | `rotation_strategy`, `rate_limit_backoff_seconds` | 轮换策略与限流退避 |
| `tls` | `proxy_url`, `force_http11` | TLS 代理与 HTTP 版本 |
| `quota` | `refresh_interval_minutes`, `warning_thresholds`, `skip_exhausted` | 用量快照、阈值配置与耗尽账号跳过 |
| `session` | `ttl_minutes`, `cleanup_interval_minutes` | Dashboard session 管理 |
| `ollama` | `enabled`, `host`, `port`, `version`, `disable_vision` | Ollama 兼容桥接 |
| `official_agent` | `enabled`, `api_key`, `app_server_url`, `auth` | 官方 Codex app-server 桥接,用于复用 Chrome/browser 插件 |
### 客户端 Profile 与指纹预设
`client.profile` 支持一键切换客户端身份,自动调整请求头组合与反检测特征:
```yaml
client:
profile: codex_cli # 预设: codex_cli (默认), codex_desktop, opencode, pi, custom
# 预设说明:
# - codex_cli: 官方 Codex CLI 纯净终端头 (originator: codex_cli_rs),剔除所有浏览器特有头 (sec-ch-ua 等)
# - codex_desktop: 官方 Codex Desktop 完整头 (originator: Codex Desktop),包含 sec-ch-ua 与 Chromium 版本
# - opencode: opencode 终端头 (originator: opencode)
# - pi: pi 终端头 (originator: pi)
# - custom: 完全自定义模式,读取 client.originator 及 fingerprint.yaml 模板
```
同时,代理为每个绑定的账号自动独立派生并持久化专属的 `x-codex-installation-id`(储存于 `data/installation_ids/`),确保多账号并发/轮换时各账号具有独立的客户端设备身份,避免上游根据设备 UUID 产生关联。
### 模型映射
`model.aliases` 用来把客户端里的模型名映射成真实上游模型,适合 Claude Desktop / Cursor / Continue 等客户端只能选择固定模型名、或你希望暴露更短别名的场景。
也可以直接在 Dashboard → Settings → **模型映射** 中添加 / 删除映射。保存后会写入 `data/local.yaml` 并热加载到后端,不需要修改 `config/default.yaml`。
```yaml
model:
aliases:
claude-opus-4-7: gpt-5.6-sol
sonnet-local: gpt-5.6-terra
openai-fast: openai:gpt-4o
deepseek-local: deepseek-chat
providers:
custom:
deepseek:
api_key: "sk-..."
base_url: "https://api.deepseek.com/v1"
models: ["deepseek-chat"]
model_routing:
deepseek-chat: deepseek
```
映射解析发生在 `model_routing` 和内置 Claude/Gemini 自动路由之前。映射到 Codex 模型时仍支持 `-fast` / `-high` 等后缀;映射到第三方 provider 时,直连请求会把 `model` 字段改写成右侧目标值。
如果你还需要把完全自定义的 Codex-compatible 模型 ID 加入模型目录,可在 `data/local.yaml` 中配置 `model.custom_models`。简单字符串会使用默认 text/medium 元数据;对象写法可补 display name、推理等级、上下文和输出上限:
```yaml
model:
custom_models:
- local-simple
- id: local-rich
display_name: Local Rich
description: Local rich model
supported_reasoning_efforts: [low, high]
default_reasoning_effort: high
input_modalities: [text, image]
output_modalities: [text]
context_window: 12345
max_context_window: 23456
max_output_tokens: 3456
```
### 配额轮转
`quota.skip_exhausted: true` 时,账号池会在选择账号前跳过缓存额度已经耗尽的账号;这个过滤发生在 session affinity / `preferredEntryId` 之前,所以长对话也不会强行粘到已耗尽账号上。
当前跳过条件是缓存额度里的 `rate_limit.limit_reached === true`、`secondary_rate_limit.limit_reached === true` 或 `code_review_rate_limit.limit_reached === true`。如果只是 `used_percent` 接近 100(例如 99%)但上游还没标记 `limit_reached`,代理仍会继续使用该账号;真正打到上游 429 后,账号会进入 `rate_limited` 退避并切换到其他可用账号。secondary / code review 窗口自己的 `reset_at` 过期后会从缓存中清除,避免账号被永久跳过。
### 局域网访问
源码默认配置仅监听 `127.0.0.1`;Electron 也会传入 `127.0.0.1`,除非 `data/local.yaml` 显式覆盖。Docker 镜像会通过 `CODEX_PROXY_HOST=0.0.0.0` 在容器内监听所有接口,`docker-compose.yml` 默认仍只把宿主机端口绑定到 `127.0.0.1`。
需要仅本机访问时写入:
```yaml
server:
host: "127.0.0.1"
```
如需局域网内其他设备访问,在 `data/local.yaml` 中添加,并把 `docker-compose.yml` 的端口映射从 `127.0.0.1:${PORT:-8080}:8080` 改成 `${PORT:-8080}:8080`:
```yaml
server:
host: "0.0.0.0"
```
Electron 桌面版的 `data/local.yaml` 路径:
当前 Electron 构建的实际 `app.getPath("userData")` 目录名为
`@codex-proxy/electron`;下面路径以该目录为准。
| 系统 | 路径 |
|------|------|
| macOS | `~/Library/Application Support/@codex-proxy/electron/data/local.yaml` |
| Windows | `%APPDATA%/@codex-proxy/electron/data/local.yaml` |
| Linux | `~/.config/@codex-proxy/electron/data/local.yaml` |
> ⚠️ 绑定 `0.0.0.0` 会将服务暴露到局域网,务必在 Dashboard → 密钥设置中配置强密钥。
### TLS 配置
```yaml
tls:
proxy_url: null # null = 自动检测本地代理;填写代理 URL 指定上游代理
force_http11: false # HTTP/2 失败时自动降级 HTTP/1.1;true = 强制 HTTP/1.1
```
> 内置 Rust native addon(reqwest + rustls),TLS 指纹与真实 Codex Desktop 完全一致。源码运行需先编译:`cd native && npm install && npm run build`。
### API 密钥
```yaml
server:
proxy_api_key: "pwd" # 自定义密钥,客户端用 Bearer pwd 访问
# proxy_api_key: null # null = 不配置全局密钥;已登录账号仍会生成 account-level codex-proxy-xxxx 密钥
```
首次启动如果缺少 `data/local.yaml`,程序会自动创建 `server.proxy_api_key: pwd`。当前可用密钥显示在控制面板的 API Configuration 区域。
### Ollama Bridge 配置
```yaml
ollama:
enabled: false # true = 启动内置 Ollama 兼容监听器
host: 127.0.0.1 # 默认仅本机可访问
port: 11434 # Ollama 默认端口
version: "0.18.3" # /api/version 返回值
disable_vision: false # true = /api/show 不声明 vision 能力
```
支持的 Ollama 端点:
| 端点 | 方法 | 说明 |
|------|------|------|
| `http://localhost:11434/api/version` | GET | Ollama 版本探测 |
| `http://localhost:11434/api/tags` | GET | 模型列表 |
| `http://localhost:11434/api/show` | POST | 模型元数据 |
| `http://localhost:11434/api/chat` | POST | 聊天补全,支持流式 NDJSON |
| `http://localhost:11434/v1/*` | 任意 | OpenAI `/v1` 直通 |
Docker 部署时,如果希望宿主机访问 `11434`:
1. 在 Dashboard 或 `data/local.yaml` 中设置 `ollama.enabled: true` 和 `ollama.host: 0.0.0.0`。
2. 取消 `docker-compose.yml` 中 `127.0.0.1:${OLLAMA_BRIDGE_PORT:-11434}:11434` 端口映射的注释。
3. 保持宿主机绑定 `127.0.0.1`,除非你明确知道自己要把无鉴权 Ollama API 暴露到网络。
浏览器 CORS 访问仅允许 `localhost`、`127.x.x.x`、`::1` 等 loopback origin;非本机网页来源不能读取桥接响应。Bridge 会为 `/v1/*` 直通请求注入已配置的 Codex Proxy API Key,因此暴露到 localhost 之外时,相当于也把主代理 API 以无鉴权方式暴露出去。
### Official Agent Bridge 配置
该桥接用于连接本机官方 `codex app-server`,从而复用 Codex app 的官方 Chrome/browser 插件、审批和 app mention 能力。默认关闭,不影响现有 `/v1/*` 模型代理。
先启动官方 app-server:
```bash
codex app-server --listen ws://127.0.0.1:4500
```
然后在 `data/local.yaml` 启用:
```yaml
server:
proxy_api_key: "your-api-key"
official_agent:
enabled: true
api_key: "your-official-agent-key"
app_server_url: ws://127.0.0.1:4500
auth:
type: none
```
如果 app-server 使用 capability token:
```bash
codex app-server --listen ws://127.0.0.1:4500 \
--ws-auth capability-token \
--ws-token-file /absolute/path/to/token
```
对应配置:
```yaml
server:
proxy_api_key: "your-api-key"
official_agent:
enabled: true
api_key: "your-official-agent-key"
app_server_url: ws://127.0.0.1:4500
auth:
type: capability_token
token_file: /absolute/path/to/token
```
可用端点:
```bash
curl http://localhost:8080/official-agent/apps \
-H "Authorization: Bearer your-official-agent-key"
```
```bash
curl -N http://localhost:8080/official-agent/threads/{threadId}/turns \
-H "Authorization: Bearer your-official-agent-key" \
-H "Content-Type: application/json" \
-d '{"text":"Open localhost:8080 and inspect the dashboard","app":{"id":"chrome","name":"Chrome"}}'
```
### 环境变量覆盖
| 环境变量 | 覆盖配置 |
|---------|---------|
| `PORT` | `server.port` |
| `CODEX_PROXY_HOST` | `server.host`(仅当 `data/local.yaml` 未显式设置 `server.host` 时生效) |
| `CODEX_PLATFORM` | `client.platform` |
| `CODEX_ARCH` | `client.arch` |
| `HTTPS_PROXY` | `tls.proxy_url` |
| `OLLAMA_BRIDGE_ENABLED` | `ollama.enabled` |
| `OLLAMA_BRIDGE_HOST` | `ollama.host` |
| `OLLAMA_BRIDGE_PORT` | `ollama.port` |
| `OLLAMA_BRIDGE_VERSION` | `ollama.version` |
| `OLLAMA_BRIDGE_DISABLE_VISION` | `ollama.disable_vision` |
</details>
<details>
<summary><h2>📡 API 端点</h2></summary>
**协议端点**
| 端点 | 方法 | 说明 |
|------|------|------|
| `/v1/chat/completions` | POST | OpenAI 格式聊天补全 |
| `/v1/responses` | POST | Codex Responses API 直通 |
| `/v1/responses/compact` | POST | Codex 远程 compact 响应代理 |
| `/v1/alpha/search` | POST | Codex standalone Web Search(`codex-responses` API-key wire) |
| `/v1/images/generations` | POST | Codex JSON 图片生成直通(`codex-responses` API-key wire) |
| `/v1/images/edits` | POST | Codex JSON 图片编辑直通(`codex-responses` API-key wire) |
| `/v1/messages` | POST | Anthropic 格式聊天补全 |
| `/v1/models` | GET | 可用模型列表(含 Codex 后端富元数据:描述、推理档位、模态、service tiers 等) |
| `/v1/models/catalog` | GET | Dashboard 使用的完整模型目录 |
| `/v1/models/catalog/codex` | GET | Codex CLI `model_catalog_url` 兼容的富目录(`{models: [ModelInfo]}`) |
| `/v1/models/:modelId/info` | GET | 单个模型的推理等级等详情 |
| `/v1beta/models` | GET | Gemini 格式模型列表 |
| `/v1beta/models/:modelAction` | POST | Gemini `generateContent` / `streamGenerateContent` |
| `:11434/api/chat` | POST | Ollama 兼容聊天补全(需启用 Ollama Bridge) |
**账号与认证**
| 端点 | 方法 | 说明 |
|------|------|------|
| `/auth/login` | GET | OAuth 登录入口 |
| `/auth/accounts` | GET | 账号列表(含缓存额度) |
| `/auth/accounts` | POST | 添加单个账号(token 或 refreshToken) |
| `/auth/accounts/import` | POST | 批量导入账号(JSON / `text/plain` token 行) |
| `/auth/accounts/export` | GET | 导出账号(`?format=full|minimal|cockpit_tools|sub2api|cpa`) |
| `/auth/accounts/batch-delete` | POST | 批量删除账号 |
| `/auth/accounts/batch-status` | POST | 批量修改账号状态 |
| `/auth/accounts/health-check` | POST | 批量检测账号可用性 |
| `/auth/accounts/:id/refresh` | POST | 刷新并探测单个账号 |
| `/auth/accounts/:id/quota` | GET | 主动查询单个账号额度 |
| `/auth/accounts/:id/cookies` | GET/POST/DELETE | 管理账号 Cloudflare cookies |
| `/auth/quota/warnings` | GET | 当前额度预警状态 |
**第三方 API Keys**
Antigravity OAuth 账号也可在 Dashboard 的 Provider 池中添加:输入 Google OAuth `refresh_token`,手动填写模型 ID;Google Cloud Project ID 可留空,由 `loadCodeAssist` 自动发现。若账号未返回项目 ID,请手动填写。OAuth client ID 和 secret 均有内置默认值,通常无需设置环境变量;如 refresh token 来自其他 OAuth client,可通过 `ANTIGRAVITY_OAUTH_CLIENT_ID` 和 `ANTIGRAVITY_OAUTH_CLIENT_SECRET` 覆盖。请求和 `/v1/models` 使用 `antigravity:<model-id>` 名称。
对于在标准 Responses API 上要求 Codex 官方客户端上下文的 API-key 上游,请在 Dashboard 中选择 `Custom` Provider 和 `Codex Responses (client context)` 协议。Base URL 应填写 API v1 根地址(例如 `https://provider.example.com/v1`,不要填写完整的 `/responses` 地址)。该协议的主 Responses 请求使用 HTTP SSE,并发送 Codex headers、installation/session/thread/window ID 与 client metadata;同时支持按请求 body 的 `model` 路由 standalone Web Search、远程 compact 和 Codex JSON 图片生成/编辑端点,不支持 Embeddings。若供应商没有提供兼容的 `/models` 接口,可在 Dashboard 中手动填写模型名。
| 端点 | 方法 | 说明 |
|------|------|------|
| `/auth/api-keys/catalog` | GET | 内置 Provider 与推荐模型目录 |
| `/auth/api-keys` | GET/POST | API Key 列表 / 添加 |
| `/auth/api-keys/models` | POST | 从自定义 OpenAI-compatible Provider 拉取模型 |
| `/auth/api-keys/export` | GET | 导出 API Key 配置 |
| `/auth/api-keys/import` | POST | 导入 API Key 配置 |
| `/auth/api-keys/batch-delete` | POST | 批量删除 API Key |
| `/auth/api-keys/:id` | DELETE | 删除单个 API Key |
| `/auth/api-keys/:id/label` | PATCH | 修改 API Key 标签 |
| `/auth/api-keys/:id/status` | PATCH | 启用或停用 API Key |
**账号导入导出示例**
```bash
# 导出所有账号(完整格式,含 token)
curl -s http://localhost:8080/auth/accounts/export \
-H "Authorization: Bearer your-api-key" > backup.json
# 导出精简格式(仅 refreshToken + label,适合分享)
curl -s "http://localhost:8080/auth/accounts/export?format=minimal" \
-H "Authorization: Bearer your-api-key" > backup-minimal.json
# 导出第三方兼容格式
curl -s "http://localhost:8080/auth/accounts/export?format=sub2api" \
-H "Authorization: Bearer your-api-key" > sub2api-accounts.json
# 批量导入(支持 token、refreshToken,或两者同时传)
curl -X POST http://localhost:8080/auth/accounts/import \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key" \
-d '{
"accounts": [
{ "token": "eyJhbGciOi..." },
{ "refreshToken": "v1.abc..." },
{ "refreshToken": "v1.def...", "label": "备用账号" }
]
}'
# 返回: { "added": 2, "updated": 1, "failed": 0, "errors": [] }
# text/plain token 行导入(每行 access token 或 refresh token)
curl -X POST http://localhost:8080/auth/accounts/import \
-H "Content-Type: text/plain" \
-H "Authorization: Bearer your-api-key" \
--data-binary $'eyJhbGciOi...\noaistb_rt_...\n'
# 备份恢复一键操作(导出后直接导入到另一个实例)
curl -X POST http://localhost:8080/auth/accounts/import \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key" \
-d @backup.json
```
**管理接口**
| 端点 | 方法 | 说明 |
|------|------|------|
| `/admin/rotation-settings` | GET/POST | 轮换策略配置 |
| `/admin/quota-settings` | GET/POST | 额度刷新与预警配置 |
| `/admin/ollama-settings` | GET/POST | Ollama Bridge 配置 |
| `/admin/ollama-status` | GET | Ollama Bridge 运行状态 |
| `/admin/refresh-models` | POST | 手动刷新模型列表 |
| `/admin/usage-stats/summary` | GET | 用量统计汇总 |
| `/admin/usage-stats/history` | GET | 用量时间序列 |
| `/admin/logs` | GET | 请求日志列表 |
| `/admin/logs/state` | GET/POST | 日志采集开关与配置 |
| `/admin/update-status` | GET | 自更新状态 |
| `/admin/check-update` | POST | 检查更新 |
| `/admin/apply-update` | POST | 执行自更新 |
| `/health` | GET | 健康检查 |
**代理池**
| 端点 | 方法 | 说明 |
|---------|---------|------|
| `/api/proxies` | GET/POST | 代理池列表 / 添加代理 |
| `/api/proxies/:id` | PUT/DELETE | 更新 / 删除代理 |
| `/api/proxies/:id/check` | POST | 健康检查单个代理 |
| `/api/proxies/check-all` | POST | 全部代理健康检查 |
| `/api/proxies/assign` | POST | 为账号分配代理 |
| `/api/proxies/assignments` | GET | 查看账号代理分配 |
| `/api/proxies/assign-bulk` | POST | 批量分配代理 |
| `/api/proxies/assign-rule` | POST | 按规则分配代理 |
| `/api/proxies/export` | GET | 导出代理池 YAML |
| `/api/proxies/import` | POST | 导入代理池 YAML |
</details>
## 📋 系统要求
- **Node.js** 18+(推荐 20+)
- **Rust** — 源码运行需 Rust 工具链(编译 TLS native addon);Docker / 桌面应用已内置
- **ChatGPT 账号** — 免费账号即可
- **Docker**(可选)
## ⚠️ 注意事项
- Codex API 为**流式输出专用**,`stream: false` 时代理内部流式收集后返回完整 JSON
- 本项目依赖 Codex Desktop 的公开接口,上游版本更新时会自动检测并更新指纹
- Windows 下 native TLS addon 需 Rust 工具链编译;Docker 部署已预编译,无需额外配置
## 📝 最近更新
完整更新日志请查看 [CHANGELOG.md](./CHANGELOG.md)。
## ☕ 赞赏 & 交流
觉得有帮助?请作者喝杯咖啡,或加入 Telegram 交流群获取使用帮助。二维码见 [页面顶部](#)。
## 🙏 贡献致谢
Codex Proxy 最初只是一个个人自用项目,一路走来收获了超乎预期的关注与支持。
特别感谢所有通过代码、文档、修复或 PR 参与建设的贡献者:
[@SsuJojo](https://github.com/SsuJojo) · [@TutuchanXD](https://github.com/TutuchanXD) · [@kanweiwei](https://github.com/kanweiwei) · [@et2010](https://github.com/et2010) · [@d-demand-priv](https://github.com/d-demand-priv) · [@hangox](https://github.com/hangox) · [@jarvisluk](https://github.com/jarvisluk) · [@jeasonstudio](https://github.com/jeasonstudio) · [@JPClaw12](https://github.com/JPClaw12) · [@lezi-fun](https://github.com/lezi-fun) · [@lookvincent](https://github.com/lookvincent) · [@pocper1](https://github.com/pocper1) · [@woai66](https://github.com/woai66) · [@xsShuang](https://github.com/xsShuang) · [@yuwei5380](https://github.com/yuwei5380) · [@aeltorio](https://github.com/aeltorio) · [@williamjameshandley](https://github.com/williamjameshandley) · [@FlavienKlr](https://github.com/FlavienKlr) · [@zyycn](https://github.com/zyycn)
感谢所有在 [Issues](https://github.com/icebear0828/codex-proxy/issues) 里提交 bug 复现、日志、兼容性反馈和功能建议的用户。这些反馈直接推动了账号轮换、代理兼容、Dashboard、Ollama Bridge、模型兼容和错误观测等能力的迭代。
**更要由衷感谢所有默默使用、关注和支持本项目的开发者朋友们。正是你们的认可与喜爱,让我一直坚持维护和迭代到现在。很高兴有这么多人喜欢 Codex Proxy!** ❤️
## ⭐ Star History
[](https://star-history.dera.page/#icebear0828/codex-proxy&Date)
## 📄 许可协议
本项目采用 **非商业许可 (Non-Commercial)**:
- **允许**:个人学习、研究、自用部署
- **禁止**:任何形式的商业用途,包括但不限于出售、转售、收费代理、商业产品集成
本项目与 OpenAI 无关联。使用者需自行承担风险并遵守 OpenAI 的服务条款。
---
<div align="center">
<sub>Built with Hono + TypeScript + Rust | Powered by Codex Desktop API</sub>
</div>