Qwen Code + Ollama in 2026: Local Setup After the Free-Tier Shutdown — modelProviders Config, Placeholder Keys, and the Impermeable Settings Trap
TL;DR: Qwen Code — v0.23.1 as of September 8, 2026 — lost its famous free ride when Qwen OAuth was discontinued on April 15, 2026, so a local Ollama backend is now the only way to run it at $0. The official docs support that path directly. Two defaults will still wreck your first session: Ollama’s 4,096-token context and Qwen Code’s impermeable modelProviders config layering.
What you’ll be able to do after this guide:
- Wire Qwen Code to Ollama two ways — the three-variable quick path for a single model, and the
settings.jsonmodelProvidersblock that gives you a real model picker with per-model timeouts - Dodge the three traps that kill local Qwen Code sessions: the server-side 4K context, the client-side
contextWindowSize, and the “impermeable” provider config that silently discards your other settings - Swap the same setup onto LM Studio or vLLM by changing one
baseUrl, with tool calling that actually works on a Qwen3-Coder-class model
Honest take: Qwen Code post-shutdown is a better deal than it looks — the agent is Apache 2.0 and genuinely capable, and running Qwen’s own coder model under it locally is the cleanest dogfood pairing in this series. If you want the most battle-tested local agent loop, OpenCode still edges it out; pick Qwen Code if you want the multi-provider
/modelpicker, hot-reloading config, and first-party docs that treat Ollama as a supported citizen rather than a hack.
Where Qwen Code fits — and what died in April
Qwen Code is Alibaba’s terminal coding agent. It started life as a Gemini CLI fork — the Apache 2.0 LICENSE file still carries Google’s copyright line next to Qwen’s — and has since grown its own agentic surface: auto-memory, skills, agent teams, IDE plugins for VS Code, JetBrains, and Zed, and an experimental qwen serve daemon. Development is fast: v0.23.1 went stable on September 8, 2026, one day before this article, with preview builds landing the same afternoon.
For most of its life the headline was the free tier: sign in with Qwen OAuth, get a generous daily request allowance, pay nothing. That’s over. The official auth docs now state it plainly: the Qwen OAuth free tier was discontinued on 2026-04-15. The supported paid routes are Alibaba Cloud’s Coding Plan (a fixed monthly fee, keys prefixed sk-sp-, set via BAILIAN_CODING_PLAN_API_KEY) and the usage-billed Token Plan — or any API key for OpenAI-compatible, Anthropic, or Gemini endpoints you bring yourself.
Which leaves the route this series exists for. Qwen Code’s provider system speaks OpenAI-compatible out of the box, and the official model-provider docs include literal Ollama, vLLM, and LM Studio config examples. Zero per-token cost, nothing leaves your machine, and — after a spring in which an entire auth method vanished with four months’ notice — no vendor can deprecate your backend. We’ve run this play for Claude Code, Codex CLI, OpenCode, Goose, Kilo Code, Aider, and Crush; Qwen Code was the gap.
One warning before you follow any other tutorial: most 2025-era Qwen Code guides open with “just run qwen and OAuth in — it’s free.” That path now dead-ends at a login flow for a tier that no longer exists. If a guide leads with OAuth, it predates April 2026; close the tab.
Step 1 — Ollama first, context before models
Ollama v0.33.3 (September 2, 2026) is current as of this writing. Install it, then fix the context window before you pull anything, because this remains the number-one local-agent killer: Ollama’s default context is 4,096 tokens, per the official FAQ. Qwen Code’s system prompt plus tool definitions plus your repo context blows through 4K before the first real request, and Ollama doesn’t error — it silently truncates from the top, and the agent starts forgetting its own instructions mid-loop. Full mechanics in our context-length fix guide; the short version:
# systemd Linux
sudo systemctl edit ollama
# add under [Service]:
# Environment="OLLAMA_CONTEXT_LENGTH=65536"
# or run the server with it set
OLLAMA_CONTEXT_LENGTH=65536 ollama serve
64K is the floor for agent work if your VRAM allows it; 32768 on tighter cards. Then pull a model that can drive a tool-calling loop. The two picks that have held up across this series:
ollama pull qwen3-coder:30b # ~19 GB at Q4 — MoE, dedicated tool-call parser, wants 24 GB VRAM
ollama pull gpt-oss:20b # ~12 GB MXFP4 — tool-calling-trained, fits 16 GB cards
There’s a neat symmetry in the first pick: Qwen’s agent driving Qwen’s coder model, with Alibaba’s billing system nowhere in the loop. On hardware, qwen3-coder:30b with a real context allocation is RTX 3090/4090 territory, and it’s comfortable on a 32 GB+ unified-memory Mac like the Mac Mini M4 Pro. The runaihome.com VRAM guide maps models to VRAM tiers in detail, and if you have no GPU at all, a RunPod rental runs everything below unchanged.
Sanity-check the endpoint Qwen Code 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 first — our connection-refused guide covers the usual suspects. Note the /v1 path: that’s Ollama’s OpenAI-compatible surface, and per the official compatibility docs it supports both streaming and tools on /v1/chat/completions — the two features an agent lives on. The docs also note an API key is “required but ignored,” which matters in a minute.
Step 2 — Install Qwen Code
Node.js 22+ via npm, or Alibaba’s standalone installer if you’d rather skip Node:
npm install -g @qwen-code/qwen-code@latest
qwen --version # 0.23.1 at time of writing
Don’t run qwen yet — with no config it drops you into the auth picker, and every choice on that screen except the API-key routes wants an Alibaba account.
Step 3 — The quick path: three environment variables
Qwen Code honors the classic OpenAI-compatible trio, with OPENAI_API_KEY required, OPENAI_BASE_URL as the endpoint override, and OPENAI_MODEL (alias QWEN_MODEL) picking the model:
export OPENAI_API_KEY="ollama" # required but ignored by Ollama — any value works
export OPENAI_BASE_URL="http://localhost:11434/v1"
export OPENAI_MODEL="qwen3-coder:30b"
qwen
That’s a working local Qwen Code. The placeholder key is not a hack — the official docs suggest exactly this (“use a placeholder like ollama or not-needed”) because the client requires some value while Ollama validates none. If you only ever run one local model, you can stop here.
You shouldn’t, though, because the env-var path gives you one model, no per-model tuning, and timeouts calibrated for cloud latency. The right way is the provider registry.
Step 4 — The right path: modelProviders in settings.json
Qwen Code reads user settings from ~/.qwen/settings.json and project settings from .qwen/settings.json in the repo root, with project overriding user. Local backends are declared under the modelProviders key — this is adapted from the official docs’ own Ollama example:
{
"modelProviders": {
"openai": [
{
"id": "qwen3-coder:30b",
"name": "Qwen3 Coder 30B (Ollama)",
"envKey": "OLLAMA_API_KEY",
"baseUrl": "http://localhost:11434/v1",
"generationConfig": {
"timeout": 300000,
"streamIdleTimeoutMs": 600000,
"contextWindowSize": 65536,
"samplingParams": { "max_tokens": 8192 }
}
},
{
"id": "gpt-oss:20b",
"name": "GPT-OSS 20B (Ollama)",
"envKey": "OLLAMA_API_KEY",
"baseUrl": "http://localhost:11434/v1",
"generationConfig": {
"timeout": 300000,
"streamIdleTimeoutMs": 600000,
"contextWindowSize": 32768,
"samplingParams": { "max_tokens": 8192 }
}
}
]
}
}
Then put the placeholder in ~/.qwen/.env so the envKey lookup resolves:
# ~/.qwen/.env
OLLAMA_API_KEY=ollama
Credentials load from process.env[envKey] at runtime and are never written into settings — good hygiene even when the “credential” is the string ollama. Inside a session, /model opens the picker listing every entry; your choice persists automatically. Within one auth type, models are identified by id + baseUrl together, so the same Ollama tag pointed at two hosts is two valid entries, while true duplicates are skipped with a warning.
Three numbers in that block deserve explanation:
timeout: 300000— five minutes. The docs’ cloud examples use 60 seconds; their own Ollama example quintuples it, because a cold local model can spend most of a minute just loading weights into VRAM before the first token.streamIdleTimeoutMs: 600000— how long a stream may go silent. A 30B model chewing a long prompt on consumer hardware produces exactly the kind of dead air that makes agents with short idle timeouts abort mid-generation.contextWindowSize: 65536— the client-side context declaration. This must agree with the server:OLLAMA_CONTEXT_LENGTHdecides what Ollama actually allocates, and this field decides what Qwen Code believes it can send. Set only the client one and Ollama truncates silently at 4K anyway; set only the server one and Qwen Code budgets prompts for the wrong window. Set both.
A quality-of-life note that surprised us: modelProviders hot-reloads. Edits to settings.json are picked up in about 300 ms without restarting the session — tweak max_tokens, save, and the next request uses it. (The providerProtocol key is the exception; that one needs a restart.)
The trap that isn’t in the tutorials: impermeable config
This is the one that will burn people migrating from other tools, and it’s stated in the docs but easy to skim past. When a model from modelProviders is selected, its generationConfig becomes impermeable: lower configuration layers — CLI flags, environment variables, the global model.generationConfig in settings — do not fill in the gaps. Any field you don’t specify in the provider entry is undefined, not inherited.
The docs’ own example: a global settings block sets max_tokens: 1000, the provider entry sets only temperature. Select that provider model and max_tokens is undefined — your global value is ignored, and the model falls back to whatever the server decides. On a local backend that can mean surprise short completions (server-side output caps) or runaway generations, depending on the server’s defaults.
The rule: treat each modelProviders entry as the complete, self-contained config for that model. Timeout, context, sampling params — write them all, every entry, even when they repeat. Copy-paste duplication in this file is correct, not sloppy. This is the inverse of the layered-config behavior in every other tool in this series, and it’s why the blocks in Step 4 look verbose.
LM Studio and vLLM variants
Same shape, different baseUrl — these mirror the official docs’ examples:
{ "id": "qwen3-coder-30b", "name": "LM Studio", "envKey": "LMSTUDIO_API_KEY",
"baseUrl": "http://localhost:1234/v1" }
{ "id": "Qwen/Qwen3-Coder-30B-A3B-Instruct", "name": "vLLM", "envKey": "VLLM_API_KEY",
"baseUrl": "http://localhost:8000/v1" }
For LM Studio, the id must match the model identifier shown in LM Studio’s server tab, and our LM Studio connection-error guide applies unchanged if the first request 404s. For vLLM, the id is the model path you launched the server with; our vLLM backend guide covers the server side. If you run several backends and want one URL in front of all of them, the LiteLLM proxy and llama-swap setups both slot into the same modelProviders block — one entry per routed model, baseUrl pointed at the proxy.
Does tool calling actually work?
Yes, with the usual local caveats. Ollama’s /v1/chat/completions accepts tools, and the Qwen3-Coder family ships a dedicated tool-call parser — early-2026 template bugs that broke its tool calls across Ollama and LM Studio were fixed upstream, so a current ollama pull gets the working template. Two honest limits: Ollama still doesn’t support tool_choice, so nothing can force a tool call at the API level, and 30B-class MoE models occasionally fumble a call mid-loop — the failure mode and workarounds are the same ones documented in our tool-use fix guide. If a model without tool support sneaks into your picker, the first agentic request fails loudly; that guide covers the error text.
Where it breaks
Same honesty section as the rest of the series. The harness is solid and the docs are unusually good about local backends — better than most cloud-first agents — but the ceiling is the model. A 30B-class local MoE handles scoped agent work: a focused refactor, tests for one module, a directed bug hunt. It does not match cloud frontier models on long multi-file plans, and Qwen Code’s fancier features (agent teams, long autonomous sessions) compound the gap because they multiply context and tool-call volume — precisely where small local models wobble. Budget for that with model.sessionTokenLimit (the recorded-prompt-token cap; -1 means unlimited) and model.maxSessionTurns if you let sessions run long.
Second, velocity risk: v0.23.1 landed yesterday, previews land daily, and this year alone the project retired its web UI and its primary auth method. The modelProviders schema documented here is current for September 2026 — when in doubt, trust the in-repo docs over any blog, this one included.
Third, the ecosystem asymmetry: unlike Crush or OpenCode, Qwen Code’s premium experience is clearly built around Alibaba’s hosted models — the Coding Plan’s roster (GLM-5, Kimi-K2.5, MiniMax-M2.5, the qwen3.x-plus line) doesn’t exist locally at those sizes. Local mode is supported, documented, and real; it’s just not the configuration Alibaba optimizes first. Our cost comparison has the math on when a paid plan beats local on time-per-task.
FAQ
Is Qwen Code still free to use at all? The software is Apache 2.0 — free forever, no account needed for BYO providers. What ended on April 15, 2026 was free hosted model access via Qwen OAuth. Bring Ollama and the whole stack is $0; bring an API key and you pay that provider.
Does Qwen Code work with Ollama on another machine?
Yes — set baseUrl to the remote host (http://192.168.1.50:11434/v1) and start Ollama with OLLAMA_HOST=0.0.0.0 so it binds beyond loopback. Don’t expose that port past your LAN: Ollama ignores API keys, so there is no auth.
Why does Qwen Code demand an API key for a server that doesn’t check one?
The client requires envKey to resolve to something; Ollama’s docs describe the key as “required but ignored.” Set OLLAMA_API_KEY=ollama (or any string) in ~/.qwen/.env and move on.
Env vars or modelProviders — which should I use?
Env vars (OPENAI_API_KEY / OPENAI_BASE_URL / OPENAI_MODEL) for a single-model quick start. modelProviders for anything real: multiple models in the /model picker, per-model timeouts and context, hot reload, and project-level overrides via .qwen/settings.json.
My global settings stopped applying after I added a provider entry. Bug?
No — documented behavior. Provider-selected models don’t inherit from lower config layers; unspecified fields become undefined. Write every field you care about into each modelProviders entry.
Sources
- Qwen Code README — QwenLM/qwen-code (GitHub)
- Model provider configuration — official Qwen Code docs
- Authentication guide (OAuth discontinuation, env vars) — official Qwen Code docs
- Settings reference (settings.json paths, model keys) — official Qwen Code docs
- Qwen Code releases (v0.23.1, Sep 8 2026) — GitHub
- Qwen Code LICENSE — Apache 2.0
- 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 9, 2026. Versions verified against the official repos on the day of writing: Qwen Code v0.23.1, Ollama v0.33.3. Qwen Code ships previews daily — check the release page 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.