Skip to content

Configuration

anchor works with no config file when ANTHROPIC_API_KEY or XAI_API_KEY is set. To choose a model, add a provider, or configure MCP servers, run the setup wizard or create ~/.anchor/config.json:

{
"provider": { "model": "claude-sonnet-5" }
}

The file accepts comments and trailing commas. The full schema is in the config reference.

anchor setup, or /setup in a session, asks four things and writes the answers to the config:

  1. Where your models come from: Anthropic, OpenAI, xAI, or another server such as LiteLLM. For another server, it asks for the URL, a short name to use as <name>/<model>, and the name of the environment variable for its key.
  2. The API key: if the variable is already set, anchor uses it. Otherwise it links to the provider’s key page and you paste the key. anchor tries it before saving it, and asks again if the provider rejects it. It’s saved in the OS keychain (Keychain on macOS, secret-tool on Linux, Credential Manager on Windows). Where there’s no keychain, such as over SSH or in a container, it goes in ~/.anchor/credentials instead, a file only you can read. anchor’s tools can’t read that file, and its values are masked in command output.
  3. The model: picked from the server’s /models list, or typed if the server has no list. Move with ↑/↓ and press Enter; typing filters the list, and a name that matches nothing is used as typed.
  4. The colors: one of the themes, such as light for a light terminal background. Esc keeps the one you have.

anchor offers the wizard when you start it interactively with no model configured and no API key set. Running it again replaces the whole provider section with the new model (so a provider.endpoint, apiKeyEnv or contextWindow you set by hand is removed), updates the named provider for another server, and keeps the rest of your config. The config’s comments can’t be kept, so a commented file is first copied to config.json.bak.

A key saved by the wizard stands in for its environment variable: the one the model name implies (such as ANTHROPIC_API_KEY), or the apiKeyEnv saved on a named provider. When the variable is set, its value wins.

The model comes from, in order:

  1. --model (or -m) on the command line,
  2. provider.model in the config,
  3. the default for the first API key that is set: claude-sonnet-5 for ANTHROPIC_API_KEY, then grok-4.5 for XAI_API_KEY.

You can switch models mid-session with /model <name>. The conversation carries over.

anchor recognizes a model’s provider from its name:

Name starts with Provider API key
claude- Anthropic (native API, cached) ANTHROPIC_API_KEY
grok- xAI (OpenAI-compatible) XAI_API_KEY
gpt-, o1, o3, o4 OpenAI OPENAI_API_KEY

For any other model, such as one served by Ollama, vLLM or LM Studio, set the endpoint and the name of the environment variable that holds its key:

{
"provider": {
"model": "qwen3-coder",
"endpoint": "http://localhost:11434/v1",
"apiKeyEnv": "OLLAMA_API_KEY",
"contextWindow": 32768
}
}

The variable must be set, or have a key saved for it by anchor setup, even if the server ignores it (export OLLAMA_API_KEY=unused).

Named providers (LiteLLM and other proxies)

Section titled “Named providers (LiteLLM and other proxies)”

To reach several models through one server, such as a LiteLLM proxy at work, give the server a name under providers and write its models as <name>/<model>:

{
"providers": {
"work": {
"endpoint": "https://litellm.example.com/v1",
"apiKeyEnv": "LITELLM_API_KEY"
}
},
"provider": { "model": "work/claude-sonnet-5" }
}

Everything after the first / is sent to the server as the model name, so work/anthropic/claude-sonnet-5 asks for anthropic/claude-sonnet-5, and Bedrock-style ids such as work/anthropic.claude-sonnet-5 or work/xai.grok-4.6 are passed through unchanged. The same names work with --model, /model and a sub-agent’s model:, so you can switch between the proxy’s models mid-session:

/model work/gpt-5

A provider speaks the OpenAI chat completions API unless you set "type": "anthropic". headers adds request headers, with ${VAR} replaced from the environment, and apiKeyEnv can be left out when the server needs no key or authenticates through a header:

{
"providers": {
"work": {
"endpoint": "https://litellm.example.com/v1",
"headers": { "Authorization": "Bearer ${LITELLM_API_KEY}", "X-Team": "platform" },
"contextWindow": 128000
}
}
}

A name that doesn’t start with a configured provider is treated as before, so claude-sonnet-5 still goes straight to Anthropic.

anchor keeps the conversation under the model’s context window. It assumes 200,000 tokens for Claude, 256,000 for Grok 4, and 128,000 for anything else, going by the model name: any name containing claude- or grok-4 counts, so anthropic.claude-sonnet-5 and xai.grok-4.6 are recognized. Set provider.contextWindow, or contextWindow on a named provider, if your model’s window is different, especially for local models with small windows.

Config, sessions and remembered MCP approvals live in ~/.anchor. Set ANCHOR_HOME to use another directory:

Terminal window
ANCHOR_HOME=/tmp/anchor-scratch anchor
Path What it holds
config.json Your configuration
sessions/ Saved sessions, one JSONL file each
mcp-trust.json Your answers about project MCP servers
approvals.json “Always” answers saved per directory
skills/<name>/SKILL.md Your personal skills
agents/<name>.md Your personal sub-agents