Codex ships with OpenAI models by default, but it doesn’t lock you into them. The CLI has a built-in OSS mode for local runtimes like Ollama and LM Studio, plus a custom provider system that points the agent at any compatible endpoint you define in a TOML file. That means you can run gpt-oss on your laptop, drive Codex with a hosted DeepSeek or Qwen API, or switch between providers per project.
This guide walks through the whole setup: what OSS mode does, the exact config keys, per-model recipes, and the tradeoffs you accept when you swap out OpenAI’s models. Everything here comes from the official Codex advanced configuration docs. Where the docs are ambiguous, I say so instead of guessing.
One note before we start. Once your model is running inside Codex, the model is only half the workflow. The other half is verifying the APIs your agent builds and calls. That’s where Apidog fits, and we’ll cover the pairing near the end.
TL;DR
Codex OSS mode is a CLI feature. Run codex --oss and Codex talks to a local Ollama or LM Studio server instead of OpenAI. Set oss_provider = "ollama" in ~/.codex/config.toml to make that the default, and pass -m <model> to pick which local model runs. For hosted open-source models (DeepSeek, Qwen, GLM via their APIs), define a [model_providers.<id>] block with a base_url and env_key, then select it with model_provider. The catch: the current config reference lists responses as the only supported wire_api value, so your endpoint needs to speak the Responses API protocol.
What OSS mode is
OSS mode is Codex’s shortcut for running against local open-source model servers. The docs describe two supported local providers:
- Ollama, the popular local model runtime
- LM Studio, the desktop app with a built-in local server
You activate it with the --oss flag. From the Codex developer commands reference:
--oss: Use a local open source model provider. Codex uses--local-provider, your configuredoss_provider, or prompts you to choose between LM Studio and Ollama.
There’s a companion flag, --local-provider, which takes lmstudio or ollama and overrides your default for a single run. If you set neither a flag nor a config default, the interactive CLI prompts you to pick. The non-interactive codex exec doesn’t prompt; it exits with an error. So for scripts and CI, always set the provider explicitly.
An honesty note on surfaces: the documentation covers OSS mode and custom providers under the CLI’s config.toml system. The IDE extension and Codex cloud aren’t mentioned as supporting local providers anywhere in the config docs. [VERIFY: whether the Codex IDE extension reads model_providers from config.toml the same way the CLI does; the docs don’t state it either way.] Treat this as a CLI workflow until OpenAI documents otherwise.
Why run an open-source model inside Codex
Fair question, since Codex is OpenAI’s own agent. A few real reasons:
- Cost control. Local inference through Ollama costs nothing per token. If you’re burning through usage limits on long agent sessions, a local model handles the grunt work while you save the hosted calls for hard problems.
- Privacy and air-gapped work. Some codebases can’t leave the machine. A local Kimi, GLM, or gpt-oss model keeps every token on your hardware. Our guide to running Kimi K3 locally covers what that takes in practice.
- Model preference. Open-weight models have closed most of the coding gap. DeepSeek and Qwen’s hosted APIs undercut OpenAI pricing while scoring within range on coding benchmarks, and you may simply like how a specific model writes code.
- One agent harness, many models. Codex’s terminal UX, sandboxing, and approval flow are good. Provider config lets you keep that harness and swap the brain.
Where the config lives
Codex stores state under CODEX_HOME, which defaults to ~/.codex. Your user-level configuration is ~/.codex/config.toml, and a repo can carry project-level overrides in .codex/config.toml. Everything below goes in one of those two files.
Quick start: Codex with Ollama
The fastest path to an open-source model in Codex is Ollama.
- Install Ollama from ollama.com and start it. It serves an OpenAI-compatible API on port 11434.
- Pull a model. OpenAI’s own open-weight release is a natural first pick; the gpt-oss library page has the 20b and 120b variants. We’ve covered the standalone setup in how to run gpt-oss using Ollama.
ollama pull gpt-oss:20b
- Run Codex in OSS mode and name the model:
codex --oss -m gpt-oss:20b
The -m/--model flag overrides the configured model, and combined with --oss it selects which local model runs. For non-interactive use:
codex exec --oss --local-provider ollama -m gpt-oss:20b "add input validation to the signup route"
- Make it the default so you can drop the flags. In
~/.codex/config.toml:
# Default local provider used with `--oss`
oss_provider = "ollama" # or "lmstudio"
That’s the whole feature for local models. No API key, no custom provider block. LM Studio works the same way: load a model in the app, start its local server, and run codex --oss --local-provider lmstudio. See lmstudio.ai for the server setup.
Custom providers: point Codex at any compatible endpoint
OSS mode covers Ollama and LM Studio. For everything else, hosted DeepSeek or Qwen APIs, a proxy, a vLLM server on your LAN, Codex has custom model providers. The docs define a provider as “how Codex connects to a model (base URL, wire API, authentication, and optional HTTP headers).”
The pattern from the official docs:
model = "gpt-5.6-terra"
model_provider = "proxy"
[model_providers.proxy]
name = "OpenAI using LLM proxy"
base_url = "http://proxy.example.com"
env_key = "OPENAI_API_KEY"
[model_providers.local_ollama]
name = "Ollama"
base_url = "http://localhost:11434/v1"
[model_providers.mistral]
name = "Mistral"
base_url = "https://api.mistral.ai/v1"
env_key = "MISTRAL_API_KEY"
The keys that matter:
| Key | What it does |
|---|---|
model_provider |
Which provider id Codex uses (default: openai) |
model |
The model name sent to that provider |
name |
Display name for the provider |
base_url |
API base URL |
env_key |
Environment variable holding the API key |
wire_api |
Protocol used by the provider |
query_params |
Extra query parameters appended to requests |
http_headers / env_http_headers |
Static headers, or headers filled from env vars |
Per-provider network tuning is available too: request_max_retries (default 4), stream_max_retries (default 5), and stream_idle_timeout_ms (default 300000). Slow local hardware benefits from a longer idle timeout, since a 120b model on a laptop can sit quiet for a while between tokens.
Two rules the docs call out directly. First, the ids openai, ollama, and lmstudio are reserved; you can’t override built-in providers. To change the base URL of the built-in OpenAI provider, set openai_base_url instead of creating [model_providers.openai]. Second, and this one shapes everything: the configuration reference states that for wire_api, “responses is the only supported value, and it is the default when omitted.”
That’s a real constraint. Earlier Codex versions accepted wire_api = "chat" for Chat Completions endpoints, and the models overview page still says you can point Codex at providers supporting “either the Chat Completions or Responses APIs.” The reference and the overview disagree. [VERIFY: whether wire_api = "chat" still works in the current CLI release; the config reference says responses-only, the models page implies chat still works. Test against a chat-only endpoint before publishing.] If responses-only holds, your provider needs a Responses API endpoint, which most OpenAI-compatible servers now expose but some hosted APIs still don’t.
Model-by-model recipes
Each recipe below is a config block plus the command to run. Set the API key env var before launching.
DeepSeek (hosted API)
DeepSeek added Responses API support alongside its V4 Flash beta, which is exactly what Codex’s wire protocol wants. We covered that rollout in DeepSeek V4 Flash, the Responses API, and Codex.
model = "deepseek-chat"
model_provider = "deepseek"
[model_providers.deepseek]
name = "DeepSeek"
base_url = "https://api.deepseek.com"
env_key = "DEEPSEEK_API_KEY"
export DEEPSEEK_API_KEY="sk-..."
codex
Check the DeepSeek API docs for the current model ids. [VERIFY: exact base_url path DeepSeek documents for Responses-protocol access; the /v1 chat path may differ from the Responses path.]
Qwen (hosted via Model Studio)
Alibaba’s Model Studio (DashScope) exposes an OpenAI-compatible mode for the Qwen 3.8 family. The compatible-mode endpoint has historically been Chat Completions shaped. [VERIFY: whether DashScope’s compatible mode now serves the Responses protocol; if not, this recipe depends on the wire_api = "chat" question above.]
model = "qwen3.8-max"
model_provider = "qwen"
[model_providers.qwen]
name = "Qwen via Model Studio"
base_url = "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
env_key = "DASHSCOPE_API_KEY"
Our Qwen 3.8 API guide covers keys, model ids, and pricing for the hosted route.
Kimi, GLM, and other open weights (local via Ollama)
Anything you can pull into Ollama works through plain OSS mode, no provider block needed:
ollama pull <model>
codex --oss -m <model>
That covers GLM and Qwen open weights, plus Kimi K3 if your hardware survives it (the K3 weights are 594 GB at MXFP4, so most people should read run Kimi K3 locally before trying). For mid-size machines, gpt-oss:20b or a quantized Qwen coder build is the practical choice.
Self-hosted vLLM or a LAN server
A vLLM or similar OpenAI-compatible server on another machine is a custom provider, not OSS mode:
model_provider = "lan_vllm"
[model_providers.lan_vllm]
name = "vLLM on the workstation"
base_url = "http://192.168.1.50:8000/v1"
env_key = "VLLM_API_KEY"
Profiles: switch brains per task
You don’t have to pick one setup. Codex profiles are separate TOML files at ~/.codex/<profile-name>.config.toml, layered on top of your base config when you pass --profile. A local-model profile looks like this:
# ~/.codex/oss-local.config.toml
oss_provider = "ollama"
model = "gpt-oss:20b"
codex --profile oss-local
codex exec --profile oss-local "write unit tests for utils/dates.ts"
Keep your default config on OpenAI models for hard refactors and spin up --profile oss-local for lint fixes, test scaffolding, and doc passes. One-off overrides work without a profile too: codex -c model='"deepseek-chat"' -c model_provider='"deepseek"'.
Tradeoffs versus OpenAI models
Be honest with yourself about what you’re trading:
- Capability. gpt-oss:20b is not gpt-5.6-terra. Local models fail more often on long multi-file edits, and agent loops amplify model weakness because every step builds on the last.
- Speed. Hosted APIs stream fast. A big local model on consumer hardware can be slow enough to change how you work.
- Tooling fidelity. Codex’s prompts and tool-calling are tuned for OpenAI models. Open-source models vary in how reliably they emit tool calls, and the responses-only wire protocol narrows which endpoints qualify at all.
- Support surface. OSS mode is a documented CLI path, but third-party providers are on you: model ids, rate limits, and protocol quirks are between you and the vendor.
The pragmatic split: local or cheap hosted models for high-volume low-stakes work, frontier models for the tasks where a failed run costs you an afternoon.
Verify the APIs your agent touches
Whatever model runs inside Codex, the output is usually code that calls or defines APIs, and open-source models hallucinate endpoints and schemas more often than frontier ones. Catch that at the API layer instead of in production.
Apidog covers that side of the workflow. Point the Apidog MCP server at your project and your Codex agent can read the real API spec while it writes code, instead of inventing field names. Then use Apidog CLI inside Codex to let the agent run your test scenarios from the terminal after each change: it edits, it tests, you review a passing diff. That loop matters more, not less, when a smaller model writes the code. Download Apidog to wire it up; the CLI and MCP server work with any model you’ve configured.
Troubleshooting
codex execerrors immediately in OSS mode. You didn’t set a provider. Non-interactive runs never prompt, so pass--local-provider ollamaor setoss_providerin config.- Connection refused on port 11434. Ollama isn’t running, or it’s bound to a different address. Start the app or
ollama serve, and confirm withcurl http://localhost:11434/v1/models. - 404 or protocol errors from a hosted provider. Wrong
base_urlshape, or the endpoint doesn’t speak the Responses protocol. Check whether the vendor documents a Responses-compatible path. - Auth failures.
env_keynames an environment variable; Codex reads the key from your shell environment at launch. Export it in the same shell, and remember launchd or CI shells may not load your dotfiles. - Streams die mid-generation on a slow local model. Raise
stream_idle_timeout_msandstream_max_retriesin the provider block. - Config edits ignored. Check for a project-level
.codex/config.tomloverriding your user config, and remember profiles layer on top of both.
FAQ
Does Codex OSS mode work in the IDE extension or Codex cloud?
The docs document OSS mode and custom providers as part of the CLI’s config system. IDE or cloud support for local providers isn’t documented, so treat this as a CLI feature. [VERIFY before relying on IDE support.]
Which models work best with Codex in OSS mode?
Whatever Ollama or LM Studio can serve on your hardware. gpt-oss:20b is the low-friction default. Strong open-weight coding options include the Qwen 3.8 family and GLM; for the giant models like Kimi K3, check the hardware math in our local Kimi K3 guide first.
Can I use OpenRouter or another aggregator with Codex?
Any aggregator exposing a compatible endpoint fits the [model_providers.<id>] pattern: set base_url and env_key, then select it with model_provider. The open question is protocol: the config reference lists responses as the only supported wire_api, so confirm your aggregator serves the Responses API.
Do I need an OpenAI API key to run Codex with an open-source model?
No key is needed for OSS mode with a local Ollama or LM Studio server. Custom hosted providers use their own key through env_key. You still sign in to Codex itself as usual for anything that touches OpenAI’s services.
Run the setup that fits the task. A local gpt-oss for the cheap loops, DeepSeek or Qwen when you want hosted speed at lower cost, and OpenAI’s frontier models when the problem is hard. Codex’s config makes all three one flag apart, and with Apidog handling verification on the API side, the model becomes a swappable part instead of a commitment.



