feat(claude-vllm): own config file instead of reading opencode's
claude-vllm read `~/.config/opencode/opencode.jsonc` directly. Same shape is
useful; sharing the actual file is not — a credential rotation in opencode would
silently change what Claude Code authenticates with, and it couples two tools'
configs for no reason.
It now has its own `$XDG_CONFIG_HOME/mcpctl/claude-vllm.jsonc`, shaped like
opencode's (`provider.<name>.options.{baseURL,apiKey}` plus a `models` map), and
takes priority. The pi and prime-agent homes stay as a fallback so the command
works before any config exists; reading opencode's file is dropped.
No key is stored in the tool. `apiKey` may be a literal in the 0600 file,
`${ENV_VAR}`, or a bare env var NAME (the form pi's models.json already uses),
so the secret can live in the environment instead of on disk. `--init` reads it
from stdin when `--api-key` is omitted — keeping it out of shell history and out
of the process table, where an argument is visible to every user via `ps`.
`--list` prints at most a 10-character prefix.
`--init` records the context window for every model it can see, not just the
active one: recording only the default meant `--model something-else` silently
fell back to Claude Code's assumed 200k on a 393k model.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BVwuCjuMoA13gmzYEfcrNP
This commit is contained in:
@@ -43,21 +43,60 @@ sake: per-project gating of model calls, audit of prompts, or budget
|
||||
enforcement. Those are real features, but they are a passthrough endpoint in
|
||||
mcpd, not a wrapper script.
|
||||
|
||||
## What it discovers, and from where
|
||||
## Its own config
|
||||
|
||||
`claude-vllm` exists only so you don't paste four exports each time. It reuses
|
||||
whatever you already configured for another agent — first hit wins:
|
||||
```bash
|
||||
claude-vllm --init # prompts for the key, writes 0600
|
||||
claude-vllm --init --api-key '${MY_KEY}' # keep the secret in the environment instead
|
||||
claude-vllm --init --base-url https://other-gateway/v1
|
||||
```
|
||||
|
||||
Written to `$XDG_CONFIG_HOME/mcpctl/claude-vllm.jsonc` (`~/.config/…`), shaped
|
||||
like `opencode.jsonc` — a `provider` map with `options.baseURL` /
|
||||
`options.apiKey` and a `models` map:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"model": "itaz/deepseek-v4-think",
|
||||
"provider": {
|
||||
"itaz": {
|
||||
"options": { "baseURL": "https://llm.ad.itaz.eu/v1", "apiKey": "${MY_LLM_KEY}" },
|
||||
"models": { "deepseek-v4-fast": { "limit": { "context": 393216 } } }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Same shape as opencode's config, but a separate file.** Reading opencode's own
|
||||
config would mean a credential rotation there silently changing what Claude Code
|
||||
authenticates with, and would couple two tools' configs for no reason.
|
||||
|
||||
### Keys are never stored in the tool
|
||||
|
||||
`apiKey` may be a literal (in a 0600 file), `${ENV_VAR}`, or a bare env var
|
||||
NAME — so the secret can live in your environment or a password manager instead
|
||||
of on disk. `--init` reads the key from **stdin** when `--api-key` is omitted,
|
||||
keeping it out of shell history and out of the process table, where `--api-key`
|
||||
would be visible to every user via `ps`. `--list` never prints more than a
|
||||
10-character prefix.
|
||||
|
||||
### Discovery order
|
||||
|
||||
| Order | Source | Supplies |
|
||||
|-------|--------|----------|
|
||||
| 1 | environment (`ANTHROPIC_BASE_URL`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_MODEL`) | anything already set is respected |
|
||||
| 2 | `--provider` / `--model` flags | provider, model |
|
||||
| 3 | `~/.pi/agent` | `settings.json` → default provider/model · `models.json` → base URL, context window · `auth.json` → key |
|
||||
| 4 | `~/.prime/agent` | same shape |
|
||||
| 5 | `~/.config/opencode/opencode.jsonc` | `provider.<name>.options.{baseURL,apiKey}` |
|
||||
| 3 | `~/.config/mcpctl/claude-vllm.jsonc` | its own config |
|
||||
| 4 | `~/.pi/agent` | `settings.json` → default provider/model · `models.json` → base URL, context windows · `auth.json` → key |
|
||||
| 5 | `~/.prime/agent` | same shape |
|
||||
|
||||
The base URL and the credential always come from the *same* source, so one
|
||||
gateway's URL is never paired with another's key.
|
||||
The pi/prime homes remain a convenience fallback so `claude-vllm` works before
|
||||
you have written a config at all. The base URL and the credential always come
|
||||
from the *same* source, so one gateway's URL is never paired with another's key.
|
||||
|
||||
`--init` records the context window for **every** model it can see, not just the
|
||||
active one — otherwise `--model something-else` silently falls back to Claude
|
||||
Code's assumed 200k.
|
||||
|
||||
## What it sets, and why each one
|
||||
|
||||
|
||||
Reference in New Issue
Block a user