Cursor models inside Codex

By Daniel Ensminger

5 min read

Codex has real remote control. Cursor has the models I actually want. A local OpenAI-compatible router lets me keep both without giving up either.

I want Codex’s remote control and Cursor’s model menu at the same time. Cursor still won’t give you the kind of remote coding Codex ships with. Codex still won’t give you Composer, Cursor Grok, or the rest of the Cursor catalog as first-class options.

So I stopped waiting for either product to finish the other’s job and built a shim.

The split that actually matters

People talk about “which agent is better” as if the model and the harness are the same product. They aren’t.

Codex is a strong coding harness: tools, sandbox, approvals, mid-turn steering, and — critically — proper remote sessions. That last part is why I keep coming back. I can leave a machine somewhere else and still drive real work through Codex.

Cursor is where a lot of the interesting model surface lives for me day to day: Composer, Cursor Grok, Claude variants, Gemini, the GPT-5.6 Cursor-only lines. Great models. Not the remote control story I want.

The useful move is not “switch tools.” It’s keep Codex as the agent, and treat Cursor as a model backend.

What the router does

I run a tiny local OpenAI-compatible server that Codex thinks is just another custom model provider. Under the hood it speaks the Responses API Codex already understands, then shells out to Cursor’s agent CLI in ask mode.

  1. 01

    Codex hits a local Responses provider

  2. 02

    Router maps model reasoning and Fast to a Cursor agent id

  3. 03

    agent --mode ask returns text only

  4. 04

    Codex keeps tools sandbox and remote control

A few design rules made this usable instead of cute:

  1. Codex owns the tools. The router strips tool schemas from the prompt. Cursor never gets exec_command or the rest of the Codex toolbox. If you flatten those schemas into text and tell the model “don’t use tools,” you burn tokens and get weird tiny replies.
  2. Echo the catalog base slug, never the resolved variant. If Codex asks for cursor-grok-4.5 with reasoning.effort = high, the agent run can be cursor-grok-4.5-high, but the response model field stays cursor-grok-4.5. Echo the concrete id and the app rewrites your session model, then the reasoning picker falls apart.
  3. Reasoning and Fast are selectors, not model names. Cursor exposes effort and speed as separate agent ids. Codex expects one model with supported_reasoning_levels and speed tiers. The catalog sync does that translation so the picker shows “Cursor Grok 4.5,” not “Cursor Grok 4.5 High Fast.”
  4. Disposable workspace. Point agent at an empty temp directory. Codex already has the real repo and sandbox. Giving Cursor your $HOME as the workspace just spins up language servers you don’t need.

Streaming matters too. Waiting for the full agent run and faking one SSE delta feels dead. Partial stream-json output mapped into response.output_text.delta events is what makes the Codex UI feel like a normal turn.

Two remotes, not one clever hack

I briefly tried routing some GPT ids through my ChatGPT / Codex subscription from inside the same router. That was the wrong abstraction. Codex does not do per-model providers. One session, one provider, one auth story.

The clean setup is two Codex homes:

Remote – CodexRemote – Other
AuthChatGPT / Codex subLocal router API key
ModelsStock OpenAI catalogLean Cursor catalog
JobSubscription OpenAI modelsComposer, Grok, Claude via Cursor, etc.

Same Codex app UX. Different CODEX_HOME. No heuristic that guesses whether gpt-5.5 should bill ChatGPT while gpt-5.6-sol stays on Cursor.

The catalog is half the product

Getting inference working was the easy part. Making the Codex model picker stop lying took longer.

Cursor’s raw list looks like a flat pile of effort variants. Codex wants one row per model family, then separate Reasoning and Fast controls. So the sync script:

  • Groups effort / fast variants under base slugs
  • Keeps GPT-5.5 plus the GPT-5.6 lines, and only the newest non-OpenAI families
  • Prefer thinking variants where they exist, without putting “Thinking” in the display name
  • Forces branded names (GPT-5.5, not bare 5.5)
  • Writes model_catalog_json and refreshes models_cache.json, because the Codex app-server loads the catalog at startup and will happily keep a stale cache forever

If the Desktop picker still shows forty obsolete rows, the router is probably fine — the app just never reloaded the catalog. Fully quit Codex, not just the window.

What this is not

This is not “Cursor remote control.” Cursor still isn’t driving the remote session. Codex is. The router is a model adapter with a Responses façade.

It is also not free dual billing magic. Cursor models bill through Cursor. OpenAI subscription models stay on the Codex / ChatGPT side via the other home. Keep those boundaries explicit and you avoid a week of auth debugging.

Why bother

Because the interesting product question in mid-2026 is rarely “which chat box do I open?” It’s which harness do I trust for long-running remote work, and which models do I want inside it?

Codex currently wins the remote / harness side for me. Cursor currently wins a big chunk of the model side. A local router is a boring piece of glue — and boring glue is exactly what you want when two tools each own half of a workflow you refuse to give up.

👍
❤️
🔥
👏
🤯

Join 2,000 readers and get infrequent updates on new projects.

+8.7K

By subscribing you consent to email updates. You can unsubscribe anytime. See our Privacy Policy.