---
> **声明**:本项目由个人独立开发和维护,初衷是解决自己的需求。我有自己的注册机,根本不缺 token,所以这个项目不是为了"薅"谁的资源而存在的。
>
> 我自愿开源、自愿维护。该有的功能我会加,有 bug 我也会第一时间修。但我没有义务为任何单个用户提供定制服务。
>
> 觉得代码垃圾?可以不用。觉得你写得更好?欢迎提 PR 加入贡献者。Issue 区用来反馈 bug 和建议,不是用来提需求、催更新、或指点江山的。
---
**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 等任何兼容上述协议的客户端中直接使用 Codex 编程模型。
只需一个 ChatGPT 账号(或接入第三方 API 中转站),配合本代理即可在本地搭建一个专属的 AI 编程助手网关。
## 🚀 快速开始
> **前置条件**:你需要一个 ChatGPT 账号(免费账号即可)。如果还没有,先去 [chat.openai.com](https://chat.openai.com) 注册一个。
### 方式一:桌面应用(推荐新手)
下载 → 安装 → 打开就能用。
**下载安装包** — 打开 [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` 即可看到控制面板。
### 方式二:Docker 部署
```bash
mkdir codex-proxy && cd codex-proxy
curl -O https://raw.githubusercontent.com/icebear0828/codex-proxy/master/docker-compose.yml
curl -O https://raw.githubusercontent.com/icebear0828/codex-proxy/master/.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-配置)。
### 方式三:源码运行
```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` 登录。
### 验证
登录后打开控制面板 `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.4","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` 支持(所有协议)
- **第三方 API Keys** — 支持 OpenAI / Anthropic / Gemini / OpenRouter / 自定义 OpenAI-compatible Provider,并按模型路由直通上游。
### 🔐 账号管理与智能轮换
- **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 登录门
### 🌐 代理池
- **Per-Account 代理路由** — 为不同账号配置不同的上游代理
- **四种分配模式** — Global Default / Direct / Auto / 指定代理
- **健康检查** — 定时 + 手动,通过 ipify 获取出口 IP 和延迟
- **不可达自动标记** — 代理不可达时自动排除
### 🛡️ 反检测与协议伪装
- **Rust Native TLS** — 内置 reqwest + rustls native addon,TLS 指纹与真实 Codex Desktop 精确一致(依赖版本锁定)
- **完整请求头** — `originator`、`User-Agent`、`x-openai-internal-codex-residency`、`x-codex-turn-state`、`x-client-request-id` 等头按真实客户端行为发送
- **Cookie 持久化** — 自动捕获和回放 Cloudflare Cookie
- **指纹自动更新** — 轮询 Codex Desktop 更新源,自动同步 `app_version` 和 `build_number`
## 🏗️ 技术架构
```
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)
```
## 📦 可用模型
| 模型 ID | 推理等级 | 当前上下文 | 最大上下文 | 最大输出 | 输出 | 说明 |
|---------|---------|------------|------------|----------|------|------|
| `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` 切换推理等级。例如:`gpt-5.4-fast`、`gpt-5.4-high-fast`。图像模型(`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/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.5",
"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(4K UHD)/ `auto`,最长边 ≤ 3840 px,像素预算约 8 MP)、`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`。详见 [API.md](./API.md#image_generation-tool)。
事件流里 `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`。
## 🔗 客户端接入
> 所有客户端的 API Key 均从控制面板 (`http://localhost:8080`) 获取。模型名填具体 ID(默认 `gpt-5.4`)或任意 [可用模型](#-可用模型) ID。
### Claude Code (CLI)
```bash
export ANTHROPIC_BASE_URL=http://localhost:8080
export ANTHROPIC_API_KEY=your-api-key
# 切换模型: export ANTHROPIC_MODEL=gpt-5.4 / gpt-5.4-fast / gpt-5.4-mini ...
claude
```
> 控制面板的 **Anthropic SDK Setup** 卡片可一键复制环境变量(含 Opus / Sonnet / Haiku 层级模型配置)。
>
> 推荐模型:Opus → `gpt-5.5`,Sonnet → `gpt-5.4`,Haiku → `gpt-5.3-codex`。
>
> ⚠️ 配置不生效?请参考 **[Claude Code 配置避坑指南](.github/guides/claude-code-setup.md)**(AUTH_TOKEN 劫持、API Key 黑名单等常见问题)。
### Codex CLI
`~/.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.4"
model_provider = "proxy_codex"
```
> 💡 也可以改用环境变量:把 `[model_providers.proxy_codex.http_headers]` 这两行删掉,换成 `env_key = "PROXY_API_KEY"`,然后 `export PROXY_API_KEY=your-api-key && codex`。需要避免密钥落到 config 文件(多人共享 / 开源仓库)时用这个。
### Claude Desktop
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.5
claude-sonnet-4-6: gpt-5.4
claude-haiku-4-5: gpt-5.3-codex
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 证书。
### Codex Desktop (官方应用)
官方客户端与 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.4"
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;登录会话仍可能直接走官方上游。
### Claude for VSCode / JetBrains
打开 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"
}
```
### Cursor
1. 打开 Settings → Models
2. 选择 OpenAI API
3. 设置 **Base URL**: `http://localhost:8080/v1`
4. 设置 **API Key**: 你的 API Key
5. 添加模型名 `gpt-5.4`(或其他模型 ID)
### Windsurf
1. 打开 Settings → AI Provider
2. 选择 **OpenAI Compatible**
3. **API Base URL**: `http://localhost:8080/v1`
4. **API Key**: 你的 API Key
5. **Model**: `gpt-5.4`
### Cline (VSCode 扩展)
1. 打开 Cline 侧边栏 → 设置齿轮
2. **API Provider**: 选择 OpenAI Compatible
3. **Base URL**: `http://localhost:8080/v1`
4. **API Key**: 你的 API Key
5. **Model ID**: `gpt-5.4`
### Continue (VSCode 扩展)
`~/.continue/config.json`:
```json
{
"models": [{
"title": "Codex",
"provider": "openai",
"model": "gpt-5.4",
"apiBase": "http://localhost:8080/v1",
"apiKey": "your-api-key"
}]
}
```
### aider
```bash
aider --openai-api-base http://localhost:8080/v1 \
--openai-api-key your-api-key \
--model openai/gpt-5.4
```
或设置环境变量:
```bash
export OPENAI_API_BASE=http://localhost:8080/v1
export OPENAI_API_KEY=your-api-key
aider --model openai/gpt-5.4
```
### Cherry Studio
1. 设置 → 模型服务 → 添加
2. **类型**: OpenAI
3. **API 地址**: `http://localhost:8080/v1`
4. **API Key**: 你的 API Key
5. 添加模型 `gpt-5.4`
### Ollama 兼容客户端
在 Dashboard → Settings → **Ollama Bridge** 中启用后,可使用 Ollama 默认地址:
| 设置项 | 值 |
|--------|-----|
| Base URL | `http://localhost:11434` |
| API Key | 不需要,Bridge 内部会使用 Codex Proxy 的密钥访问主服务 |
| Model | `gpt-5.4`(或其他模型 ID) |
```bash
curl http://localhost:11434/api/tags
curl http://localhost:11434/api/chat \
-H "Content-Type: application/json" \
-d '{"model":"gpt-5.4","messages":[{"role":"user","content":"Hello!"}],"stream":true}'
```
> Ollama API 本身没有鉴权。默认仅监听 `127.0.0.1`,不建议暴露到公网或未信任的局域网。
### 通用 OpenAI 兼容客户端
任何支持自定义 OpenAI API Base 的客户端均可接入:
| 设置项 | 值 |
|--------|-----|
| Base URL | `http://localhost:8080/v1` |
| API Key | 控制面板获取 |
| Model | `gpt-5.4`(或其他模型 ID) |
SDK 代码示例(Python / Node.js)
**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.4", 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.4", messages: [{ role: "user", content: "Hello!" }], stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content || "");
}
```
## ⚙️ 配置说明
> **重要**:不要直接修改 `config/default.yaml`,该文件会在版本更新时被覆盖。自定义配置请通过 Dashboard 设置面板修改(自动保存到 `data/local.yaml`),或手动创建 `data/local.yaml` 写入需要覆盖的字段。`data/` 目录不受更新影响。
### 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` | `app_version`, `build_number`, `chromium_version` | 模拟的 Codex Desktop 版本 |
| `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 插件 |
### 模型映射
`model.aliases` 用来把客户端里的模型名映射成真实上游模型,适合 Claude Desktop / Cursor / Continue 等客户端只能选择固定模型名、或你希望暴露更短别名的场景。
也可以直接在 Dashboard → Settings → **模型映射** 中添加 / 删除映射。保存后会写入 `data/local.yaml` 并热加载到后端,不需要修改 `config/default.yaml`。
```yaml
model:
aliases:
claude-opus-4-7: gpt-5.5
sonnet-local: gpt-5.4
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` 路径:
| 系统 | 路径 |
|------|------|
| macOS | `~/Library/Application Support/Codex Proxy/data/local.yaml` |
| Windows | `%APPDATA%/Codex Proxy/data/local.yaml` |
| Linux | `~/.config/Codex Proxy/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` |
## 📡 API 端点
点击展开主要端点列表
**协议端点**
| 端点 | 方法 | 说明 |
|------|------|------|
| `/v1/chat/completions` | POST | OpenAI 格式聊天补全 |
| `/v1/responses` | POST | Codex Responses API 直通 |
| `/v1/responses/compact` | POST | Codex compact 响应代理 |
| `/v1/messages` | POST | Anthropic 格式聊天补全 |
| `/v1/models` | GET | 可用模型列表 |
| `/v1/models/catalog` | GET | Dashboard 使用的完整模型目录 |
| `/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**
| 端点 | 方法 | 说明 |
|------|------|------|
| `/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 |
## 📋 系统要求
- **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)。
## ☕ 赞赏 & 交流
觉得有帮助?请作者喝杯咖啡,或加入微信交流群获取使用帮助。二维码见 [页面顶部](#)。
## 🙏 贡献致谢
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、模型兼容和错误观测等能力的迭代。
## ⭐ Star History
[](https://star-history.com/#icebear0828/codex-proxy&Date)
## 📄 许可协议
本项目采用 **非商业许可 (Non-Commercial)**:
- **允许**:个人学习、研究、自用部署
- **禁止**:任何形式的商业用途,包括但不限于出售、转售、收费代理、商业产品集成
本项目与 OpenAI 无关联。使用者需自行承担风险并遵守 OpenAI 的服务条款。
---
Built with Hono + TypeScript + Rust | Powered by Codex Desktop API