{"slug": "the-quest-for-local-model-routing-inside-claude-code-starts-with-a-codex-gateway", "title": "The Quest for Local Model Routing Inside Claude Code Starts with a Codex Gateway Plugin", "summary": "As of August 2026, roughly 80% of the work handed off by Eigenwise's developer runs on a GPT model, all from inside Claude Code, thanks to a new MIT-licensed plugin called model-gateway that routes requests to ChatGPT, Grok, and Anthropic models on localhost. The plugin, available in the Eigenwise Toolshed marketplace, fronts three providers at once, sets itself up on first run, and splits traffic so Claude requests go straight to Anthropic with the user's own credential, preserving prompt caching. The developer built it to avoid switching to Codex CLI, Grok Build, or Gemini CLI, which would require moving twenty-odd plugins, hooks, skills, and MCP servers.", "body_md": "# The Quest for Local Model Routing Inside Claude Code Starts with a Codex Gateway Plugin\n\nI wanted model routing inside *Claude Code*. **That meant a gateway first**, and it meant making the gateway something you install once and then forget exists.\n\nEvery piece of work should go to whichever model actually suits it: mechanical edits to something cheap, real engineering judgment to a mid tier, the genuinely hard stuff to the expensive one, *Opus* over the top to plan and review. **That only works if one client can reach every one of those models.** *Claude Code* couldn’t reach the GPT ones, so I was choosing from **a third of my actual options**.\n\nSo I built the piece that fixed it, and then split it out into its own plugin on the off chance it was useful to anyone else: **model-gateway** (MIT, in my [Eigenwise Toolshed](https://github.com/Eigenwise/eigenwise-toolshed) marketplace). It runs **entirely on localhost**, it fronts **three providers at once**, and it puts the models from my *ChatGPT* and *Grok* subscriptions **right in Claude Code’s /model picker**, next to\n\n*Opus*. It sets itself up on first run, so\n\n**there’s basically nothing to configure**.\n\nAs of August 2026, **roughly 80% of the work I hand off** runs on a GPT model, going by some stats I pulled off my own setup. **All of it from inside Claude Code.**\n\nThe reasonable question is why I don’t just use *Codex CLI* for that four-fifths. I did for a while, and *Grok Build*, and *Gemini CLI* before Google retired it in June. **They’re all genuinely good now.** The router isn’t the only thing that would have to move, though: twenty-odd plugins, the hooks that fire on every single turn, the skills, the MCP servers. **Moving models takes a minute. Moving everything built around them takes a week I’m not going to spend.**\n\n## What It Actually Does\n\nThis started when I found `claude-code-proxy`\n\n, an open-source Rust project that does the *ChatGPT* OAuth and **translates the Anthropic Messages API to OpenAI’s Codex backend**. It’s MIT, it works, and it had commits land the same day I wrote this.\n\nRunning it yourself is another matter. You go find the right release for your platform, drop it somewhere sensible, keep it alive, notice when it goes stale, and point *Claude Code* at it by hand. Fine once, tedious every time after. **I wanted something you install and then never think about again**, so the plugin owns that whole job: it fetches the binary, **checks its sha256 before anything runs**, and **keeps itself updated** without you going near it.\n\nThe plugin also adds a small router that sits in front. *Claude Code* points at it through `ANTHROPIC_BASE_URL`\n\n, and it makes three different decisions:\n\n```\nClaude Code ──▶ shim (127.0.0.1:18764)\n                  │\n                  ├── claude-gpt-*  ──▶ claude-code-proxy (:18765) ──▶ Codex\n                  ├── claude-grok-* ──▶ cli-chat-proxy.grok.com\n                  └── everything else ──▶ api.anthropic.com\n```\n\nThat third arrow is the one that matters. Point a plain proxy at *Claude Code* and it takes over your endpoint outright, so everything you do goes through it. **This splits the traffic instead.** Claude requests go straight to Anthropic **carrying your own credential**, with the original request bytes forwarded untouched so **prompt caching still keys on them**. Your *claude.ai* auth never travels toward the proxy at all. So *Opus* and GPT-5.6 **live in the same session**, and I can switch between them mid-conversation without either one noticing.\n\nThe Grok path is my own code: **about 450 lines translating Anthropic Messages to xAI’s Responses API**, with its own streaming transformer. It reads the token the *Grok* CLI already stored, so there’s **no second login**.\n\n## The Trick Is a Prefix, and So Is the Price\n\n*Claude Code* can populate `/model`\n\nfrom a gateway’s `/v1/models`\n\n, and the [documentation](https://code.claude.com/docs/en/llm-gateway-protocol) is precise about the catch: it ”**ignores entries whose id doesn’t begin with claude or anthropic**.”\n\nSo the router lies a little. It advertises GPT-5.6 Terra as ** claude-gpt-5.6-terra** and strips the prefix back off on the way through. Routing keys off\n\n**the family segment after the prefix**, which is why\n\n`claude-opus-5`\n\nand `claude-gpt-5.6-sol`\n\nshare a namespace without colliding. Discovery is off by default and needs v2.1.129 or newer, so it’s **one environment variable and a restart**.\n\n**That prefix is not free.** As of *Claude Code* 2.1.207, the context-window resolver never reads a discovered model’s advertised `max_input_tokens`\n\nfor a `claude-`\n\nprefixed id. **It hardwires 200,000.** And the escape hatch that would let you override it is gated behind the id *not* starting with `claude-`\n\n.\n\nRead that twice, because I had to. **The prefix is what gets these models into the picker, and the same prefix caps them at 200k.** My router advertises 370,000 tokens on the Codex rows and *Claude Code* throws every one of them away. **You cannot have the picker without the cap**, and I can’t fix it from my side.\n\n## Where Claude Code Is Still Ahead\n\nThe honest answer here is less flattering than the one I’d have given six months ago.\n\nAs of August 2026, *Codex CLI* has hooks, plugins, marketplaces, skills, subagents, MCP, an SDK, and an enterprise policy layer. *Grok Build* shipped AGENTS.md, plugins, hooks, skills and **parallel subagents in worktrees** while still in an early beta. `SKILL.md`\n\nis now an [open cross-vendor standard](https://agentskills.io) that OpenAI builds on directly. On a few things *Codex* is straight-up ahead: **hook trust is bound to the hook’s hash**, so editing one re-triggers review; subagents pin their own sandbox mode; MCP tools get per-tool approval. **The categories converged, and anyone telling you otherwise hasn’t opened the docs this year.**\n\nWhat’s left is depth, and **OpenAI documents the gap themselves**. *Codex* defines five hook handler types. Its [hooks reference](https://learn.chatgpt.com/docs/hooks) says `prompt`\n\nand `agent`\n\nhandlers ”**are parsed but skipped**.” **One of the five actually executes.** The same page lists `async`\n\n, `suppressOutput`\n\n, `updatedMCPToolOutput`\n\nand `permissionDecision: \"ask\"`\n\nas parsed and unimplemented too.\n\n*Claude Code* runs all five, across **roughly 32 lifecycle events against Codex’s 12**, and the extra ones aren’t padding: `FileChanged`\n\n, `ConfigChange`\n\n, `WorktreeCreate`\n\n, `TaskCompleted`\n\n, `PostToolBatch`\n\nare **exactly what an infrastructure plugin needs to exist at all**. A *Claude Code* plugin can also ship LSP servers, background monitors, and **executables that join the Bash tool’s PATH** while it’s enabled. **That’s the difference between a surface that exists and a surface that’s finished**, and it’s the whole reason I stay.\n\n## What I Actually Run\n\nThe picking is automatic. *Sidequest*, my own board and router, classifies each piece of work by what it actually is, and **the category decides which model runs it and at what effort**. The table above is its routing profile, and it’s what I look at when I want to know where my work actually went.\n\n**Those splits are my own stats off my own machine**, so read them as one person’s setup rather than a benchmark. They come out of a separate Toolshed plugin that handles observability and hands you a **Grafana dashboard** of where your work and your tokens are actually going. Both of those sit in the same marketplace as the gateway, they’re worth a look if any of this appeals to you, and **I’ll have a lot more to say about them shortly**.\n\nSo the tiers do the work and I mostly stay out of it. **Terra is my default.** *Sol* takes the hard escalations, *Luna* does the mechanical work, and *Opus* barely executes anything at all: it plans, reviews, and gatekeeps the audits. *Fable* I’ve reached for maybe a dozen times, for the rare thing that stalls *Opus* and *Sol* outright.\n\nThere’s an objection to this that I think is right. **Use a second model purely as a cheap executor downstream of a Claude plan and you mostly just get a slower Claude.** The real value of a second model is that it **disagrees** with the first one.\n\nThat’s why *Opus* stays in the review seat. On one project, **three separate audit passes over the same renderer** all ran on *Opus*, checking work that *Sol* had produced. **The cheaper tokens are the least interesting part of this**, and if the savings were the only reason, I’d have stopped bothering months ago.\n\nGrok, honestly: it works and **I’ve barely touched it**. One 17-minute session in late July. I built the backend because I wanted the option sitting there, not because it’s part of my day.\n\n## The Trade-Off\n\nThe only real cost is *Remote Control*. It only activates when `ANTHROPIC_BASE_URL`\n\npoints at the actual Anthropic host, and the gateway needs that variable **pointed at the router instead**. There’s a compatibility mode that gets *Remote Control* back through a hosts-file entry, and it **costs you the dropdown rows**: you type `/model claude-gpt-5.6-terra`\n\nby hand and it still routes fine. On Linux and macOS the port it needs is root-reserved, so it **quietly stays in normal mode** rather than asking.\n\nThe rest, briefly. **Codex and Grok are not equally supported**: the Codex path has a context sentry, error normalization, a compaction retry guard and a WebSocket retry, and **the Grok path has none of them**. Plan mode is stripped on Codex models because GPT models call it spuriously and an approved exit **downgrades your permission mode**. Codex returns no reasoning stream. Compaction on Codex was unreliable enough that it needed **a dedicated buffered retry** to work at all.\n\nAnd it’s one more thing to maintain, sitting downstream of **OpenAI’s client fingerprinting**, which they’ve tightened before. The blast radius is bounded, at least: **Claude models never break**, and one command puts everything back to stock.\n\n## It’s Modular, and It Wires Itself In\n\nOn its own, the gateway is **just the picker rows**. Install it by itself and that’s exactly what you get, and honestly for a lot of people that’s the whole use case: your other subscription, in the client you already like, no ceremony.\n\nThe reason it ends up **near zero-config** is Workbench, which is the piece of the Toolshed that owns setup. It notices the gateway isn’t configured and offers to run it, and it **swaps binaries by rename** so an update never makes you close a session. Then it restarts the thing and tells you what state it actually ended in rather than assuming. **The only step it can’t do for you is the ChatGPT browser sign-in**, because that’s a browser sign-in.\n\nThe wiring gets written once, globally, and it covers **every project and every executor worktree**. That second half is the part that makes routing work at all: a dispatched subagent running off in its own git worktree **reaches the GPT models exactly the same way my main session does**, with no per-project setup and nothing to remember.\n\n*Sidequest* sits on top of all of it, and **the gateway is what makes any of that possible**. It’s the reason it exists at all.\n\nNone of these require each other, which was the point of splitting them up. **The gateway on its own just gives you a better model picker**, and for most people that’s the whole thing. The routing layer above it is mine, and you can ignore it entirely.\n\n## Where to Get It\n\nFor the whole setup wired for you, three commands inside *Claude Code*, in this order:\n\n```\n/plugin marketplace add Eigenwise/eigenwise-toolshed\n/plugin install workbench@eigenwise-toolshed --scope user\n/workbench:init-workspace\n```\n\nThe third one is where the gateway actually happens. Workbench notices it isn’t configured and offers to do it, so **say yes**, sign in to *ChatGPT* when the browser opens, and restart the session.\n\n**If the picker rows are all you want, skip Workbench entirely.** Two commands, and install at user scope so the keepalive hook follows you everywhere:\n\n```\n/plugin marketplace add Eigenwise/eigenwise-toolshed\n/plugin install model-gateway@eigenwise-toolshed --scope user\n```\n\nYour next session notices it isn’t set up and offers to finish: the download, the sign-in, and **the wiring written once into ~/.claude/settings.json** for every project you’ll ever open. Restart after that. If you’d rather drive it by hand, the\n\n[setup guide](https://eigenwise.github.io/eigenwise-toolshed/getting-started/model-gateway/)has the raw commands.\n\nEither way the new rows show up in `/model`\n\n, or you can skip the picker and name one outright:\n\n```\n/model claude-gpt-5.6-terra\n```\n\nIf you want to add a provider, here’s what that actually costs: **there’s no config file for it**. It’s a code change in five places plus a backend module, and `grok-backend.js`\n\nis the complete worked example at about 450 lines. **Gemini isn’t in there today.** I’d take the help.\n\nIf you only take one idea from this: **the model you use and the tool you use it in are two separate decisions**, and you’re allowed to make them separately.\n\nAnd if you’re at a company trying to **get real value out of your AI stack**, this is a big part of what I do: the plugins, hooks, and routing that make *Claude Code* actually productive on your own codebase and your own model budget. If you’d want a hand getting it working, feel free to reach out.", "url": "https://wpnews.pro/news/the-quest-for-local-model-routing-inside-claude-code-starts-with-a-codex-gateway", "canonical_source": "https://eigenwise.io/writing/the-quest-for-local-model-routing-inside-claude-code", "published_at": "2026-08-07 00:00:00+00:00", "updated_at": "2026-08-09 12:57:36.574559+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools", "ai-infrastructure"], "entities": ["Eigenwise", "Claude Code", "model-gateway", "Eigenwise Toolshed", "ChatGPT", "Grok", "Anthropic", "Codex CLI"], "alternates": {"html": "https://wpnews.pro/news/the-quest-for-local-model-routing-inside-claude-code-starts-with-a-codex-gateway", "markdown": "https://wpnews.pro/news/the-quest-for-local-model-routing-inside-claude-code-starts-with-a-codex-gateway.md", "text": "https://wpnews.pro/news/the-quest-for-local-model-routing-inside-claude-code-starts-with-a-codex-gateway.txt", "jsonld": "https://wpnews.pro/news/the-quest-for-local-model-routing-inside-claude-code-starts-with-a-codex-gateway.jsonld"}}