💡 让 Codex CLI 通过单一 base_url 访问 DeepSeek、小米 MiMo 与 OpenAI 的全功能本地代理 + Web 管理界面 + 桌面应用
English · 简体中文 · 日本語 · 한국어 · Español
Codex CLI 使用 OpenAI Responses API,而 DeepSeek 和 MiMo 使用 Chat Completions API。
Codex Assistant 在两者之间双向转换 — 包含流式 SSE、工具调用与思考模式回合 — 让你在不修改 Codex 客户端的前提下,使用任意支持的模型。
新增功能(v1.2.7):
- 🔐 机器码加密 — API Key 加密改用硬件机器码,与访问密钥独立,修改访问密钥不再影响已保存的 Key
- 🧩 前端模块化 —
ui-frontend.js拆分为 6 个独立模块(common/dashboard/providers/env/backup/settings),便于维护 - 🌓 系统主题跟随 — 支持浅色/深色/跟随系统三种模式
- 📡 版本检查优化 — 浏览器直连 GitHub API,hosts 修改用户也能正常检测更新
- 🔧 deepseek-v4-pro 上下文 — 更新为 1M tokens
- 🐛 多项 Bug 修复 — API Key 丢失问题彻底解决、加密机制重构、警告文案修正
- 从 Releases 页面下载
CodexAssistant.zip - 解压到任意纯英文目录!纯英文目录!纯英文目录(无需安装)
- 双击
CodexAssistant.exe启动 - 首次启动会自动生成访问密钥,并在浏览器中打开管理界面
💡 桌面应用使用 Edge
--app模式(无边框窗口),体积远小于 Electron 方案。
git clone https://github.com/muyun1314/codex-assistant.git
cd codex-assistant
# 双击运行(Windows)
启动UI.cmd启动后自动打开浏览器,访问 http://127.0.0.1:8788/(端口自动检测)。
管理界面提供四个主要页面:
| 功能 | 说明 |
|---|---|
| 代理状态 | 实时显示代理运行/停止状态,一键启停 |
| 运行时间 | 代理启动后自动计时,停止后自动清零 |
| 当前模型 | 显示已应用的模型,无模型时提示配置 |
| 提供商状态 | 显示已配置的提供商数量 |
| Codex 控制 | 启动/停止 Codex 或 Codex++ |
| 版本信息 | 显示当前版本,一键检查更新 |
点击侧边栏底部🌙/☀️按钮切换浅色/深色模式,选择会保存在 localStorage 中。
| 操作 | 说明 |
|---|---|
| 添加提供商 | 填写名称、Base URL、API Key、协议类型、模型列表 |
| 编辑提供商 | 修改任意字段,API Key 以加密形式存储 |
| 删除提供商 | 确认后删除,同时清除关联的模型配置 |
| 应用配置到 Codex | 将当前选中的模型写入 ~/.codex/config.toml |
| 测试连接 | 调用 /v1/models 验证 Base URL 和 API Key 是否有效 |
| 导入/导出 | 跨设备迁移配置(详见下方「配置迁移」) |
⚠️ 安全提示:导出配置时,API Key 以加密态保存在 JSON 文件中(通过CAENC:base64...格式)。
导出文件包含PROXY_AUTH_KEY明文(用于解密迁移),请妥善保管,切勿分享给不可信的第三方。
如怀疑有泄露风险,请在各提供商管理平台作废当前 API Key 并重新生成。
在界面中直接修改代理的环境变量,无需手动编辑 .env 文件:
| 变量 | 说明 |
|---|---|
PROXY_PORT |
代理监听端口(默认 4000) |
DEFAULT_PROVIDER |
模型未知时的回退提供商 |
LOG_LEVEL |
日志级别(silent/error/warn/info/debug) |
UPSTREAM_TIMEOUT_MS |
上游请求超时(默认 120000ms) |
STORE_TTL_MS |
响应存储条目 TTL |
STORE_MAX |
响应存储 LRU 容量 |
MAX_CONSECUTIVE_TOOL_CALLS |
工具调用熔断器阈值 |
修改后点击「保存环境配置」即可生效(部分变量需重启代理)。
- 每次代理启动生成独立日志文件,命名格式:
proxy-YYYY-MM-DD-HH-MM-SS.log - 按保留天数自动清理过期日志
- 界面内可直接查看最近日志,支持按级别过滤
- 在「提供商管理」页面点击「导出配置」
- 确认弹出的安全提示(配置包含敏感信息)
- 浏览器自动下载
codex-assistant-config-YYYY-MM-DD.json
导出内容包含:
- 所有提供商配置(API Key 为加密态
CAENC:...) PROXY_AUTH_KEY明文(用于导入时解密 Key)- 模型列表
- 环境变量配置(
PROXY_PORT、LOG_LEVEL等)
- 在目标机器上点击「导入配置」
- 选择之前导出的 JSON 文件
- 系统自动:
- 用导出文件中的
PROXY_AUTH_KEY解密所有 API Key - 用本机的
PROXY_AUTH_KEY重新加密(确保密钥隔离) - 写入
user/provider-configs.json - 恢复模型列表和环境变量
- 用导出文件中的
⚠️ 导入后,若某些提供商的 API Key 无法解密(如导出文件被篡改),界面会提示「以下提供商需重新填写 API Key」。
所有 API Key 在磁盘上均以加密形式存储:
存储格式:CAENC:<base64>
加密算法:AES-256-GCM
密钥派生:PBKDF2(100,000 次迭代,SHA-256)
主密钥:Windows MachineGuid(硬件指纹),独立于 PROXY_AUTH_KEY
即使 provider-configs.json 被泄露,攻击者也必须在同一台机器上才能解密 API Key。
- 加密密钥基于机器硬件指纹自动生成,无需手动配置
- 更换机器 / 主板 / 系统后已保存的 Key 需要重新输入
- PROXY_AUTH_KEY 仅用作 Codex 通信的访问密钥,不再参与加密
- 导出配置仅用于跨设备查看配置结构,不能用于迁移加密 Key
系统每次启动 Web UI 时自动检查 GitHub Releases 是否有新版本:
- 点击侧边栏底部「检查版本更新」
- 若有新版本,点击「一键更新」
- 系统自动下载、解压、替换文件并重启
版本信息保存在 version.json 中:
{
"version": "1.1.0",
"build": 1,
"releasedAt": "2026-05-29",
"changelog": "Initial release with auto-update support"
}┌─────────────────┐ Responses API ┌──────────────────┐
│ Codex CLI │────────────────────▶│ Codex Assistant │
│ │ Authorization: │ :4000 (代理) │
└─────────────────┘ Bearer <key> └────────┬─────────┘
│ 按模型名路由
┌───────────────┼──────────────────┐
│ │ │
▼ ▼ ▼
┌────────────────┐ ┌────────────────┐ ┌──────────────┐
│ DeepSeek V4 │ │ 小米 MiMo │ │ OpenAI │
│ Chat Completions │ │ Chat Completions│ │ Responses │
└────────────────┘ └────────────────┘ └──────────────┘
Web 管理界面(端口 8788)
┌─────────────────────────────────────────────┐
│ Dashboard │ 提供商 │ 环境配置 │ 运行日志 │
└─────────────────────────────────────────────┘
如果不使用 Web 管理界面,可手动配置:
mkdir -p user
cp env.example user/.env编辑 user/.env:
# 必填:生成代理访问密钥
PROXY_AUTH_KEY=sk-proxy-local-$(openssl rand -hex 24)
# 可选:DeepSeek
DEEPSEEK_API_KEY=sk-...
DEEPSEEK_BASE_URL=https://api.deepseek.com/v1
DEEPSEEK_MODELS=deepseek-v4-pro,deepseek-v4-flash
# 可选:小米 MiMo
MIMO_API_KEY=...
MIMO_BASE_URL=https://token-plan-cn.xiaomimimo.com/v1
MIMO_MODELS=mimo-v2.5-pro
# 可选:OpenAI
OPENAI_API_KEY=sk-...
OPENAI_BASE_URL=https://api.openai.com/v1node --env-file=user/.env proxy.mjs编辑 ~/.codex/config.toml:
model = "deepseek-v4-flash"
model_provider = "local_proxy"
[model_providers.local_proxy]
name = "local_proxy"
base_url = "http://127.0.0.1:4000/v1"
wire_api = "responses"
requires_openai_auth = true设置 Codex 鉴权密钥(~/.codex/auth.json):
{ "OPENAI_API_KEY": "<同 user/.env 中的 PROXY_AUTH_KEY>" }运行 codex — 完成。
每个请求按以下优先级根据模型名进行路由:
- 精确匹配 — 模型出现在
DEEPSEEK_MODELS/MIMO_MODELS/OPENAI_MODELS - 前缀启发 — 模型以
OPENAI_MODEL_PREFIXES中任一项开头 → OpenAI - 名称提示 — 模型包含
deepseek或mimo→ 对应提供商 - 回退 —
DEFAULT_PROVIDER,再退回到第一个已配置密钥的提供商
Codex 发送 none | minimal | low | medium | high | xhigh。各上游接受的格式不同:
| Codex effort | DeepSeek | MiMo | OpenAI |
|---|---|---|---|
none |
thinking: {type: "disabled"} |
thinking: {type: "disabled"} |
字段移除 |
minimal |
reasoning_effort: "low" |
reasoning_effort: "low" |
透传 |
low / medium / high |
透传 | 透传 | 透传 |
xhigh |
reasoning_effort: "xhigh" |
限制为 high |
限制为 high |
注意: DeepSeek 会静默忽略
enable_thinking: false。本代理改用thinking: {type: "disabled"}。
| 方法 | 路径 | 鉴权 | 说明 |
|---|---|---|---|
GET |
/health |
否 | 健康检查 |
GET |
/v1/models |
是 | 合并后的模型列表 |
POST |
/v1/responses |
是 | Codex CLI 主端点(Responses API) |
POST |
/v1/chat/completions |
是 | 直接 Chat Completions 透传 |
POST |
/v1/images/generations |
是 | 图像生成(DALL-E,需配置 OPENAI_API_KEY) |
GET |
/cop?url=... |
是 | URL 抓取(Jina Reader / 原生 HTTP) |
POST |
/cop |
是 | 自定义方法/请求头/请求体的 URL 抓取 |
| 方法 | 路径 | 说明 |
|---|---|---|
GET |
/ |
管理界面 HTML |
GET |
/ui-frontend.css |
界面样式 |
GET |
/ui-frontend.js |
界面逻辑 |
GET |
/api/providers |
获取所有提供商配置 |
POST |
/api/providers |
保存提供商配置 |
DELETE |
/api/providers/:name |
删除提供商 |
GET |
/api/env |
获取环境变量 |
POST |
/api/env |
保存环境变量 |
POST |
/api/proxy/start |
启动代理 |
POST |
/api/proxy/stop |
停止代理 |
GET |
/api/proxy/status |
获取代理状态 |
GET |
/api/codex/start-app |
启动 Codex CLI |
GET |
/api/codex/start-codexpp |
启动 Codex++ |
POST |
/api/codex/stop |
停止 Codex |
GET |
/api/export-config |
导出配置 |
POST |
/api/import-config |
导入配置 |
GET |
/api/check-update |
检查版本更新 |
POST |
/api/apply-update |
执行更新 |
./scripts/smoke.sh # 默认使用 localhost:4000
./scripts/smoke.sh http://host:4000 # 自定义目标
MODEL=mimo-v2.5-pro ./scripts/smoke.sh # 测试不同模型执行 30 项检查,覆盖端点、入参形态、鉴权门、流式完成、思考强度翻译、工具调用回合与供应商锁定。
--env-file 在 Node 20 才引入。旧版本请使用:
set -a && source .env && set +a && node proxy.mjsnohup node --env-file=.env proxy.mjs > /tmp/codex-assistant.log 2>&1 &在 .env 中使用 PROXY_KEYS 创建按供应商隔离的入站密钥:
PROXY_KEYS=sk-deepseek-aaa:deepseek,sk-mimo-bbb:mimo,sk-all-ccc:*然后创建多个 Codex 配置,切换时更改 config.toml 中的 model_provider。
将 MODEL_CATALOG_PATH 指向 Codex 使用的同一份 JSON 文件(config.toml 中的 model_catalog_json),自动保持模型列表同步:
MODEL_CATALOG_PATH=~/.codex/proxy-models.jsonCC Switch 是一款热门桌面应用,可一键管理和切换多种 AI CLI 工具(Claude Code、Codex、Gemini CLI 等)的供应商配置。
-
打开 CC Switch → Codex 选项卡 → 添加供应商
-
填写供应商信息:
字段 值 名称 Codex Assistant(或你喜欢的标签)API Key 你的 PROXY_AUTH_KEY(来自user/.env)Base URL http://127.0.0.1:4000/v1 -
点击 启用 — CC Switch 会自动写入
~/.codex/auth.json并更新config.toml。
| 症状 | 原因 | 解决方案 |
|---|---|---|
EADDRINUSE :4000 |
端口被占用 | 更改 PROXY_PORT 在 .env 中;代理会优先尝试 4000,若被自己占用则杀旧进程重用,若被其他软件占用则从 4001 逐个尝试 |
401 Unauthorized |
鉴权密钥不匹配 | 确认 ~/.codex/auth.json 中的 OPENAI_API_KEY 与 user/.env 中的 PROXY_AUTH_KEY 一致 |
代理异常退出 |
端口冲突或启动失败 | 查看 log/ 目录中的代理日志 |
运行时间显示 -- |
代理未启动或计时器未初始化 | 启动代理后等待 5 秒,运行时间会自动显示 |
| 导出配置后无法导入 | PROXY_AUTH_KEY 不匹配 |
确保导入时目标机器的 PROXY_AUTH_KEY 正确;或手动重新填写 API Key |
| 任务未完成就中断 | web_fetch 死循环检测触发 | 已修复:v1.1.0+ 中 isStuckLoop 不再中断循环,改为继续用缓存结果;MAX_FETCH_LOOPS 已从 5 提升到 8 |
codex-assistant/
├── proxy.mjs # 代理核心(路由、协议转换、鉴权、流处理)
├── ui-server.mjs # Web UI 后端(提供商 CRUD、进程管理、静态服务)
├── ui-frontend.html # 管理界面 HTML
├── ui-frontend.css # 管理界面样式(浅色/深色主题)
├── ui-frontend.js # 管理界面前端逻辑(单体源文件)
├── common.js # 前端公共模块(状态/主题/API/导航)
├── dashboard.js # 仪表盘模块(代理控制/模型选择)
├── providers.js # 提供商管理模块(CRUD/模型管理)
├── env.js # 环境配置模块(环境变量/日志)
├── backup.js # 备份管理模块(Codex备份/Codexpp路径)
├── settings.js # 设置模块(版本检查/关闭行为/初始化)
├── src/
│ ├── shared.mjs # 共用工具函数
│ ├── protocol.mjs # 协议翻译(Responses ↔ Chat Completions)
│ ├── crypto-store.mjs # API Key 加密存储(AES-256-GCM)
│ ├── web-fetch.mjs # 内置 web_fetch 工具实现
│ └── updater.mjs # 自动更新逻辑
├── user/ # 用户专属配置(不提交到 Git)
│ ├── .env # 环境变量(代理端口、日志级别等)
│ ├── provider-configs.json # 提供商配置(API Key 加密存储)
│ └── proxy-models.json # 模型清单(可选)
├── dist/ # 桌面应用分发文件
│ └── CodexAssistant.exe # C# 启动器(Edge --app 模式)
├── scripts/
│ └── smoke.sh # 冒烟测试脚本
├── tests/
│ └── protocol.test.mjs # 协议转换单元测试
├── env.example # 环境变量模板
├── proxy-models.example.json # 模型清单模板
├── package.json # Node.js 项目配置
├── version.json # 版本信息
└── 启动UI.cmd # Windows 启动脚本
- API Key 保护:所有 API Key 在磁盘上以加密形式存储(
CAENC:base64...),使用 AES-256-GCM + PBKDF2 加密。 - 入站鉴权:所有
/v1/*端点均受PROXY_AUTH_KEY保护(唯一例外:/health)。 - CSRF 保护:Web UI 的所有非 GET 请求均需携带
X-CSRF-Token请求头。 - SSRF 防护:新的上游 URL 均经过
validateProviderUrl()校验。 - 配置导出警告:导出配置时系统会弹窗警告,提示用户妥善保管包含敏感信息的 JSON 文件。
- 用户配置隔离:所有用户专属配置均存放在
user/文件夹中,该文件夹已加入.gitignore。
- Node.js 18+
- macOS / Linux / Windows
- 至少一个上游 API 密钥(DeepSeek、MiMo 或 OpenAI)
# 安装依赖(实际上零依赖,此步骤可选)
npm install
# 运行代理(手动模式)
node --env-file=user/.env proxy.mjs
# 运行 Web UI(开发模式)
npm start
# 然后访问 http://127.0.0.1:8788/
# 运行测试
npm test本项目遵循严格的代码审查标准,详见 CODE_REVIEW.md。
关键规则:
proxy.mjs和ui-server.mjs只能使用var(ES5 语法兼容)- 所有 API Key 必须通过
crypto-store.mjs加密 - 所有
try-catch的 catch 块不得为空 - 新功能优先放在
src/独立模块中,避免proxy.mjs进一步膨胀
- ✨ API Key 加密改用机器码(Windows MachineGuid),与访问密钥解耦
- ✨ 前端模块化拆分:ui-frontend.js → 6 个独立模块(common/dashboard/providers/env/backup/settings)
- ✨ 主题支持跟随系统(浅色/深色/系统三种模式)
- ✨ 版本检查增加浏览器直连降级(hosts 修改用户也能检测更新)
- ✨ deepseek-v4-pro 上下文窗口更新为 1M tokens
- 🔧 修复 syncCodexConfig 双向同步导致 API Key 丢失
- 🔧 修复更新检查在 hosts 网络环境下静默失败
- 🔧 修复加密相关警告文案过时问题
- 🔧 修复模块文件未列入 Tauri bundle 导致开发版启动失败
- ✨ 新增 Web 可视化管理界面
- ✨ 新增桌面应用版(C# 启动器 + Edge --app 模式)
- ✨ 新增 API Key 加密存储(AES-256-GCM + PBKDF2)
- ✨ 新增配置导入/导出功能
- ✨ 新增自动更新检测
- ✨ 新增浅色/深色主题切换
- 🔧 修复端口占用处理逻辑(优先 4000,智能识别进程归属)
- 🔧 修复代理停止后运行时间继续走的问题
- 🔧 修复手动停止代理显示「代理异常退出」的问题
- 🔧 修复导出配置包含明文
PROXY_AUTH_KEY的安全问题 - 🔧 修复 web_fetch 死循环检测导致任务中断的问题
- 🔧
MAX_FETCH_LOOPS从 5 提升到 8
MIT — 详见 LICENSE。
- Codex CLI — OpenAI 官方 CLI 工具
- CC Switch — AI CLI 工具供应商管理桌面应用
- Jina Reader — URL 内容抓取服务
用 ❤️ 制作 by muyun1314