Providers as data; add Ollama and Custom endpoints
Every gateway provider is now an entry in providers.json - endpoint and auth template, how its model list is read, how it is probed before a switch, what setup asks, which doctor checks apply, and its title, colour and logo - installed next to the presets and read by all three consumers: the bash CLI (through cm-json.py), the Windows script, and the bar widget (through health.json). anthropic stays built in; it is the native login, not a gateway. Behaviour that differs in kind stays in code, chosen by name from the entry: catalogue parsers (openrouter, lmstudio, ollama, openai, static), probe rules (always, lenient, local), and named doctor checks. A provider that reuses them is an entry and a default preset, with no code. The widget draws providers from health.json, so a new one needs no QML change and no shell restart. The existing three are unchanged in behaviour: their blank presets come out byte-identical from the file, and setup, doctor, models and the picker run the same checks through the generic paths. Ollama: local server on :11434, placeholder token, one model for every tier, models from /api/tags. doctor reads the context each loaded model actually runs with (/api/ps) and its maximum (/api/show), because Ollama defaults to 4096 tokens unless OLLAMA_CONTEXT_LENGTH is set and silently truncates past it. A bare model name matches its :latest tag. Custom: any Anthropic-compatible endpoint. Ships with no address and is refused until it has one; key optional; models from /v1/models when the endpoint has a list, and a lenient probe so a proxy without one is not blocked. Also: preflight (and Set-ClaudeMode on Windows) refuses a preset with no server address; the server form, setup and set-auth use each provider's own default URL, key name and placeholder token instead of LM Studio's; the Windows build gains the no-models and no-address guards it never had. Tested on Linux against fake Ollama/Custom servers, and on Windows 5.1 in a USERPROFILE sandbox on winbox. 1.12.0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
# claude-mode
|
||||
|
||||
Switch Claude Code system-wide between **Anthropic**, **OpenRouter**, **Z.AI**, and a
|
||||
local **LM Studio** server — with named per-tier model presets.
|
||||
Switch Claude Code system-wide between **Anthropic**, **OpenRouter**, **Z.AI**, a
|
||||
local **LM Studio** or **Ollama** server, and any **custom** Anthropic-compatible
|
||||
endpoint — with named per-tier model presets.
|
||||
|
||||
One write to `~/.claude/settings.json` covers the CLI, the VS Code extension, and
|
||||
the desktop app. Restart Claude Code afterwards — nothing else. Windows
|
||||
@@ -14,12 +15,16 @@ claude-mode anthropic # subscription login
|
||||
claude-mode openrouter # remote gateway (preset: default)
|
||||
claude-mode zai # Z.AI GLM coding plan (preset: zai)
|
||||
claude-mode lmstudio # local server (preset: lmstudio)
|
||||
claude-mode ollama # local server (preset: ollama)
|
||||
claude-mode custom # your own endpoint (preset: custom)
|
||||
```
|
||||
|
||||
**Contents:** [Install](#install) · [First run](#first-run) · [The interactive
|
||||
menu](#the-interactive-menu) · [Commands](#commands) · [Presets](#presets-shipped) ·
|
||||
[Context windows](#context-windows-and-early-auto-compaction) · [Z.AI](#zai-mode) ·
|
||||
[LM Studio](#lm-studio-mode) · [Live sessions](#live-sessions) ·
|
||||
[LM Studio](#lm-studio-mode) · [Ollama](#ollama-mode) · [Custom
|
||||
endpoints](#custom-endpoints) · [Adding a provider](#adding-a-provider) ·
|
||||
[Live sessions](#live-sessions) ·
|
||||
[Troubleshooting](#troubleshooting) · [Design decisions](#design-decisions) ·
|
||||
[Layout](#layout) · [Linux / Omarchy](#linux--omarchy) · [The bar
|
||||
widget](#the-omarchy-bar-widget) · [Uninstall](#uninstall)
|
||||
@@ -177,7 +182,9 @@ claude-mode status active mode, preset, model map
|
||||
claude-mode anthropic native login (deletes all managed keys)
|
||||
claude-mode openrouter [preset] default preset: default
|
||||
claude-mode zai [preset] default preset: zai (alias: z.ai, z-ai)
|
||||
claude-mode lmstudio [preset] default preset: lmstudio
|
||||
claude-mode lmstudio [preset] default preset: lmstudio (alias: lm-studio)
|
||||
claude-mode ollama [preset] default preset: ollama
|
||||
claude-mode custom [preset] default preset: custom
|
||||
|
||||
claude-mode presets list presets (* = active)
|
||||
claude-mode preset show <name>
|
||||
@@ -401,6 +408,98 @@ like every other credential — a real key on a public address is a real key.
|
||||
Nothing here changes the shipped presets unless you ask it to; the local default
|
||||
stays exactly as it was.
|
||||
|
||||
## Ollama mode
|
||||
|
||||
Ollama serves Anthropic's Messages API itself, at `/v1/messages`, so nothing sits
|
||||
in between. `claude-mode setup ollama` asks where the server is (it ships on
|
||||
`http://127.0.0.1:11434`), whether it needs a key, and picks one model for every
|
||||
tier from what the server has pulled. One model for all four is the right shape
|
||||
for a local server: it holds one in memory at a time, and mapping tiers to
|
||||
different models just means paying the load cost on every tier change. The token
|
||||
is a placeholder, `ollama`, which Ollama requires but does not check.
|
||||
|
||||
### The context window is set on the server
|
||||
|
||||
This is the part that bites. Ollama sizes the context on the server, not per
|
||||
request: **4096 tokens** unless `ollama serve` runs with `OLLAMA_CONTEXT_LENGTH`,
|
||||
and anything past it is cut off without an error. Claude Code's system prompt
|
||||
alone is most of that. Ollama recommends 64k or more for Claude Code, and the
|
||||
shipped preset declares 65,536 — but `contextTokens` only tells Claude Code what
|
||||
to expect. It cannot change what the server does.
|
||||
|
||||
```bash
|
||||
OLLAMA_CONTEXT_LENGTH=65536 ollama serve
|
||||
# or, for the systemd service: systemctl edit ollama
|
||||
# [Service]
|
||||
# Environment=OLLAMA_CONTEXT_LENGTH=65536
|
||||
```
|
||||
|
||||
`claude-mode doctor` reads what each loaded model is actually running with
|
||||
(`/api/ps`) and the model's own maximum (`/api/show`), and says so when either is
|
||||
below the preset. When nothing is loaded it cannot see the server's setting, and
|
||||
says that instead of guessing.
|
||||
|
||||
Also worth knowing:
|
||||
|
||||
- A bare name like `qwen3-coder` is `qwen3-coder:latest` to Ollama; both work.
|
||||
- Ollama does not implement `count_tokens` or prompt caching, so long sessions
|
||||
redo more work than they would on a hosted provider. Nothing breaks.
|
||||
- To reach it from another machine, serve it with `OLLAMA_HOST=0.0.0.0` and
|
||||
point the preset there: `claude-mode preset url ollama http://192.168.1.40:11434`.
|
||||
|
||||
## Custom endpoints
|
||||
|
||||
For anything else that speaks Anthropic's Messages API: a LiteLLM or Vercel
|
||||
gateway, vLLM, llama.cpp's server, a company proxy. The `custom` preset ships
|
||||
with no address — there is no sensible one to guess — and a switch to it is
|
||||
refused until it has one.
|
||||
|
||||
```bash
|
||||
claude-mode setup custom # asks for all of the below
|
||||
# or by hand:
|
||||
claude-mode preset url custom https://llm.example.com
|
||||
claude-mode preset auth custom key custom # the key lives in the vault as 'custom'
|
||||
claude-mode set-key custom
|
||||
claude-mode preset set custom opus <model-id> # ...and each other tier
|
||||
```
|
||||
|
||||
Several endpoints are several presets, each with its own address and key name:
|
||||
`claude-mode preset new work --provider custom --blank`, then
|
||||
`claude-mode preset auth work key work`.
|
||||
|
||||
The model list comes from `/v1/models` when the endpoint has one (OpenAI's shape
|
||||
or Anthropic's). Plenty of proxies serve Messages and nothing else. That is fine:
|
||||
the check before a switch only wants something to answer, and model ids can be
|
||||
typed by hand. The cost guard still applies. A custom endpoint in front of
|
||||
Anthropic's own models needs `"allowAnthropicModels": true` in the preset, which
|
||||
keeps it deliberate.
|
||||
|
||||
## Adding a provider
|
||||
|
||||
Every gateway provider is an entry in [`providers.json`](providers.json), installed
|
||||
next to the presets and read by the CLI, the bar widget (through `health.json`)
|
||||
and the Windows build. Anthropic is not in it: it is the native login, not a
|
||||
gateway. An entry holds:
|
||||
|
||||
| field | what it says |
|
||||
|---|---|
|
||||
| `id`, `aliases`, `title`, `label`, `blurb`, `color` | names and how the CLI, menu and panel show it |
|
||||
| `defaultPreset`, `preset` | the preset `claude-mode <id>` picks, and the template for a blank one (URL, auth, context, extra env) |
|
||||
| `server` | whether the address is editable, how it is probed before a switch (`always`, `lenient` for proxies, `local` only when it is on this machine), setup hint |
|
||||
| `catalogue.kind` | how its model list is read: `openrouter`, `lmstudio`, `ollama`, `openai` (`/v1/models`) or `static` (a list kept in the entry) |
|
||||
| `setup` | whether a key is required or optional, where to get one, and one model for every tier or one per tier |
|
||||
| `doctor` | which checks apply: `catalogue-models`, `openrouter-key`, `guardrail`, `message-check`, `ollama-context`, `lmstudio-templates` (Windows) |
|
||||
| `logo`, `logoScale` | a single-path 24×24 SVG mark, and its optical size correction |
|
||||
|
||||
A provider that reuses those kinds is an entry plus a default preset in
|
||||
`presets/`, and no code. A hosted Anthropic-compatible coding plan — Kimi,
|
||||
MiniMax, DeepSeek — is an entry shaped like `zai`, with its own URL and a
|
||||
`static` or `openai` catalogue. Only a genuinely new kind of behaviour, such as
|
||||
a catalogue format none of the parsers read, needs code: a parser in
|
||||
`cm-json.py`, and a branch in `provider_catalogue` (bash) and
|
||||
`Get-ProviderCatalogue` (Windows). The bar widget picks new providers up from
|
||||
`health.json` — no QML change, and no shell restart.
|
||||
|
||||
## Live sessions
|
||||
|
||||
### Why a switch breaks a running session
|
||||
@@ -719,6 +818,7 @@ Windows:
|
||||
```
|
||||
~/.claude-mode/
|
||||
claude-mode.ps1 main script
|
||||
providers.json what each gateway provider is (replaced on every install)
|
||||
state.json mode, active preset, and the exact env keys last written
|
||||
presets/*.json provider + model maps
|
||||
vault/*.cred DPAPI-encrypted keys (openrouter, zai, ...)
|
||||
|
||||
Reference in New Issue
Block a user