Claude CLI, OpenCode & Gemini – route models, pick a harness
Three coding CLIs, one workflow – but the routing axis is the models, not the tools. How I pick the model first (context, privacy, cost, capability) and then the right harness. With shell setup and a small router script.

One misconception up front – one that was clear to me from the start: you don’t route CLIs. A CLI is a harness, i.e. a tool, and the harness uses a model. Those are two separate decisions. So day to day, two questions run in parallel:
- Which model solves this task best? → context, privacy, cost, capability.
- Which harness runs that model most comfortably? → agentic loop, tool use, ergonomics.
Three harnesses stuck with me: Claude Code, OpenCode and Gemini CLI. But the actual routing axis is the models behind them – the CLI is just the front end I drive them with.
Two axes, not one
The properties I route on are almost all model properties, not CLI properties:
- Gemini’s huge context is a property of the Gemini model – you get the same window via API or in any other harness.
- “Stays on the machine” means: a local model (Qwen), not “OpenCode”.
- Cost and reasoning depth hang on the model, not on the terminal front end.
The harness still contributes real, independent value – just a different kind: how well the agentic loop edits-tests-corrects, how tools are wired in, how the repo is read. Claude Code’s strength on multi-file refactors is exactly that – harness work on top of a strong model.
Broken out cleanly, my “routing” looks like this – axis first, then model, then harness:
| The task sits on … | Model (the actual routing) | Harness I use for it |
|---|---|---|
| sensitive, must stay local | local Qwen3 (Ollama) | OpenCode |
| huge context | Gemini | Gemini CLI |
| deep multi-file agent task | Claude | Claude Code |
One honest special case is right there in the table: OpenCode is not a model of its own. It’s a model-agnostic shell – I could just as well run Claude or Gemini through it. It sits next to local Qwen here because I use it for that, not because “OpenCode” is a capability. This row is exactly where the 1:1 bundling “one CLI = one model” – which makes the rest of the table look so tidy – falls apart.
The routing heuristic
The three questions decide the model first; the harness usually follows from it:
- Is the data sensitive? → a local model (Qwen), no cloud call – for me via OpenCode.
- Is the context huge (whole repo, long logs)? → Gemini, via the Gemini CLI.
- Is it a deep, multi-step agent task (refactor, migrate, debug across many files)? → Claude, via Claude Code.
As an executable version this fits into a small shell function. It’s a shortcut that bundles both decisions – model and harness – into one word:
# ~/.config/fish/functions/ai.fish (bash variant analogous)
function ai --description "Route a coding task to the right model (via a harness)"
switch $argv[1]
case local # sensitive data → local model, everything stays on the machine
opencode --model ollama/qwen3-32b-local $argv[2..]
case big # huge context → Gemini model
gemini $argv[2..]
case agent # deep multi-file change → Claude model
claude $argv[2..]
case '*' # default: general, deep task → Claude model
claude $argv
end
endThen you call e.g. ai local "explain db/migrations to me" or ai agent "pull the auth out of the controller into a service". You can see the dual nature in the alias: for local, the actual choice lives in the --model flag – the harness (OpenCode) is interchangeable.
In practice: same prompt, different choice
The prompt barely changes – the choice of model and harness does. Three real patterns:
Sensitive code (client project, nothing to the cloud):
ai local "Review this payment logic for race conditions"
# → local Qwen3-32B (run via OpenCode), not a byte leaves the machineUnderstand a whole repo:
gemini "Read all of src/ and describe the module boundaries as a Mermaid diagram"
# → the Gemini model's large window carries here, where others would have to truncateDeep refactor with tool use:
claude "Migrate all class components in src/components to hooks,
run the tests after each file and stop if it goes red"
# → agentic loop (harness) on a strong model: edit, test, correctThe honest part: the trade-offs
- Cost vs. capability: the Claude model is my quality anchor for big tasks – but also the most expensive path. Small, well-scoped changes don’t always need the strongest model.
- Privacy vs. convenience: the local path (Qwen, whatever harness runs it) is slower than any cloud, but non-negotiable for client code. How I got Qwen onto 16 GB for this is in the quantisation post.
- Context vs. precision: Gemini’s giant window is tempting – but “dump it all in” is rarely the best idea. Why, is in the context-engineering post.
Conclusion
Multi-model doesn’t mean “have many tools open”, and it doesn’t mean “route CLIs” either. It means: put the task on its axis, then pick the model – and then the harness that runs that model best. The three questions – sensitive? big? deep? – settle the model choice; the CLI is the finish, not the decision. The best model is rarely the biggest, but the one that fits the axis the task currently sits on.