Skip to content
Yoink

Use any provider in Zed

Zed's agent panel reads extra models from language_models in its settings.json, but it refuses to read an API key from that file. So yoink writes the provider block, edits the JSONC in place to keep your comments, sets agent.default_model, and leaves the key to an environment variable. Run yoink connect <name> --to zed.

On this page

At a glance

Zed facts
FactValue
Harness idzed
Config yoink writes~/.config/zed/settings.json
FormatJSONC
Protocols, in order of preferenceopenai-chat, openai-responses, anthropic-messages
Default modelagent.default_model: { provider, model }
Path overrideXDG_CONFIG_HOME
Providers at oncemany, side by side
Experimentalyes
Presets that reach it7 of 7: openai, kimi-code, moonshot, openrouter, deepseek, zai, ollama
Connect commandyoink connect <name> --to zed

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

What yoink writes

The block goes under openai_compatible or anthropic_compatible, keyed by the profile id. Here is the OpenRouter preset with --default z-ai/glm-4.7:

{
  "language_models": {
    "openai_compatible": {
      "openrouter": {
        "api_url": "https://openrouter.ai/api/v1",
        "available_models": [
          {
            "name": "z-ai/glm-4.7",
            "display_name": "GLM-4.7",
            "max_tokens": 204800,
            "max_output_tokens": 131072,
            "capabilities": {
              "tools": true,
              "parallel_tool_calls": false,
              "prompt_cache_key": false,
              "images": false,
              "chat_completions": true
            }
          }
        ]
      }
    }
  },
  "agent": {
    "default_model": { "provider": "openrouter", "model": "z-ai/glm-4.7" }
  }
}

max_tokens is the context window and max_output_tokens the output limit, both from the model data yoink keeps for the provider. In capabilities, yoink always sets images and chat_completions. It seeds tools: true, parallel_tool_calls: false and prompt_cache_key: false only the first time, so if you flip one of those three by hand, your value stays.

Three shapes, one per protocol

Zed accepts all three protocols, in the order Chat, Responses, Anthropic. Zed's API access docs describe both sections yoink uses.

Protocol yoink pickedSectionDifference
OpenAI Chatopenai_compatiblechat_completions: true
OpenAI Responsesopenai_compatiblechat_completions: false, the switch Zed documents for Responses-only models
Anthropic Messagesanthropic_compatibleapi_url without /v1, no capabilities block

Because Chat comes first, every preset except a Responses-only gateway lands as Chat, openai included. A custom gateway that answers only /responses gets the chat_completions: false shape. If a provider's endpoints change and it moves from one section to the other, yoink deletes the old block so the provider never appears twice.

Setting the key

yoink prints the variable name after connecting. It is the profile id in upper case, with every run of characters other than letters and digits turned into _, plus _API_KEY:

yoink connect openrouter --to zed --default z-ai/glm-4.7
export OPENROUTER_API_KEY="<your key>"

A provider saved as fuse reads FUSE_API_KEY. Zed has to inherit the variable, so launch it from a shell that exports it, or paste the key into the provider in Zed's agent settings instead. This step is why Zed is marked experimental: yoink cannot put the key where Zed reads it.

Paths and detection

  • Linux and macOS: ~/.config/zed/settings.json, or under $XDG_CONFIG_HOME/zed.
  • Windows: %APPDATA%\Zed\settings.json.

yoink counts Zed as installed when zed or zeditor is on your PATH, /Applications/Zed.app or /Applications/Zed Preview.app exists, or the config folder does.

Disconnect and backups

yoink disconnect openrouter --from zed removes the openrouter block from whichever section holds it, clears agent.default_model only when it names openrouter, and drops any section left empty. The first write keeps the original as settings.json.yoink.bak.

FAQ

Why is there nothing to import from Zed?

Zed never stores keys in settings.json, so a provider you configured there has no key yoink could adopt. yoink import skips Zed for that reason; add the provider with yoink add and connect it instead.

Will yoink reformat my settings.json?

No. yoink edits only the paths it owns inside the JSONC text, so your comments and the order of your other settings stay as they were.

  • 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 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.

  • Providers

    Add an API key once with yoink, from a preset (OpenAI, Kimi, OpenRouter, DeepSeek, z.ai, Ollama) or any compatible URL it probes, and pick its models.

  • 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.