Back to blog

Run Codex CLI with Any Model: OpenRouter, DeepSeek, Ollama

Oct 14, 2026AutoJev

Codex speaks the OpenAI Responses API. Learn how to run it on OpenRouter, DeepSeek, Ollama or any OpenAI-compatible model with a local gateway that converts Responses to Chat Completions, and what gets written to ~/.codex/config.toml.

Codex CLI is OpenAI's terminal coding agent. It is fast, scriptable and good at multi-step edits — and it is built around one protocol: the OpenAI Responses API. That is a problem if the model you want to use only offers Chat Completions, which is still the most common format across DeepSeek, OpenRouter, Ollama and self-hosted servers such as vLLM.

This guide walks through running Codex on any of those models with AutoJev, a free, open-source desktop app that runs one local gateway at http://127.0.0.1:9527/v1 and converts between protocols. By the end you will have:

  • Codex connected to a local gateway with one click.
  • A model catalog in Codex listing every model and route you selected.
  • OpenRouter, DeepSeek and a local Ollama model available side by side.
  • An understanding of which Responses features survive conversion and which do not.

The protocol gap

Codex sends POST /v1/responses requests. Responses has its own shape for input items, tool definitions (including custom tools), tool call outputs and streaming events. Chat Completions represents the same conversation as a list of messages with tool_calls, and streams deltas differently.

A model that only speaks Chat Completions cannot answer a Responses request directly. Something has to translate the request on the way in and the streaming events on the way out — while keeping tool call IDs stable, because Codex depends on them to match a tool result to the call that produced it.

That is the job AutoJev does:

Codex ──Responses──▶ AutoJev (127.0.0.1:9527/v1) ──▶ Chat Completions upstream
                                                ──▶ Responses upstream (native)
                                                ──▶ Anthropic Messages upstream

If a model's upstream already speaks Responses, the request passes through natively. Otherwise AutoJev converts it, calls the provider's /v1/chat/completions (or /v1/messages), and converts the response back into Responses events.

Step 1: Install AutoJev and add providers

Download AutoJev from the download page (macOS, Windows x64, Linux x64). Open it; the gateway starts on port 9527.

Under Providers, add the ones you want. The presets fill in the base URL:

PresetBase URL
OpenRouterhttps://openrouter.ai/api
DeepSeekhttps://api.deepseek.com
Ollamahttp://127.0.0.1:11434
OpenAIhttps://api.openai.com/v1

For anything else — Kimi (Moonshot), GLM (Zhipu), Qwen (DashScope), SiliconFlow, vLLM, LM Studio — use OpenAI Compatible or Anthropic Compatible with the provider's URL. A local Ollama server usually needs no key. Click the provider test for each one.

If your providers already live in CC Switch or Termany, use the import option instead. AutoJev reads ~/.cc-switch/cc-switch.db or ~/.termany/termany.db and de-duplicates by endpoint.

Step 2: Add models with the right API type

Under Models, add one entry per model. The most important field is API type, and it describes the upstream, not Codex:

ProviderExample model IDAPI type
OpenRouterqwen/qwen3-coder-flashchat_completions
OpenRouteranthropic/claude-sonnet-4chat_completions
DeepSeekdeepseek-chatchat_completions
Ollamaa model name from ollama listchat_completions
OpenAIa model that supports Responsesresponses

A common mistake is setting every model to responses because Codex uses Responses. Don't — AutoJev needs to know the upstream format so it can convert correctly.

Fill in input, output and cache prices per 1M tokens so Usage can estimate cost. Then run a speed test: AutoJev sends three short streaming requests per model and records first-content latency and output tokens per second. Scheduled tests are on by default (every 30 minutes) and keep measurements fresh for speed-based routing.

Step 3: Create a route (optional but recommended)

You can connect Codex to a single model, but a route lets you change models later without touching Codex's configuration. Under Routes, create for example:

  • fast — intelligent selection, preference Lower latency. AutoJev picks from recent speed measurements locally, without calling Jev.
  • cheap — intelligent selection, preference Lower cost. AutoJev picks the cheapest candidate that meets the capability requirements. Turn on Prefer local models to favour Ollama when it qualifies.
  • quality — intelligent selection, preference Higher quality. AutoJev asks the OpenRouter Jev decision model to choose, sending only routing metadata, never your conversation.

Routes appear to agents as autojev/fast, autojev/cheap and autojev/quality. Single models appear as <provider-id>/<model-id>, for example deepseek/deepseek-chat.

Step 4: Connect Codex

Open Agents. AutoJev detects Codex at ~/.codex/config.toml. Select one or more models and routes, choose the default, and click Connect. AutoJev backs up the original file first, then writes:

toml
model = "autojev/fast"
model_provider = "autojev"
model_catalog_json = "/Users/you/.codex/autojev-models.json"
web_search = "disabled"
 
[model_providers.autojev]
name = "AutoJev"
base_url = "http://127.0.0.1:9527/v1"
wire_api = "responses"
 
[model_providers.autojev.http_headers]
x-autojev-agent = "codex"

What each line does:

  • model is the default model or route Codex starts with.
  • model_provider = "autojev" and the [model_providers.autojev] table tell Codex to send requests to the local gateway using the Responses wire format.
  • x-autojev-agent = "codex" labels requests so Logs and Usage can break them down by agent.
  • web_search = "disabled" turns off Codex's hosted web search, because hosted tools cannot be converted to Chat Completions or Messages models.
  • model_catalog_json points to a second file AutoJev writes, ~/.codex/autojev-models.json.

The catalog lists every model and route you selected, so you can switch between them from inside Codex. An abbreviated entry looks like this:

json
{
  "models": [
    {
      "slug": "autojev/fast",
      "display_name": "Fast",
      "description": "AutoJev · fast",
      "visibility": "list",
      "supported_in_api": true,
      "input_modalities": ["text", "image"],
      "supports_search_tool": false,
      "apply_patch_tool_type": "freeform"
    }
  ]
}

Other settings in your config.toml are preserved. Restart Codex if it was running, then:

bash
codex "Add input validation to the signup handler and write a test for it"

Open Logs in AutoJev to see the agent, the route ID, the model and provider that actually answered, tokens, first-byte and total time, and estimated cost. The detail view lists every upstream attempt.

What survives conversion

AutoJev converts in all six directions among Responses, Chat Completions and Anthropic Messages. For Codex on a Chat Completions model, the important parts are covered:

  • System instructions and full conversation history.
  • Function tools, tool choice, tool calls and tool outputs with stable call IDs.
  • Responses custom tools — translated into a function with a single string input argument, and decoded back into custom tool input on the way out. Grammar constraints are not enforced by the upstream function API.
  • Streaming text and streaming tool arguments, including UTF-8 characters split across network chunks.
  • Images as URLs or base64.
  • Structured output formats between Responses and Chat Completions.
  • Token usage and protocol-shaped errors. Interrupted or malformed upstream streams are reported as errors, not as successful completions.

What does not

Some Responses features have no Chat Completions equivalent. AutoJev rejects them clearly instead of pretending:

  • previous_response_id and conversation. Cross-protocol conversion needs the full history in each request.
  • Hosted tools such as web search — hence web_search = "disabled".
  • Audio and file content, namespaced tool definitions and multiple choices.
  • Reasoning state. Provider-specific thinking blocks, encrypted reasoning and signatures are dropped. Reasoning controls are not translated. Models that require their private reasoning state to accompany later tool results may not complete a full cross-protocol agent loop; use their native API for that.

And the general rule: conversion cannot add tools, vision, reasoning or context capacity to a model that lacks them. For Codex, choose models that are good at tool calling.

Running Codex on a local Ollama model

Local models are a good fit for privacy-sensitive repos or for working offline from paid APIs:

  1. Start Ollama and pull a coding model.
  2. In AutoJev, enable the Ollama provider (http://127.0.0.1:11434) and add the model with API type chat_completions.
  3. Either connect Codex directly to ollama/<model>, or add the model to a route with Prefer local models turned on and a cloud model as a second candidate.

With the route approach, failover covers you: if the local server is down or returns 5xx before any output starts, AutoJev tries the next candidate. Defaults are up to 4 attempts and a 30-second cooldown. A stream that has already started is never replayed, so Codex will not run the same tool action twice.

Running Codex on OpenRouter or DeepSeek

The steps are the same; only the provider changes. Two tips:

  • Use routes to compare. Put an OpenRouter model and DeepSeek in a load-balancing route with equal weights. New sessions are spread across both, and session affinity keeps each session on one model. Compare results in Usage, broken down by model.
  • Watch cost. Set prices on each model and pick a Cost baseline in the route to estimate savings against a reference model. The LLM cost calculator helps with rough planning.

Disconnecting

Click Disconnect on Codex in Agents. AutoJev restores the backed-up config.toml, keeping later edits that do not conflict with its fields; if the catalog file did not exist before, it is removed. Stop and restore configurations does this for every connected agent at once, and so does Quit AutoJev (restore agents) in the tray.

Troubleshooting

Codex says a feature is unsupported. Check whether the request used previous_response_id, a hosted tool or file content. Switch that session to a model whose API type is responses, or start a fresh session.

Requests go to the wrong provider. Open the request in Logs. The detail view shows the route, every upstream attempt and, for intelligent routes, the decision reason.

Speed routing keeps using load balancing. Speed routing needs recent measurements — up to five samples from the last 30 minutes. Run a speed test or leave scheduled tests on.

Gateway paused. Requests return HTTP 404 with gateway_paused while the service is paused. Resume it in AutoJev.

Summary

Codex only speaks Responses, but your models don't have to. AutoJev writes a small, reversible block to ~/.codex/config.toml, adds a model catalog at ~/.codex/autojev-models.json, converts Responses to Chat Completions or Messages on the fly, and lets routes decide which model handles each request.

Keep reading: