Use QuickSilver Pro in OpenCode and Crush
Configure the OpenCode and Crush terminal coding agents to use QuickSilver Pro, run Claude Sonnet 5.5 at $0.50 / $2.50 per million tokens or DeepSeek V4.1 Flash for less, and see what a small bug fix cost.
OpenCode and Crush are open-source coding agents that run in your terminal. Both let you add your own OpenAI-compatible provider, so both can use QuickSilver Pro: one key, every model in the catalog, prepaid billing.
You need a QuickSilver Pro API key from the dashboard. New accounts get $0.05 of free credit, which covers the starter models (GPT-6 Luna, Claude Haiku 5.5, DeepSeek V4.1 Flash, Qwen3.8 Flash Next and MiMo-V2.6-Flash); Claude Sonnet 5.5 needs a top-up, from $5. Put the key in your environment so the config files below can read it without storing it:
export QSP_API_KEY=YOUR_QSP_KEY
We tested everything here on 2026-10-20 with OpenCode 1.18.35 and Crush 0.98.1 (and the older JSON config on Crush 0.20.1).
OpenCode
Create opencode.json in your project root:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"quicksilverpro": {
"npm": "@ai-sdk/openai-compatible",
"name": "QuickSilver Pro",
"options": {
"baseURL": "https://api.quicksilverpro.io/v1",
"apiKey": "{env:QSP_API_KEY}"
},
"models": {
"claude-sonnet-5-5": { "name": "Claude Sonnet 5.5", "limit": { "context": 1000000, "output": 64000 } },
"deepseek-v4.1-flash": { "name": "DeepSeek V4.1 Flash", "limit": { "context": 1000000, "output": 32000 } }
}
}
},
"model": "quicksilverpro/claude-sonnet-5-5"
}
npm: "@ai-sdk/openai-compatible"tells OpenCode to talk to the Chat Completions API atbaseURL.{env:QSP_API_KEY}reads the key from your environment.- Only the models listed under
modelsshow up.opencode models quicksilverproprints them; add any other ID from the model list the same way. modelsets the default. Pick another per run with-m:
opencode # interactive, uses the default
opencode run -m quicksilverpro/deepseek-v4.1-flash "explain what main.py does"
Crush
Current Crush versions read a crushrc file — Bash with a few built-in commands. Put this in ~/.config/crush/crushrc:
provider add quicksilverpro \
--name "QuickSilver Pro" \
--type openai-compat \
--base-url "https://api.quicksilverpro.io/v1" \
--api-key "$QSP_API_KEY"
model add quicksilverpro/claude-sonnet-5-5 --name "Claude Sonnet 5.5" --context-window 1000000 --default-max-tokens 32000
model add quicksilverpro/deepseek-v4.1-flash --name "DeepSeek V4.1 Flash" --context-window 1000000 --default-max-tokens 32000 --can-reason true
model large quicksilverpro/claude-sonnet-5-5
model small quicksilverpro/deepseek-v4.1-flash
model large is the model you chat with. model small is for Crush's side jobs: in our runs it got one short extra request per session. Pointing it at a cheap model keeps those calls cheap.
Then run crush as usual, or switch model for one prompt with crush run -m quicksilverpro/deepseek-v4.1-flash "...". Use the quicksilverpro/ prefix: crush models lists the same model IDs under several built-in providers.
If you are on an older Crush that uses crush.json (we tested 0.20.1), the equivalent is:
{
"$schema": "https://charm.land/crush.json",
"providers": {
"quicksilverpro": {
"type": "openai-compat",
"base_url": "https://api.quicksilverpro.io/v1",
"api_key": "$QSP_API_KEY",
"models": [
{ "id": "claude-sonnet-5-5", "name": "Claude Sonnet 5.5", "context_window": 1000000, "default_max_tokens": 32000 },
{ "id": "deepseek-v4.1-flash", "name": "DeepSeek V4.1 Flash", "context_window": 1000000, "default_max_tokens": 32000 }
]
}
},
"models": {
"large": { "provider": "quicksilverpro", "model": "claude-sonnet-5-5" },
"small": { "provider": "quicksilverpro", "model": "deepseek-v4.1-flash" }
}
}
Which models to use
| Use | Model | QuickSilver Pro (input / output) |
|---|---|---|
| Default | Claude Sonnet 5.5 | $0.50 / $2.50 |
| Cheap, and Crush's small model | DeepSeek V4.1 Flash | $0.125 / $0.55 |
Prices are per million tokens. Sonnet 5.5 is 75% below Anthropic's list price of $2.00 / $10.00. Other catalog models can be added the same way; these two are the ones we ran.
What a small fix cost
On 2026-10-20 we gave each tool the same task in a fresh copy of a two-file Python project: average() divided by len(numbers) - 1, and a test caught it. The prompt was "test_stats.py fails. Find the bug in stats.py and fix it with a minimal edit. Do not change the tests." A run passed if the test passed afterwards. Token counts are what the API reported; costs are those counts at QuickSilver Pro prices on 2026-10-20, with cached input at the cache-read rate.
| Tool | Model | Passed | Requests | Input tokens (cached) | Output tokens | Time | Cost |
|---|---|---|---|---|---|---|---|
| OpenCode | Claude Sonnet 5.5 | yes | 4 | 47,677 (24,180) | 810 | 11 s | $0.015 |
| OpenCode | DeepSeek V4.1 Flash | yes | 7 | 56,421 (49,792) | 537 | 16 s | $0.0017 |
| Crush | Claude Sonnet 5.5 + DeepSeek V4.1 Flash for the title | yes | 5 | 74,446 (29,772) | 980 | 12 s | $0.027 |
| Crush | DeepSeek V4.1 Flash | yes | 8 | 86,141 (73,216) | 1,094 | 20 s | $0.0031 |
All four made the same one-line fix. This is one run per row on a deliberately easy bug, so read it for the order of magnitude, not as a ranking. Two things stand out:
- Most of the input is the agent's own system prompt and tool definitions, sent with every request: 7,500 to 18,000 tokens on the first request here, before any of your code. Prompt caching serves much of it at a fraction of the input price on later requests.
- On this task DeepSeek V4.1 Flash cost roughly a tenth of what Sonnet 5.5 did, in both tools. The bug was easy; we did not compare the two on harder work.
Every request also shows up in your dashboard with its model, tokens and cost.
Things we ran into
- OpenCode shows a cost of 0. It has no prices for a custom provider, so its per-step cost reads 0. The real figures are in your dashboard.
- For unattended OpenCode runs, add
--auto. We ranopencode run --auto ..., which auto-approves tool permissions that are not explicitly denied. Only do that in a project you can reset. crush rundoes not take-y. It fails withUnknown shorthand flag: 'y' in -y. It did not need it either: in non-interactive mode Crush edited files and ran shell commands without asking, so treat it the same way.--can-reasonneeds a value incrushrc. Crush's docs say boolean flags default to true, but--can-reasonon its own stopped Crush from starting:model: --can-reason requires a value.Write--can-reason true.- Reasoning models count their thinking as output. DeepSeek V4.1 Flash reasons before it answers, and those tokens are in the output counts above.
Using Claude Code instead? See Claude Code with QuickSilver Pro. Calling models from your own code? The quickstart and integrations pages cover the SDKs.