codex-deepseek-v4-proxy is a lightweight local proxy for Codex CLI and Codex App. It lets you keep one local base_url while routing each request by model:
- DeepSeek V4 models are translated from OpenAI-style Responses API requests into DeepSeek Chat Completions.
- OpenAI models are forwarded natively to OpenAI Responses or Chat Completions.
- URL-heavy DeepSeek runs can use a proxy-side
web_fetchtool instead of getting stuck trying shell HTTP tools.
This lets you use DeepSeek V4 Pro and V4 Flash inside Codex alongside your normal GPT-family workflows.
- DeepSeek Responses → Chat Completions translation
- OpenAI Responses pass-through
- OpenAI Chat Completions pass-through
- Model-based provider routing
- Combined
/v1/modelsmodel catalog - Streaming support on both routing paths
previous_response_idbridging for responses stored by the proxy- Tool-call ordering repair
- Tool-call loop circuit breaker
- Proxy-side
web_fetchfor URL-heavy DeepSeek turns - Zero runtime dependencies
git clone https://github.com/DevvGwardo/codex-deepseek-v4-proxy.git
cd codex-deepseek-v4-proxy
cp env.example .envSet at least one upstream key:
export DEEPSEEK_API_KEY="sk-..."You can also set OPENAI_API_KEY for hybrid routing.
node proxy.mjsThe default listener is:
http://localhost:4000/v1
Option A — Use a profile (recommended alongside native codex login):
model = "gpt-5.4"
[profiles.deepseek]
model = "deepseek-v4-pro"
model_provider = "deepseek_proxy"
[model_providers.deepseek_proxy]
name = "DeepSeek Proxy"
base_url = "http://localhost:4000/v1"
env_key = "DEEPSEEK_API_KEY"Use it like this:
codex # uses default OpenAI model
codex -p deepseek # switches to DeepSeek V4Option B — Route all traffic through the proxy:
model = "deepseek-v4-pro"
model_provider = "deepseek_proxy"
[model_providers.deepseek_proxy]
name = "DeepSeek Proxy"
base_url = "http://localhost:4000/v1"
env_key = "DEEPSEEK_API_KEY"The proxy advertises and routes models from:
DEEPSEEK_MODELSOPENAI_MODELS
Default values:
DEEPSEEK_MODELS=deepseek-v4-pro,deepseek-v4-flash
OPENAI_MODELS=gpt-5.4,gpt-5.4-mini,gpt-5.4-nano,gpt-4o
If a model is not explicitly listed, it can still route to OpenAI by prefix:
OPENAI_MODEL_PREFIXES=gpt-,o1,o3,o4,codex-,chatgpt-
If a request is missing a model or the model is ambiguous, fallback order is:
DEFAULT_PROVIDER, if set and enabled- OpenAI, if enabled
- DeepSeek, if enabled
| Variable | Default | Description |
|---|---|---|
PROXY_PORT |
4000 |
Local listen port |
DEFAULT_PROVIDER |
auto | Fallback provider when model is missing or ambiguous |
DEEPSEEK_API_KEY |
unset | Enables DeepSeek routing |
DEEPSEEK_BASE_URL |
https://api.deepseek.com/v1 |
DeepSeek upstream base URL |
DEEPSEEK_MODELS |
deepseek-v4-pro,deepseek-v4-flash |
Models exposed as DeepSeek |
OPENAI_API_KEY |
unset | Enables OpenAI routing |
OPENAI_BASE_URL |
https://api.openai.com/v1 |
OpenAI upstream base URL |
OPENAI_MODELS |
gpt-5.4,gpt-5.4-mini,gpt-5.4-nano,gpt-4o |
Models exposed as OpenAI |
OPENAI_MODEL_PREFIXES |
gpt-,o1,o3,o4,codex-,chatgpt- |
Prefix heuristics for OpenAI routing |
GITHUB_TOKEN |
auto via gh auth token |
Used for GitHub API fetches in /cop and web_fetch |
| Method | Path | Description |
|---|---|---|
GET |
/health |
Health summary, enabled providers, default provider |
GET |
/v1/models |
Combined model list from enabled providers |
GET |
/cop?url=... |
Quick URL fetch using Jina/raw HTTP |
POST |
/cop |
URL fetch endpoint with method, headers, and body |
POST |
/v1/responses |
Main Codex-compatible endpoint |
POST |
/v1/chat/completions |
Direct Chat Completions endpoint |
When a request routes to DeepSeek, the proxy applies normalization:
systemanddeveloperroles are flattened touser- tool results are reordered so they directly follow their tool calls
- older oversized tool outputs are truncated
- long conversations are trimmed more aggressively
- direct URLs can trigger proxy-side
web_fetch
The proxy can bridge previous_response_id across providers only for responses it has already stored locally.
That means:
- DeepSeek → OpenAI works for stored proxy-managed chains
- OpenAI → DeepSeek works for stored proxy-managed chains
- native Codex/OpenAI outside the proxy → DeepSeek through the proxy is not reconstructable automatically
This repo includes helper scripts so you don't have to remember profile flags.
npm run codex:gpt
npm run codex:deepseek
npm run codex:app:gpt
npm run codex:app:deepseekNotes:
codex:deepseekandcodex:app:deepseekauto-start the local proxy if needed
For non-technical users, the easiest path is a desktop launcher that opens Codex in the chosen mode.
npm run install:launchers:macCreates a Codex DeepSeek Launchers folder on the Desktop with:
Codex GPT.commandCodex DeepSeek.command
powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -File .\scripts\install-windows-launchers.ps1Creates a Desktop folder with:
Codex GPT.lnkCodex DeepSeek.lnk- matching
.cmdand.ps1launchers
curl http://localhost:4000/health
curl http://localhost:4000/v1/modelsExample health response:
{
"status": "ok",
"proxy": "codex-deepseek-v4-proxy",
"providers": ["deepseek", "openai"],
"default_provider": "openai"
}- Node.js 18+
- at least one upstream API key: DeepSeek and/or OpenAI
MIT

