Crush Setup
Add QCode.cc as a custom provider in Charm Crush: type=anthropic plus base_url in crush.json, and use Claude from the terminal
Crush Setup¶
Crush is Charm's terminal-first AI coding agent (written in Go). It supports custom providers, so QCode.cc can be its upstream.
Naming note: Crush was originally called "Open Code" and was renamed to avoid confusion with OpenCode. They are different projects.
Which protocol¶
Crush's custom providers accept anthropic and openai-compat as type. For Claude, use anthropic — QCode's OpenAI endpoint does not accept Claude models (see Endpoints & API Paths).
| Model you want | type |
base_url |
|---|---|---|
| Claude | anthropic |
https://api.qcode.cc/api |
| GPT / the four Chinese families | openai-compat |
https://api.qcode.cc/openai/v1 |
Install¶
# Homebrew
brew install charmbracelet/tap/crush
# or download a prebuilt binary from Releases
# https://github.com/charmbracelet/crush/releases
Verify (trust the actual output, not a version number in any doc):
crush --version
Configure¶
Create crush.json in your project root (a user-level config directory also works; defer to the official docs for its path):
{
"$schema": "https://charm.land/crush.json",
"providers": {
"qcode": {
"type": "anthropic",
"base_url": "https://api.qcode.cc/api",
"api_key": "$QCODE_KEY",
"extra_headers": { "anthropic-version": "2023-06-01" },
"models": [
{
"id": "claude-sonnet-5",
"name": "QCode Sonnet 5",
"cost_per_1m_in": 2,
"cost_per_1m_out": 10,
"context_window": 1000000,
"default_max_tokens": 8192
},
{
"id": "claude-haiku-4-5",
"name": "QCode Haiku 4.5",
"cost_per_1m_in": 1,
"cost_per_1m_out": 5,
"context_window": 200000,
"default_max_tokens": 4096
}
]
}
}
}
Inject the key through the environment rather than writing it into the file:
export QCODE_KEY="cr_your_qcode_key"
| Field | Meaning |
|---|---|
type |
anthropic selects the native Messages protocol |
base_url |
Stop at /api — Crush appends /v1/messages itself |
api_key |
Supports $VAR environment expansion |
extra_headers |
The Anthropic protocol needs anthropic-version |
models[] |
Models must be listed explicitly; each id must match qcode.cc/models character for character |
From mainland China, swap the host for
https://asia.qcode.cc/api(Hong Kong node); the key is unchanged.cost_per_1m_*only affects Crush's own usage estimate display, not actual billing.
Verify¶
crush run "reply with exactly: OK"
OK means you are connected.
To prove the traffic really goes to QCode, deliberately point base_url at a path that does not exist and run again. You should see an explicit 404 echoing the full URL:
404 Not Found {"error":"Not Found","message":"Route /api/xxx/v1/messages not found"}
That error proves Crush is composing base_url + /v1/messages and that your config took effect. (This is a negative control: a success alone does not prove your provider was used — Crush might have fallen back to another one.)
Everyday usage¶
# interactive
crush
# non-interactive
crush run "make this function async"
# pipes
cat README.md | crush run "make this clearer" > README.new.md
# specific directory with debug logging
crush --debug --cwd /path/to/project
# auto-accept every permission (use with care)
crush --yolo
Troubleshooting¶
model_not_available_on_endpoint¶
type is openai-compat while the model is a Claude one. Switch to type: "anthropic" with base_url = https://api.qcode.cc/api.
401 Invalid API key¶
The environment variable was not injected, or the key has stray whitespace. Check that echo $QCODE_KEY starts with cr_.
The model does not appear in the picker¶
Crush only shows models listed explicitly in models[]. Add an entry and restart.
Related¶
- Endpoints & API Paths — protocol × model-family table
- OpenCode Integration — a different terminal agent (not the same project)
- Chinese Models — GLM / Kimi / DeepSeek / Qwen