Skip to content
Yoink

Use any provider in Qwen Code

Qwen Code lists models, not providers: each entry under modelProviders in ~/.qwen/settings.json is one model with its own base URL and an envKey naming the variable that holds the key. yoink writes one entry per selected model and puts the key once in the env block. Connect with yoink connect <name> --to qwen.

On this page

At a glance

Qwen Code facts
FactValue
Harness idqwen
Config yoink writes~/.qwen/settings.json
FormatJSON
Protocols, in order of preferenceopenai-chat, openai-responses, anthropic-messages
Default modelmodel.name and security.auth.selectedType
Path overrideQWEN_HOME
Providers at oncemany, side by side
Experimentalno
Presets that reach it7 of 7: openai, kimi-code, moonshot, openrouter, deepseek, zai, ollama
Connect commandyoink connect <name> --to qwen

Generated from the yoink CLI source and docs/harnesses.md.

What yoink writes

For an OpenRouter key saved as openrouter, with --default z-ai/glm-4.7, the file looks like this (key redacted):

{
  "modelProviders": {
    "openai": [
      {
        "id": "z-ai/glm-4.7",
        "name": "GLM-4.7",
        "baseUrl": "https://openrouter.ai/api/v1",
        "envKey": "YOINK_OPENROUTER_API_KEY",
        "wireApi": "chat-completions",
        "generationConfig": { "contextWindowSize": 204800 }
      }
    ]
  },
  "env": {
    "YOINK_OPENROUTER_API_KEY": "<your key>"
  },
  "model": { "name": "z-ai/glm-4.7" },
  "security": { "auth": { "selectedType": "openai" } }
}

Qwen Code's model providers guide documents the same fields. The parts yoink decides:

FieldValue yoink writes
group under modelProvidersopenai for OpenAI Chat or Responses, anthropic for Anthropic Messages
wireApichat-completions or responses; left out for Anthropic entries
baseUrlthe endpoint URL; for Anthropic, without /v1
envKeyYOINK_<PROVIDER>_API_KEY, the profile id in upper snake case
generationConfig.contextWindowSizethe context window from models.dev

Why the key goes in env

Qwen Code reads each model's key from the variable that its envKey names, not from the entry itself. yoink writes the literal key once into the env block of settings.json and points every model of that provider at it. A key rotation therefore changes one line, however many models you exposed. The YOINK_ prefix is also how yoink recognises its own entries, so a model you added by hand with your own envKey is left alone. The exception is a hand-written entry with the same model id in the same group whose envKey resolves to this provider's exact key: yoink adopts it and rewrites its envKey to YOINK_<PROVIDER>_API_KEY.

Other keys you add to a yoink entry, such as extra generationConfig options, are kept when yoink re-syncs.

Which providers work

Qwen Code accepts OpenAI Chat, OpenAI Responses and Anthropic Messages, in that order, so every preset reaches it, ollama included. A provider that offers both Chat and Anthropic, like openrouter or deepseek, lands in the openai group with wireApi: "chat-completions".

yoink connect openrouter --to qwen --default z-ai/glm-4.7
yoink connect deepseek --to qwen

Two providers, same model id

Entries in one group are matched by id. If two providers expose the same model id through the same group, the second connect stops instead of overwriting the first:

✖ Qwen Code: Qwen Code already has a modelProviders.openai entry "gpt-5.2" that yoink does not manage. Rename or remove it before connecting gateway.

The same happens when you already have a hand-written entry with that id. Remove the model from one provider with yoink models <name>, or delete the other entry, then connect again. The one exception: a hand-written entry with the same id whose envKey already holds this provider's exact key is adopted, not refused.

Set the default model

Qwen Code needs two keys to pick a model: model.name and security.auth.selectedType. --default sets both, with selectedType matching the group the model was written to. Without --default, both stay as they are.

Backups and disconnect

The first change to an existing settings.json saves settings.json.yoink.bak once, as on most harnesses (see Backups). yoink disconnect openrouter --from qwen removes every entry whose envKey is YOINK_OPENROUTER_API_KEY, removes that variable from env, and clears model.name and selectedType only when the default was one of those models. Empty objects left behind are pruned.

Gotchas

  • QWEN_HOME. When it is set, yoink writes $QWEN_HOME/settings.json instead of ~/.qwen/settings.json.
  • Detection. Qwen Code counts as installed when the qwen binary is on your PATH or the config directory exists.
  • Import. yoink import groups hand-written entries by their envKey (or by host when there is none) and adopts them when the env block holds a literal key for that variable.
  • Restart Qwen Code after a change so it reloads settings.json.

FAQ

Why does yoink put my API key in the env block instead of each model?

Qwen Code looks up a model's key through its envKey. Writing the key once under YOINK_<PROVIDER>_API_KEY lets every model of that provider share it, and lets yoink find its own entries later.

Can I keep my own Qwen Code models next to the yoink ones?

Yes. yoink edits entries whose envKey uses its YOINK_ prefix and leaves the rest alone, with one exception: a hand-written entry with the same model id whose envKey resolves to this provider's exact key is adopted and rewritten. Other entries stay, as long as they do not use the same model id in the same group as a yoink provider.

  • Use OpenRouter in your coding agents

    Add your OpenRouter key once and yoink writes it into Claude Code, opencode, pi, Qwen Code, Crush and 7 more. Codex is not supported: no Responses endpoint.

  • One API key in every coding agent

    Add an API key once and yoink writes it into the native config of up to 13 coding agents: pi, opencode, codex, Claude Code, Qwen Code, Crush and more.

  • Harnesses

    What yoink writes into pi, omp, opencode, codex, Claude Code, Qwen Code, Kilo, Droid, Crush, Continue, Goose, Zed and Claude Desktop: paths and keys.

  • Use any provider in pi

    Connect any OpenAI- or Anthropic-compatible provider to pi. yoink writes ~/.pi/agent/models.json with model limits from models.dev and sets the default.

  • Use any provider in omp

    Connect a provider to omp. yoink writes ~/.omp/agent/models.yml (or models.yaml), carries over a legacy models.json and sets modelRoles.default in config.yml.

  • Use any provider in opencode

    Connect OpenRouter, DeepSeek, Ollama or any compatible API to opencode. yoink edits opencode.json or .jsonc in place, keeping your comments and formatting.