Crush + Ollama in 2026: Charm's Terminal Agent on a Local Model — crushrc Config, the 60-Second Timeout Trap, and Tool Calling That Works Now
TL;DR: Crush — Charm’s terminal coding agent, v0.92.0 as of August 31, 2026 — has the cleanest local-model story of any TUI agent: a dedicated ollama provider type that auto-discovers your pulled models, configured in three lines of the new Bash-based crushrc. Two defaults will still ruin your first session: Ollama’s 4,096-token context and Crush’s 60-second request timeout.
What you’ll be able to do after this guide:
- Point Crush at Ollama with a three-line
crushrcand have every pulled model appear in the model picker automatically — no per-model JSON - Fix the three failure modes that make local Crush sessions die silently: the 4K server-side context, the 60-second streaming-inactivity abort, and stale builds that drop tool calls
- Run the same setup against LM Studio or a bare
llama-serverby changing one--typeflag, and lock the whole thing down for offline use
Honest take: Crush is now the nicest-looking way to run a local coding agent in a terminal, and since the June 2026 tool-call fix it’s a working one too. If you want the most mature local agent loop, OpenCode still has the edge on batteries-included agent features; pick Crush when you want mid-session model switching, LSP-fed context, and a config file that’s just Bash. Either way, the model matters more than the harness —
qwen3-coder:30bon a 24 GB card is where local agentic coding starts being real.
Where Crush fits in the local-agent lineup
We’ve wired Ollama into every major terminal agent on this site — Claude Code, Codex CLI, OpenCode, Goose, Kilo Code’s CLI, and Aider. Crush is the one readers kept asking about, and it earned the wait: this is Charm’s flagship agent, built by the people behind the Bubble Tea TUI ecosystem, and it shows — the interface is the best-looking of the lot, sessions persist per project, and it reads your codebase through actual LSP servers rather than grep alone.
The September 2026 state of the project, verified against the repo: v0.92.0 shipped August 31, 2026, with v0.91.x releases landing almost weekly through August. Licensing is the one thing to know before you commit: Crush is FSL-1.1-MIT — source-available, free to use, but not OSI open source today; under the FSL’s terms each release’s code converts to plain MIT two years after that release. If your company’s policy requires OSI-approved licenses, Cline (Apache 2.0) or OpenCode (MIT) are the alternatives; for solo use it changes nothing about anything below.
Why bother running it against Ollama at all? Same math as the rest of the series: zero per-token cost, nothing leaves your machine, and no vendor can deprecate your backend. Crush also happens to make the multi-model case unusually well — it switches LLMs mid-session while preserving context, so “draft with the local 30B, escalate the gnarly refactor to a cloud model” is two keystrokes (ctrl+l), not a config edit.
Step 1 — Ollama first, and set the context before anything else
Ollama v0.33.3 (September 2, 2026) is current as of this writing. Install it, then deal with the context window before pulling models, because this is the single most common way local agents fail: Ollama’s default context is 4,096 tokens per the official FAQ, and a coding agent’s system prompt plus tool definitions plus repo context blows through 4K before your first real request. Ollama doesn’t error when that happens — it silently truncates from the top, and the agent starts forgetting its own instructions. The full mechanics are in our num_ctx fix guide; the short version:
# systemd Linux
sudo systemctl edit ollama
# add under [Service]:
# Environment="OLLAMA_CONTEXT_LENGTH=65536"
# or just run the server with it set
OLLAMA_CONTEXT_LENGTH=65536 ollama serve
64K is the floor for agent work if your VRAM allows it; drop to 32768 on tighter cards. Then pull a model that can actually drive an agent loop. The two picks that have held up across this series:
ollama pull qwen3-coder:30b # ~19 GB at Q4 — MoE, strong tool caller, wants 24 GB VRAM
ollama pull gpt-oss:20b # ~12 GB MXFP4 — tool-calling-trained, fits 16 GB cards
On hardware: qwen3-coder:30b plus a real context allocation is RTX 3090/4090 territory (24 GB), and it’s also comfortable on a 32 GB+ unified-memory Mac like the Mac Mini M4 Pro. The runaihome.com VRAM guide has the full model-per-VRAM-tier table, and if you have no GPU at all, a RunPod rental runs everything here unchanged.
Sanity-check the OpenAI-compatible endpoint Crush will talk to:
$ curl -s http://localhost:11434/v1/models | head -c 200
{"object":"list","data":[{"id":"qwen3-coder:30b","object":"model", ...
If that curl fails, fix it before touching Crush — our connection-refused guide covers the usual suspects.
Step 2 — Install Crush
# macOS / Linux
brew install charmbracelet/tap/crush
# any platform with Node
npm install -g @charmland/crush
# Windows
winget install charmbracelet.crush
# from source
go install github.com/charmbracelet/crush@latest
Debian/Ubuntu and Fedora repos exist too (repo.charm.sh), and binaries ship for Linux, macOS, Windows, and the BSDs. Crush runs first-class on Windows PowerShell natively — no WSL requirement, which is rarer than it should be in this category.
Step 3 — The crushrc: three lines for auto-discovery
Here’s the part that makes Crush’s local story better than most. Config moved in 2026 from JSON to a crushrc — literally Bash with Crush-specific builtins, executed by Crush’s own built-in Bash interpreter so it works identically on Windows. The old crush.json still loads but is officially deprecated. Put this in ~/.config/crush/crushrc (global) or ./.crushrc (per-project):
# ~/.config/crush/crushrc
provider add ollama \
--name Ollama \
--type ollama \
--base-url "http://localhost:11434/v1/"
That’s the whole thing. Because the provider --type is ollama and no models are listed, Crush auto-discovers every model Ollama has pulled and populates its model picker with them. The same auto-discovery works for --type lmstudio, llamacpp, litellm, and omlx — this is a first-class local-provider system, not an OpenAI-compat afterthought. Two details people get wrong:
- The base URL for the
ollamatype includes/v1/. The bare:11434root is Ollama’s native API, not the OpenAI-compatible surface Crush speaks. - For a bare llama-server backend, the
llamacpptype takes the server root without/v1(the README’s own example is--base-url "http://localhost:2222").
Launch crush in a repo, hit ctrl+l, and your Ollama models are in the picker. To make the local model the default instead of selecting it each time, set the large-model slot:
model large ollama/qwen3-coder:30b
Crush uses a large/small model split (big model for the agent, small model for cheap background work) — model small accepts a local model the same way.
Overriding what discovery guesses
Auto-discovery gets you running, but you can pin metadata explicitly — user-defined models take precedence, and fields you set are never overwritten by discovery:
provider add ollama \
--name Ollama \
--type ollama \
--base-url "http://localhost:11434/v1/" \
--discover-models true
model add ollama/qwen3-coder:30b \
--name "Qwen3 Coder 30B" \
--context-window 65536 \
--default-max-tokens 20000
One thing --context-window does not do: change what Ollama allocates. It tells Crush how much it may send before compacting. The serving context is set on Ollama’s side (OLLAMA_CONTEXT_LENGTH, step 1) — set both, and make them agree. Declaring 65536 to Crush while Ollama serves 4,096 recreates the silent-truncation bug with extra steps.
Step 4 — The 60-second timeout, and the other things that kill first sessions
Three problems accounted for essentially every “Crush + Ollama doesn’t work” report we could find. In order of likelihood:
The request timeout. Crush aborts an LLM request after 60 seconds of streaming inactivity by default (request-timeout, documented default 60). A 30B model on a saturated card, prompt-processing 40K tokens of repo context, can sit well past a minute before emitting its first token — no tokens streamed means “inactivity,” and Crush kills a request the model was still working on. Cloud APIs never hit this; local backends hit it constantly. The fix is one crushrc line:
option request-timeout 300 # or 0 to wait forever
If your sessions die on the first big prompt and work on trivial ones, this is why.
Stale builds dropping tool calls. Through spring 2026 there was a real, well-documented bug here: Crush sent tool definitions correctly, the local model returned properly structured tool_calls, and Crush never executed them — reasoning text streamed to the UI and the loop just stopped (issue #2936, filed May 16, 2026 against v0.67.0, reproduced against both Ollama and vLLM). The fix landed in Charm’s Fantasy provider library (PR #287, merged June 19, 2026): OpenAI-compatible streams that pack tool calls and content into the same delta — which local servers do and OpenAI’s own API doesn’t — now parse correctly. The practical takeaway: any Crush ≥ v0.9x is fine; if you tried Crush on a local model in early 2026 and concluded tool calling was broken, retry on current. If tools still don’t fire, it’s almost always the model, not Crush — instruct-tuned generalists without tool training will chat instead of act, the same failure covered in our Ollama tool-support fix. Stick to qwen3-coder or gpt-oss class models.
The wrong provider type. Crush distinguishes openai (actual OpenAI, or proxies to it) from openai-compat (everything else speaking the dialect) from the dedicated local types. Older community configs wired Ollama as openai-compat — it mostly works, but you lose auto-discovery. Use --type ollama and delete the old block.
When something’s still off, Crush’s logging is genuinely good:
$ crush logs --tail 100
$ crush logs --follow # watch requests live in a second terminal
Logs live at ./.crush/logs/crush.log per project; option debug true in the crushrc turns up verbosity.
The same setup on LM Studio, llama.cpp, and LiteLLM
The provider line is the only thing that changes:
# LM Studio (default port 1234) — see our LM Studio guides for server setup
provider add lmstudio --type lmstudio --base-url "http://localhost:1234/v1/"
# bare llama-server — note: no /v1 suffix for this type
provider add llamacpp --type llamacpp --base-url "http://localhost:8080"
# LiteLLM proxy — route local + cloud through one port
provider add litellm --type litellm --base-url "http://localhost:4000/v1/"
All of them auto-discover loaded models. If you’re choosing a backend from scratch, Ollama is still the lowest-friction daily driver; the tradeoffs across the whole backend family are mapped in our Cline/Continue/Aider backend series, and everything there applies to Crush unchanged since it’s the same OpenAI-compatible surface.
How Crush compares to the other local-capable terminal agents
| Crush v0.92.0 | OpenCode | Claude Code + Ollama | |
|---|---|---|---|
| License | FSL-1.1-MIT (source-available) | MIT | Proprietary client, free |
| Local config | 3-line crushrc, dedicated ollama type | Ollama provider in opencode.json | Env vars to Anthropic-compat endpoint |
| Model auto-discovery | Yes (ollama, lmstudio, llamacpp, litellm, omlx) | Partial | No — models declared manually |
| Mid-session model switch | Yes, context preserved (ctrl+l) | Yes | No (restart) |
| LSP context | Built in, per-language config | No | No (greps instead) |
| The catch | 60s timeout default; FSL license | Fewer TUI niceties | Tuned for Claude models; local quality drops hardest |
Two Crush-only extras worth configuring while you’re in the crushrc. Permissions, so the agent stops prompting for read-only operations (leave bash gated; and treat --yolo as the footgun the flag name admits it is):
permissions allow view ls grep edit
And project context: Crush reads ~/.config/crush/CRUSH.md plus a shared ~/.config/AGENTS.md, and crush init generates a per-repo AGENTS.md — same convention other agents read, so it coexists with an existing Claude Code or Cursor setup. It even loads skills from .claude/skills/ and ~/.claude/skills/ automatically, so skill packages you built for Claude Code work in Crush without copying.
Fully offline: two more switches
A local model isn’t a local setup until the harness stops phoning home. Crush checks Catwalk (Charm’s community model catalog) for provider updates at startup and records pseudonymous usage metrics. Both have documented off-switches:
export CRUSH_DISABLE_PROVIDER_AUTO_UPDATE=1
export CRUSH_DISABLE_METRICS=1 # DO_NOT_TRACK=1 also respected
With those set, an Ollama-backed Crush runs air-gapped — pair it with the llamafile approach if even Ollama is too much install for the target machine.
Where it breaks
Honesty section, same standard as the rest of the series. Crush’s harness is in good shape; the ceiling is the models. A 30B-class local MoE drives short, well-scoped agent loops — a focused refactor, tests for one module, a bug hunt with the LSP feeding it real symbols. It does not match cloud frontier models on long multi-file plans, and no local harness changes that; our 7-way agent comparison quantifies the gap in task terms. The FSL license is a real (if narrow) adoption blocker for OSI-only shops. And Crush’s velocity cuts both ways: weekly releases fixed the tool-call bug fast, but a config surface this new (the crushrc format is a 2026 change) means older tutorials — including anything showing crush.json — age quickly. When in doubt, trust the in-repo docs over any blog, this one included.
FAQ
Does Crush work with Ollama on a different machine?
Yes — point --base-url at the remote host (http://192.168.1.50:11434/v1/) and make sure Ollama binds beyond localhost (OLLAMA_HOST=0.0.0.0). Don’t expose that port past your LAN; Ollama has no auth.
Why don’t my Ollama models show up in the picker?
In order: the provider --type isn’t ollama (openai-compat configs don’t discover), the base URL is missing /v1/, or Ollama isn’t running (curl http://localhost:11434/v1/models to check). crush logs names the failure.
Can I mix local and cloud models in one session?
Yes — that’s Crush’s best trick. Add both providers, then switch with ctrl+l mid-session; context carries over. A common split: model large on a cloud model, model small on ollama/gpt-oss:20b for background work.
Is Crush free? The software costs nothing and no subscription is required for BYO providers — local or cloud keys. Charm sells Hyper, an optional hosted provider with a free tier; with Ollama you never touch it.
Do I need --jinja or a chat-template flag like other backends?
No. That flag family belongs to raw llama.cpp servers (details here). Ollama applies each model’s chat template itself, for Crush like any other client.
Sources
- Crush README — charmbracelet/crush (GitHub)
- Crush config reference (crushrc) — charmbracelet/crush docs
- Crush releases (v0.92.0, Aug 31 2026) — GitHub
- Crush LICENSE — FSL-1.1-MIT
- Issue #2936: Tool calls from local OpenAI-compatible providers are never executed — charmbracelet/crush
- Fantasy PR #287: fix tool calls in same streaming delta (merged Jun 19 2026) — charmbracelet/fantasy
- Ollama FAQ — context window default and OLLAMA_CONTEXT_LENGTH
- Ollama OpenAI compatibility — official docs
- Ollama releases (v0.33.3, Sep 2 2026) — GitHub
- Ollama — the FOSS deep-dive review at aifoss.dev
Last updated September 8, 2026. Versions verified against the official repos on the day of writing: Crush v0.92.0, Ollama v0.33.3. Both projects ship weekly — check the release pages before filing bugs against old builds.
Recommended Gear
Products linked in this guide:
- RTX 3090 24GB — the used-market VRAM king for
qwen3-coder:30bat a real context window - Mac Mini M4 Pro 64GB — the quiet unified-memory route to the same models
Was this article helpful?
Thanks for the feedback — it helps improve future articles.
Need hands-on help?
I offer 1-on-1 technical consulting for local AI setup, GPU selection, and AI coding tool configuration — same topics covered on this site.
Book a session — $49 / hour →Know which coding tool is worth paying for
Hands-on comparisons of AI coding assistants and what each one costs to run — including the local-model path. Sent only when something changes. Unsubscribe anytime.