Kin / Reference
Provider presets
How to pick a curated API provider without memorising URLs, model ids, or auth headers — and how to extend the catalogue with custom endpoints.
Read as MarkdownHow to pick a curated API provider without memorising URLs, model ids, or auth headers — and how to extend the catalogue with custom endpoints.
What a preset gives you
A preset bundles provider identity, the wire, endpoint selection, and—when
curated—the default model id. The direct OpenAI/Anthropic rows deliberately
leave the endpoint and model at their SDK/operator defaults so a model route can
name an exact account-available model. Auth is bundled too: MiniMax and Z.ai
send Authorization: Bearer <key>. The preset chooses the correct form so only
one authentication header rides the request.
A preset folds into the override chain via setdefault semantics — an
explicit CLI flag, env var, or file entry always wins over the preset’s
default for the same knob. The preset never silently overwrites something
you set.
Host-scheduled kin -p runs use the same local provider and route
configuration as other Kin processes. A scheduler may select documented
one-run CLI or environment overrides.
Built-in presets
| id | label | wire API | base_url |
default model | models | key_url |
|---|---|---|---|---|---|---|
openai |
OpenAI | Chat (Responses selectable) | SDK default (api.openai.com) |
explicit | explicit | https://platform.openai.com/api-keys |
anthropic |
Anthropic | Messages | SDK default (api.anthropic.com) |
explicit | explicit | https://console.anthropic.com/settings/keys |
minimax |
MiniMax | Messages | https://api.minimax.io/anthropic |
MiniMax-M3[1m] (1M ctx) |
MiniMax-M3[1m], MiniMax-M3, MiniMax-M2.7, MiniMax-M2.7-highspeed, MiniMax-M2.5, MiniMax-M2.5-highspeed, MiniMax-M2.1, MiniMax-M2.1-highspeed, MiniMax-M2 |
https://api.minimax.io/usercenter/charge |
zai |
Z.ai | Messages | https://api.z.ai/api/anthropic |
glm-5.3-flash (1M ctx) |
glm-5.3-flash, glm-5.3, glm-5-turbo, glm-4.7 |
https://z.ai/manage-apikey/apikey-list |
The direct rows are primarily stable trust handles for
model_routes. Set their exact model in
the route (or use the legacy top-level model setting); Kin does not pretend
that every account has one universal OpenAI/Anthropic model catalogue. In
/providers openai or /providers anthropic, enter an exact model to switch the
MCA too, or leave the model blank after pasting a key to save that credential
for future routed calls without changing the live MCA backend. Running children
retain the prior route snapshot.
The OpenAI row exposes a Wire API selector. Chat Completions is selected by
default for broad compatibility; choose Responses only for an endpoint you
intend to use through that API. Saving the row persists wire_api and swaps
the live backend. Selecting Anthropic clears a stale OpenAI wire choice because
Messages is implied internally by the provider.
Cloud-plan subagent capacity
/providers minimax and /providers zai also show the subscription plan.
The saved provider_tiers choice sizes ordinary foreground and background
subagent capacity for every session on that provider; local and custom
endpoints keep the conservative default of 3.
The official kinra-api connection sizes itself from the service instead:
the gateway advertises its enforced per-credential admission cap in the model
profile, and the profile refresh writes subagent_limit = cap − 1 (the root
session keeps a slot) under the same pin-aware rules as every other managed
value — a hand-set subagent_limit on the row always wins, and an older
gateway leaves the default 3 in place. Dynamic admission (429 +
Retry-After + the capacity scope header) stays authoritative either way
(DR 0206).
| Provider plan | Kin max parallel/background agents | Basis |
|---|---|---|
| MiniMax Plus (default) | 4 | Provider publishes 3–4 concurrent agents |
| MiniMax Max | 5 | Provider publishes 4–5 |
| MiniMax Ultra | 7 | Provider publishes 6–7 |
| Z.ai Lite (default) | 4 | Conservative Kin ceiling; provider manages concurrency dynamically |
| Z.ai Pro | 5 | Conservative Kin ceiling; live-gated at five concurrent calls |
| Z.ai Max | 7 | Conservative Kin ceiling; provider still owns dynamic throttling |
MiniMax’s values follow its Token Plan comparison.
Z.ai documents only the ordering Max > Pro > Lite, recommends subagents, and
states that actual limits vary with capacity in its Coding Plan usage policy.
Kin’s Z.ai numbers are therefore client-side runaway guards, not promises about
the service. A provider rate-limit response still follows the normal bounded
retry path.
Z.ai Coding Plan tool policy
Z.ai’s current usage policy says Coding Plan benefits are limited to its supported tools and may be restricted when used elsewhere. Kin speaks the documented compatible endpoint but is not an endorsement or entitlement guarantee; review Z.ai’s current supported-tool list before relying on a Coding Plan subscription here.
The Anthropic-preset rows (MiniMax, Z.ai) both carry thinking.type. MiniMax
M3 documents the adaptive / enabled / disabled tri-state (M2.x silently
ignores disabled) as its depth control. The GLM-5.3 family always reasons;
on Z.ai’s Messages endpoint, Kin sends the documented max / high / low
depth through output_config.effort, while thinking.type remains the
thinking toggle. The /effort picker uses those provider-real paths — see
/effort and the
Effort picker table. The
construction-time default stays adaptive (change with
KIN_THINKING_TYPE=... env or thinking_type = "..." in settings.toml, or
flip live with /settings on).
Note
The
[1m]suffix means opposite things on the two presets. Z.ai: the suffix is a Claude Code SDK convention, not a wire-level model id — a raw SDK call with it returnsmodel_not_found. Use a plain model id such asglm-5.3-flash; Kin pins the catalogued GLM-5.3 and GLM-5.3-Flash ids to their documented 1M context windows. MiniMax:MiniMax-M3[1m]is the documented wire-level long-context id (1,048,576 tokens) — plainMiniMax-M3only guarantees 512K. Kin defaults to the live-verified[1m]id; pick the plain id only when you deliberately want the smaller window.
MiniMax Token Plan keys
MiniMax’s flat-rate Token Plan uses a distinct Subscription Key that is explicitly not interchangeable with pay-as-you-go API Keys. Both ride the same header on the same URL, so the harness cannot tell which kind you pasted — a wrong-kind key fails (or draws the wrong balance) in a way that looks like a harness bug but isn’t. Z.ai has no such split: once the account owns a GLM Coding Plan, the Anthropic-compat endpoint bills against it automatically.
Kin recognizes each provider’s subscription error codes too. Exhausted MiniMax 5-hour windows and exhausted/expired Z.ai Coding Plans are reported as non-retryable with the reset/renewal action; bad keys name the correct key kind; temporary Z.ai overload remains retryable with bounded backoff, while fair-use and package-type restrictions point to the provider console instead of retrying.
Connections in /models
The complete key-entry walkthrough and provider screenshot live in Connect a
model and first run.
This page records the catalogue contract: /models connections lists built-ins
and custom rows, stages provider-specific credentials and fields, and applies
the complete configuration fail-closed. /providers [name] is a deep link to
that section and preselects the named connection.
From the shell, kin connect creates or
re-keys one custom OpenAI-compatible connection and activates it without
opening the TUI — the key comes from a masked prompt, never argv or the
environment, and the write goes through the same locked hub transaction. Its
--vision-route flags can additionally create and assign a hosted vision
route on the same connection in that one save.
Stored keys and extra-header values are never loaded into the form. Status and masked placeholders show what exists; blank retains, replacement is explicit, and removal requires confirmation. Check connection calls only the authenticated models endpoint, never generates output, and can import its bounded sanitized model ids into a custom connection draft. A failed check does not block saving.
Search credentials stay separate
/web-search shows hosted retrieval and the optional local Brave override.
Search credentials are separate from model credentials; changing one does not
change the other. The web guide
owns activation, local precedence, and hosted device-scope requirements.
/models vs /model
Persistent policy and current-session selection remain separate:
| Surface | When to use | Writes |
|---|---|---|
/models (/providers deep link) |
Stage connections, credentials, jobs, routes, and assignments as one transaction | The existing provider/route/assignment schema, atomically |
/model <id> (inline) |
Swap to a model id you already know; silent when a key resolves, else a one-field key prompt opens at the point of need | provider_preset + model; a prompted key lands via the hub’s locked transaction |
/model (bare, picker) |
Browse across providers with the keyboard; the ✓ key badge shows which are ready, unkeyed picks prompt inline |
provider_preset + model; a prompted key lands via the hub’s locked transaction |
/models validates and prepares the full catalog before
save_model_configuration(...), then shares /reload’s application path.
When a /model pick has no resolvable key, the inline prompt collects one and
commits it through that same locked transaction before swapping — esc cancels
the swap and writes nothing.
Other surfaces
Three surfaces reach the same preset machinery, in this precedence order:
| Surface | Example | When to use |
|---|---|---|
| CLI flag | uv run kin --preset minimax |
A one-off override (highest precedence) |
| Env var | KIN_PRESET=zai uv run kin |
A shell-level override (above the file) |
| Settings key | provider_preset = "minimax" in ~/.kin/settings.toml |
Persistent baseline |
The modal writes the file layer and swaps the live backend in place.
The file is still what new sessions read; /reload re-applies an
edited settings.toml to a running session without a restart too.
A top-level base_url and model do not create a catalog row. Add a [[providers]] entry if you want to return to that endpoint through the model picker after switching away. Auth-less local rows can omit a key.
Custom endpoints
The modal’s Custom endpoint… path writes the [[providers]] schema shown
below. The task flow is in First
run; this is
the field reference for catalogue maintainers and managed configurations.
[[providers]]
id = "openrouter"
label = "OpenRouter"
provider = "openai"
wire_api = "chat" # or "responses" (explicit opt-in)
base_url = "https://openrouter.ai/api/v1"
default_model = "anthropic/claude-3.7-sonnet"
models = ["anthropic/claude-3.7-sonnet"]
# extra_headers = { "X-Tenant-ID" = "acme" } # optional
# reasoning_effort = "high" # optional endpoint default; on a
# # Responses row also opts the stream
# # into reasoning-summary deltas
Built-in ids take precedence over custom duplicates. Give a custom endpoint
a distinct id; /providers openrouter then opens that row directly.
wire_api is optional on an OpenAI row and defaults to chat. Its only public
values are chat and responses; either implies provider = "openai". Do not
put wire_api on an Anthropic row—Messages is selected by the provider. Invalid
providers, wire values, and Anthropic/OpenAI-wire combinations are rejected
instead of guessed.
Row keys: model vs default_model vs models
The three keys do different things, and a row that confuses them renders
an empty group in /model (the header shows but there’s nothing to pick):
| Key | What it does |
|---|---|
default_model |
The model id the factory pre-fills when this preset is active and no other model was set. Also seeds models if no models list was given (see below). |
models |
The catalogue the /model picker iterates for this row. Multiple ids → multiple pickable rows. |
model |
Convenience alias for default_model — same key, just shorter. Honored ONLY when default_model is unset. Useful for one-line rows like a vLLM stable-alias setup: model = "default". |
Two safety nets so the one-line shape still surfaces a pickable row:
model = "default"is accepted as an alias fordefault_model.- When neither
modelsnordefault_modelis set, butmodelis, the model id seedsmodels = (model,)too — the picker renders one row.
# Minimal: single-model / stable-alias custom endpoint.
[[providers]]
id = "vllm"
label = "vLLM (staged serve)"
provider = "anthropic"
base_url = "http://model-host:8000/v1"
model = "default" # alias for default_model; seeds models = ["default"]
reasoning_profile = "poolside" is the one model-family-specific row key.
It is accepted only with provider = "anthropic" and makes /effort use
Laguna’s chat_template_kwargs.enable_thinking control while preserving
signed reasoning across tool rounds. It is deliberately explicit: Kin never
guesses a request profile from a model id or hostname. See
Laguna S 2.1 on vLLM.
If you want the picker to show every model your server actually serves, prefer the explicit two-key form — or wire /providers’s “Custom endpoint…” form, which writes both default_model and (when known) models for you.
The curated catalogue is not a silent cap
The built-in lists cover the verified ids from each provider’s official docs. A model id not in the catalogue is still reachable:
KIN_MODEL=<id> uv run kin(overrides the preset’s default)--model <id>(CLI override)- A
[[providers]]row that names it
The catalogue is the curated subset the harness is willing to ship defaults for; nothing stops you from picking another model id on the same wire.
Preset auth is provider-specific
MiniMax and Z.ai send
Authorization: Bearer <key>because both reject the Anthropic SDK’s defaultX-Api-Keyheader. The factory routes the resolved key into the SDK’sauth_token=slot (notapi_key=) so only Bearer rides the wire. A non-presetAnthropicBackend(api_key=...)still uses x-api-key as before — no behaviour change for users who aren’t using presets.
The GLOBAL_ONLY safety boundary
provider_preset and providers are global-only keys — honored from
the global file, the environment, or a CLI flag, but stripped (with a
warning) from any project .kin/settings.toml. A cloned repo’s project
file can’t silently retarget your wire to a third-party endpoint and
silently route your global api_key through it. The threat model is
identical to base_url / api_key being global-only — see
settings.toml keys for the rest of the
denylist and the rationale.