This guide takes Codex Warp from a fresh checkout to a working Codex session with one upstream provider.
You need:
- Codex Desktop or Codex CLI
- Git and a stable Rust toolchain
- CMake and a C/C++ build toolchain
- an API key for an OpenAI-compatible provider
If you use Codex Desktop, the CLI is not required for normal sessions. The smoke test in step 6 is an optional CLI-only verification.
See the developer build guide for exact Linux, macOS, and Windows prerequisites.
git clone https://github.com/jatmn/Codex-warp.git
cd Codex-warp
cargo build --releaseThe resulting binary is:
- Linux and macOS:
target/release/codex-warp - Windows:
target\release\codex-warp.exe
Keep the repository's codex-warp.toml and configs/ directory available when
you run the binary. The runtime configuration is not embedded in the
executable.
Codex Warp includes ready-made profiles. Export the matching API key and pass
the profile with --config.
OpenRouter:
export OPENROUTER_API_KEY="..."
./target/release/codex-warp --config configs/openrouter.tomlMoonshot Kimi Code:
export KIMICODE_API_KEY="..."
./target/release/codex-warp --config configs/moonshot-kimicode.tomlXiaomi Token Plan:
export XIAOMI_TOKEN_PLAN_API_KEY="..."
./target/release/codex-warp --config configs/xiaomi-token-plan.tomlOn Windows PowerShell, set an environment variable for the current terminal like this:
$env:OPENROUTER_API_KEY = "..."
.\target\release\codex-warp.exe --config configs\openrouter.tomlFor another gateway, copy
configs/openai-compatible.toml, then set
its base_url, api_key_env, and endpoint behavior. Provider credentials
belong in Codex Warp, not in Codex's local-provider entry.
Warp starts on http://127.0.0.1:8787 by default. Leave it running and use a
second terminal for the remaining steps.
Confirm that the process is healthy:
curl -sS http://127.0.0.1:8787/health
# okThen inspect the model catalog:
curl -sS http://127.0.0.1:8787/v1/modelsInvoke-RestMethod http://127.0.0.1:8787/health
# ok
Invoke-RestMethod http://127.0.0.1:8787/v1/modelsIf the health check works but the model request fails, check the API key name, the selected profile, and the terminal running Warp. For more diagnostic output, set the debug environment variable before restarting Warp with the selected profile:
export RUST_LOG=codex_warp=debug$env:RUST_LOG = "codex_warp=debug"Codex reads personal settings from ~/.codex/config.toml. Add the following
provider definition:
model_provider = "codex-warp"
[model_providers.codex-warp]
name = "Codex Warp"
base_url = "http://127.0.0.1:8787/v1"
wire_api = "responses"
[model_providers.codex-warp.auth]
command = "printf"
args = ["codex-warp-local"]
refresh_interval_ms = 0The command prints a nonsecret placeholder bearer token for the local proxy.
Warp owns the real upstream credential through the provider profile's
api_key_env. Do not add the upstream key, model_catalog_json, or a
Codex-side env_key to this entry.
Warp's default hide_codex_builtin_models = true keeps Codex's bundled models
out of the gateway-only model picker. Change that setting in codex-warp.toml
if you want a mixed catalog.
Windows does not provide printf by default. Use PowerShell to print the same
fixed, nonsecret placeholder as the Linux and macOS configuration:
[model_providers.codex-warp.auth]
command = "powershell"
args = ["-NoProfile", "-Command", "Write-Output codex-warp-local"]
refresh_interval_ms = 0Restart Codex after changing its configuration. In Codex Desktop, fully quit
and reopen the app so its managed app-server daemon rebuilds the model manager,
then select one of the models returned by Warp's /v1/models endpoint. With
Codex CLI, select a returned model and start a session normally:
codexCodex sends Responses-shaped requests to the local proxy. Warp selects the configured gateway, applies provider and model-family transforms, and forwards the adapted request upstream.
This optional check requires Codex CLI and ignores the rest of your user
configuration. Desktop-only users can skip it after completing step 5. Replace
MODEL_ID_FROM_CATALOG with a model ID returned by /v1/models:
codex exec \
--ignore-user-config \
--skip-git-repo-check \
-C /tmp \
-m MODEL_ID_FROM_CATALOG \
-c 'model_provider="codex-warp"' \
-c 'model_providers.codex-warp.name="Codex Warp"' \
-c 'model_providers.codex-warp.base_url="http://127.0.0.1:8787/v1"' \
-c 'model_providers.codex-warp.wire_api="responses"' \
-c 'model_providers.codex-warp.auth.command="printf"' \
-c 'model_providers.codex-warp.auth.args=["codex-warp-local"]' \
-c 'model_providers.codex-warp.auth.refresh_interval_ms=0' \
-s read-only \
--output-last-message /tmp/codex-warp-hello.txt \
'Respond with exactly one word: hello'Expected result:
cat /tmp/codex-warp-hello.txt
# hello$outputPath = Join-Path $env:TEMP "codex-warp-hello.txt"
$smokeHome = Join-Path $env:TEMP ("codex-warp-smoke-" + [guid]::NewGuid())
New-Item -ItemType Directory -Path $smokeHome | Out-Null
@'
model_provider = "codex-warp"
[model_providers.codex-warp]
name = "Codex Warp"
base_url = "http://127.0.0.1:8787/v1"
wire_api = "responses"
[model_providers.codex-warp.auth]
command = "powershell"
args = ["-NoProfile", "-Command", "Write-Output codex-warp-local"]
refresh_interval_ms = 0
'@ | Set-Content -Path (Join-Path $smokeHome "config.toml") -Encoding Ascii
$previousCodexHome = $env:CODEX_HOME
try {
$env:CODEX_HOME = $smokeHome
codex exec `
--skip-git-repo-check `
-C $env:TEMP `
-m MODEL_ID_FROM_CATALOG `
-s read-only `
--output-last-message $outputPath `
'Respond with exactly one word: hello'
} finally {
$env:CODEX_HOME = $previousCodexHome
Remove-Item -Recurse -Force $smokeHome
}
Get-Content $outputPath
# helloSee live testing for provider-specific checks and failure diagnosis.
- Load multiple gateways: configuration guide
- Add a custom gateway: provider catalogs
- Tune model capabilities: model-family catalogs
- Enable the management UI: Web UI and analytics
- Configure tool-call rules: tool approval policy