Droid (Factory) Setup
Add QCode.cc as a BYOK custom model in Factory's Droid CLI: provider=anthropic plus baseUrl in ~/.factory/settings.json
On This Page
Last verified: 2026-09-18 · 📄 Per official docs (Droid CLI v0.222.0 released 2026-09-18; frequent releases — trust
droid --version)
At a glance¶
| Item | Details |
|---|---|
| Models you can use | Claude ✅ (provider: "anthropic") · GPT ✅ · Chinese models ✅ (provider: "generic-chat-completion-api") · Gemini ❌ (no such provider upstream) |
| Protocol & Base URL | Anthropic: https://api.qcode.cc/api · OpenAI Chat: https://api.qcode.cc/openai/v1 |
| Where to configure | ~/.factory/settings.json (auto-created on first droid run) |
| Official docs | BYOK · settings |
| Droid is Factory's terminal AI coding agent. It supports BYOK custom models, so QCode.cc can be its upstream. |
Which protocol¶
Droid selects the protocol through the provider field. For Claude, use anthropic — QCode's OpenAI endpoint does not accept Claude models (see Endpoints & API Paths).
| Model you want | provider |
baseUrl |
|---|---|---|
| Claude | anthropic |
https://api.qcode.cc/api |
| GPT / the four Chinese families | generic-chat-completion-api (Chat-Completions-compatible) |
https://api.qcode.cc/openai/v1 |
🔴 Do not write
"provider": "openai"— upstream reserves it for the OpenAI Responses API (“Use provider:"generic-chat-completion-api"unless you are calling OpenAI's or Anthropic's official API”, BYOK docs). GPT / Chinese models on QCode speak Chat Completions, so usegeneric-chat-completion-api.
Install¶
curl -fsSL https://app.factory.ai/cli | sh
It installs to ~/.local/bin/droid. If the installer reports that PATH is not configured, add the line it prints to ~/.zshrc / ~/.bashrc.
Verify (trust the actual output):
droid --version
Configure¶
Edit ~/.factory/settings.json (it is auto-created on the first droid run; a project-level .factory/settings.local.json also works — it merges on top, remember to gitignore it):
{
"customModels": [
{
"model": "claude-sonnet-5",
"displayName": "QCode Sonnet 5",
"baseUrl": "https://api.qcode.cc/api",
"apiKey": "${QCODE_KEY}",
"provider": "anthropic",
"maxOutputTokens": 8192
},
{
"model": "claude-haiku-4-5",
"displayName": "QCode Haiku 4.5",
"baseUrl": "https://api.qcode.cc/api",
"apiKey": "${QCODE_KEY}",
"provider": "anthropic",
"maxOutputTokens": 4096
}
]
}
Inject the key through the environment:
export QCODE_KEY="cr_your_qcode_key"
| Field | Meaning |
|---|---|
model |
The model id sent to the API; must match qcode.cc/models exactly |
displayName |
Label in the model picker; free-form |
baseUrl |
Stop at /api; Droid appends /v1/messages itself |
apiKey |
Supports ${VAR} environment references |
provider |
anthropic for Claude |
maxOutputTokens |
Output cap per reply |
Per Factory's docs, API keys stay local and are not uploaded to Factory servers. From mainland China, swap the host for
https://asia.qcode.cc/api(Asia node, nearest of Korea / Taiwan / Hong Kong).
Verify¶
droid exec --model "claude-sonnet-5" "reply with exactly: OK"
OK means you are connected.
Negative control (proving the config actually took effect): temporarily point baseUrl at a path that does not exist and run again — it should fail. A success alone does not prove your leg was used.
Everyday usage¶
# interactive
droid
# non-interactive
droid exec "run the tests and fix the failures"
# specific working directory
droid --cwd /path/to/project
# run inside a git worktree (isolated changes)
droid -w feature-x
# autonomy level
droid --auto medium
Troubleshooting¶
model_not_available_on_endpoint¶
provider is an OpenAI-compatible value while the model is a Claude one. Set "provider": "anthropic" with baseUrl = https://api.qcode.cc/api.
401 / auth failure¶
${QCODE_KEY} was not expanded (the variable is not exported), or the key has stray whitespace. Check that echo $QCODE_KEY starts with cr_.
Another trap: putting the config into the legacy ~/.factory/config.json (snake_case fields) — officially the legacy file does not expand apiKey environment references, so ${QCODE_KEY} would be sent verbatim as the key. Use settings.json.
The model is missing from the picker¶
Only models listed in customModels[] appear. Add an entry and restart.
Related¶
- Endpoints & API Paths — protocol × model-family table
- Crush Setup — another terminal agent
- Chinese Models — GLM / Kimi / DeepSeek / Qwen