Melious
Integrations

Codex CLI

OpenAI's terminal coding agent, pointed at Melious through a custom TOML provider block

Codex is OpenAI's terminal coding agent — one codex binary from npm, configured through TOML, with a provider system that points it at any backend speaking the OpenAI Responses API. That last part is the whole story here. Codex removed Chat Completions support in February 2026, so wire_api = "responses" is the only value it accepts, and this integration rides on our Responses endpoint rather than the /v1/chat/completions route the rest of this section uses. Both are live, so pointing Codex at us is a provider block and an API key. One rough edge up front: our Responses stream delivers the finished answer in a single event instead of token by token, so Codex prints the reply all at once rather than typing it out — the answer is the same, the theater isn't.

Setup

Install Codex

Codex ships as an npm package wrapping a native binary per platform. Requires Node.js 18 or newer:

npm install -g @openai/codex

Or Homebrew (macOS, Linux):

brew install codex

Windows works natively in PowerShell — no WSL required, though WSL2 is fine if you'd rather the agent's sandbox ran on the Linux side.

Check it landed:

codex --version

Add Melious as a provider

Codex reads ~/.codex/config.toml (or .codex/config.toml inside a trusted project, or wherever CODEX_HOME points). Add a provider block and select it:

~/.codex/config.toml
model = "<MODEL_ID>"
model_provider = "melious"
model_context_window = 131072

[model_providers.melious]                               
name = "Melious"
base_url = "https://api.melious.ai/v1"
env_key = "MELIOUS_API_KEY"
env_key_instructions = "Create a key at melious.ai/account/api/keys"
wire_api = "responses"

Exporting OPENAI_BASE_URL does not redirect Codex at us. Current releases ignore that variable and send traffic to api.openai.com regardless — you get a 401 naming OpenAI's host, which reads like an auth problem and isn't one. The provider block is the only way in.

base_url carries /v1, unlike the Anthropic-shape endpoint that Claude Code uses. No trailing slash.

Don't name the provider openai. That ID is reserved, and Codex refuses to load a config that reuses it — you get model_providers contains reserved built-in provider IDs before the session starts. Any other name is fine.

model_context_window is the window Codex plans against. It ships metadata for OpenAI's own models only, so set this from _meta.context_length on GET /v1/models?include_meta=true. Leave it out and Codex warns that it's falling back to default metadata, then plans against that instead of your model's real window.

Run a session

Codex reads the key from the environment variable named in env_key, once, at startup:

export MELIOUS_API_KEY=sk-mel-<YOUR_API_KEY>
codex

Windows PowerShell:

$env:MELIOUS_API_KEY = "sk-mel-<YOUR_API_KEY>"
codex

Codex prints its wiring in the session header. The provider line is the one to check:

model: <MODEL_ID>
provider: melious
approval: never
sandbox: read-only

If provider says anything else, model_provider didn't take.

Picking a model

Codex defaults to a gpt-5-family model name, and we don't run those. There's no name substitution on the OpenAI-shape endpoints either — only claude-* names map, and only on the Anthropic path — so an unset model fails on the first turn. Set it explicitly and keep it set.

Beyond that, Codex leans hard on long tool-call chains and multi-file edits, so pick something that holds a sequence together without losing the thread. Filter GET /v1/models?include_meta=true on _meta.capabilities.function_calling and _meta.context_length, or browse melious.ai/hub/models.

Append a flavor suffix to the model ID to bias provider selection — <MODEL_ID>:speed, :price, or :eco. See Routing for the decision table.

Profiles

A profile is a whole config file layered over your base one, named <name>.config.toml in your Codex home — not a section inside config.toml:

~/.codex/melious-fast.config.toml
model = "<LIGHTWEIGHT_MODEL_ID>"
model_provider = "melious"
model_context_window = 131072
codex --profile melious-fast
codex -c model_provider="melious" -m "<MODEL_ID>"

There's no --provider flag; -c is how you override any config key from the command line, and it parses values as TOML before falling back to a literal string. Precedence runs CLI flags, then the profile, then project config, then user config.

Non-interactive runs

codex exec is the scripted path — same config, no TUI:

export MELIOUS_API_KEY=sk-mel-<YOUR_API_KEY>
codex exec --skip-git-repo-check "summarize the diff on this branch"
codex exec --json "run the test suite and report failures"

In CI, set MELIOUS_API_KEY in the job environment rather than a dotfile — Codex reads it at launch and never re-reads it. Sandbox policy is a flag: -s read-only (the default), -s workspace-write to let it edit, -s danger-full-access when you've already decided.

What's different

  • Responses, not Chat Completions. Codex is the one tool in this section that talks to /v1/responses. Everything else here uses /v1/chat/completions. Same key, same base URL, different endpoint — and wire_api = "responses" is what selects it.
  • OPENAI_BASE_URL is ignored. Setting it points nowhere useful. The provider block is mandatory, not a nicety.
  • Streaming is coarse. Our Responses stream emits response.created, response.in_progress, and response.completed — no incremental text deltas. Codex renders the whole reply at once. Nothing breaks — the answer lands in one piece instead of unspooling. We'd like to fix this and haven't yet.
  • No environment_impact or billing_cost on the wire. The Responses shape doesn't carry our two extension objects the way Chat Completions does. Usage is still metered and still shows up in your usage dashboard — you can't read it off the response.
  • No Melious CLI support. melious tools install covers Claude Code, OpenCode, Mistral Vibe, and Pi. Codex you wire by hand — OpenAI doesn't accept third-party providers upstream, so this page is the integration.
  • No explicit cache control. Nothing marks a prefix as cacheable. Transparent prefix caching still happens on the provider side and bills at the cheaper cache-read rate. See Models.
  • Sandboxing is Codex's, not ours. sandbox_mode and approval_policy govern what the agent may touch on your machine. Unrelated to routing, but it's what usually refuses an edit.

When it breaks

  • 401 Unauthorized naming api.openai.com — you exported OPENAI_BASE_URL and expected it to redirect. It doesn't. Add the [model_providers.melious] block and set model_provider = "melious".
  • stream disconnected before completion: stream closed before response.completed, after five reconnects — a model ID we don't have. Most often that's an unset model, because Codex then falls back to its own default (a gpt-5-family name). On a streaming request we report the failure as a response.error event, which Codex doesn't treat as terminal, so it retries instead of showing you the message. That's on us. Check the ID with GET /v1/models; a non-streaming call returns the real error, Model not found: <MODEL_ID>.
  • warning: Model metadata for <MODEL_ID> not found — expected, and harmless. Codex ships metadata for OpenAI's own models only. Set model_context_window so its planning is based on your model's real window rather than a fallback.
  • Missing environment variable — Codex reads env_key once, at launch, from the shell that launched it. Export it there, or set it in the CI job environment. Filling in env_key_instructions makes this message tell the reader what to do.
  • model_providers contains reserved built-in provider IDs — your provider is named openai, which Codex reserves. Rename it to melious and point model_provider at the new name.
  • Config edits appear to do nothing — a project-level .codex/config.toml is skipped entirely in untrusted projects. Move the block to ~/.codex/config.toml, trust the project, or pass -c on the command line.
  • 429 mid-session — per-plan token caps, and a long agent session carries a lot of context per turn. Rate limits covers which plan lifts which limit.

Errors and retry patterns: Errors.

On this page