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.
The setup wizard
Section titled “The setup wizard”anchor setup, or /setup in a session, asks four things and writes the answers to the config:
- 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. - 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-toolon Linux, Credential Manager on Windows). Where there’s no keychain, such as over SSH or in a container, it goes in~/.anchor/credentialsinstead, a file only you can read. anchor’s tools can’t read that file, and its values are masked in command output. - The model: picked from the server’s
/modelslist, 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. - The colors: one of the themes, such as
lightfor 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.
Choosing a model
Section titled “Choosing a model”The model comes from, in order:
--model(or-m) on the command line,provider.modelin the config,- the default for the first API key that is set:
claude-sonnet-5forANTHROPIC_API_KEY, thengrok-4.5forXAI_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 |
Other OpenAI-compatible servers
Section titled “Other OpenAI-compatible servers”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-5A 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.
Context window
Section titled “Context window”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.
The anchor home directory
Section titled “The anchor home directory”Config, sessions and remembered MCP approvals live in ~/.anchor. Set ANCHOR_HOME to use another
directory:
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 |