---
title: Kimi Provider
---

# Kimi Provider

## What it is

Omniscio supports spawning Claude-Code-style sessions backed by Moonshot's Kimi Anthropic-compatible API as an additional provider, alongside `claude` (the default), `codex`, `gemini`, `antigravity`, `deepseek`, `glm`, `minimax`, `cursor`, `hermes`, `pi`, `opencode`, and `openclaw`.

## Where to find it

**Settings → Accounts**, and only after **Show alternative AI providers** has been switched on there — the whole Kimi section is hidden until it is. A Kimi session then appears in the sidebar like any other, marked with the Kimi icon in its header.

## How it behaves

### What the user sees

A Kimi session looks identical in the sidebar and main pane to a Claude session — same status dots, same streaming bubbles, same Ctrl+Enter to send, same Plan / Auto-Accept / Bypass Permissions modes, same tool-call approval UI. The provider is invisible in normal chat. The only user-visible difference is the Kimi icon (a non-Claude provider mark, no text label) in the session header.

Tool-call behavior is **identical to Claude** because the same `claude` CLI binary is doing the talking — only the model and the upstream endpoint differ. There is **no yolo / auto-approve mode** like Gemini or Anti-Gravity; the standard Claude approval flow applies.

### How to enable

> **Master toggle required first.** Kimi is an alternative provider — by default Omniscio ships as a Claude-only product, and the entire Kimi setup section below is hidden in Settings → Accounts. Flip **Settings → Accounts → Show alternative AI providers** to ON (off by default) and the Kimi panel appears alongside Gemini, Codex, Anti-Gravity, and DeepSeek. With the master off, the per-project "Default provider" radio collapses to a single Claude row and the session header's provider switcher (ChangeProviderButton) hides Kimi — Kimi effectively does not exist in the UI even if every gate below is configured. Your saved API key and "Allow Kimi sessions" toggle are preserved across master-toggle flips.

You need two of these in place (note: no binary check — same `claude` binary as Claude). The opt-in **toggle leads and gates the key field** — the API key input appears only once Kimi is turned on, so a key can't be entered into a disabled provider (when off, a hint keeps the `kimi-api-key` Settings-search anchor landable and a saved key is preserved):

1. **Settings → Account → Allow Kimi sessions in any project** — opt-in toggle, off by default; same security stance as the Codex/Gemini spawn guards. Turning it on reveals the key field below.
2. **Settings → Account → Kimi → API key** — paste a Kimi API key from `platform.moonshot.ai` (encrypted at rest via Electron `safeStorage`).

**A key is one way to pay, not the only one.** Who pays for a Kimi session, and which company serves it, is Kimi's **supply list** in **Settings → Accounts → Who pays & who serves**. It holds your own Kimi key and **Omniscio credits** (signed-in, drawn from your prepaid balance) — so with no key saved, a Kimi session can still run on credits — and it can hold a DeepInfra row for Kimi K2.7 Code. A session connects through the first row that can serve. See [model-vendors.md](model-vendors.md).

Once both are green, you can launch a Kimi session in three ways:

- **Per-launch override** — on a fresh (zero-message) session, the **ChangeProviderButton** in the new session's main panel (the launch-config pickers on a fresh session) lets you pick a one-off provider before sending the first message. Non-ready providers appear `aria-disabled` with an "Add key…" / "Enable in Settings…" suffix and deep-link to the right Settings panel.
- **Per-project default** — Edit Project dialog (three-dot menu → Edit) has a "Default provider" section listing every enabled provider. Pick Kimi and the project's sidebar "+ New Session" button spawns Kimi automatically.
- **Programmatically** — anything that creates a session with `provider: 'kimi'` (recipes, agent-driven sessions, the CLI control HTTP API). Same readiness gates apply on the backend.

### Choosing the model

A fresh Kimi session lets you pick the model in the launch-config pickers (next to the provider chooser). The list is registry-driven (`MODELS_BY_PROVIDER.kimi` in [provider-models.ts](../../src/shared/providers/provider-models.ts)) and offers two models: **Kimi K3** (`kimi-k3`, **the default** — Moonshot's flagship 1M-context model for coding + knowledge work, live-verified 2026-07-20 to complete a real Claude Code turn) and **Kimi K2.7 Code** (`kimi-k2.7-code` — the proven 256K agentic coding model, kept as a selectable fallback). Either may be gated to higher account tiers, so a key without access surfaces a clear "model not supported". ⚠️ **`moonshot-v1-*` was removed from the picker (2026-06-27):** it passes a minimal model-acceptance check, but Moonshot rejects a full Claude Code session (which carries tool definitions) with a 400 "tokenization failed" error — so _every_ real turn on it failed, making it a useless option. A session or project still defaulted to `moonshot-v1-128k` is now refused **before** the (paid) spawn with a clear "no longer available — pick another" message, instead of failing every turn. The earlier `kimi-k2-0711-preview` ("Kimi K2") was discontinued by Moonshot 2026-05-25 and removed the same way. The pick is staged locally and applied when you send your first message. **Use default** spawns **`kimi-k3`** rather than omitting the model flag — Kimi _requires_ a real Moonshot id (the shared `claude` binary's built-in default is a Claude id that Moonshot 404s as "model not found"), so the registry pins one via `getProviderDefaultModel`. Kimi has no separate "reasoning effort" knob. The model list is Moonshot's own — a Kimi session never inherits your Claude default model (those are Claude ids its endpoint would reject). See [start-a-new-session.md](start-a-new-session.md).

### Per-project default

Each project remembers a default provider in the `projectDefaultProviders` setting (a `Record<projectId, ProviderId>`). Empty by default — every project falls back to Claude. Change it from the project's three-dot menu → Edit → Default provider radios; the change persists immediately.

When you set a project's default to Kimi but Kimi isn't ready (toggle off or key missing), an amber **"!" badge** appears on that project's sidebar row. Hover the badge for a tooltip explaining the gap; click it to deep-link straight to the right Settings panel. The badge re-checks on every render, so fixing the gap clears it without a refresh. Claude defaults never show the badge — Claude is always considered ready.

### Error states and fixes

Two gap codes — fewer than Gemini/Codex because there is no separate binary to check:

| Gap           | What it means                            | Click-to-fix lands you at…                      |
| ------------- | ---------------------------------------- | ----------------------------------------------- |
| `toggle-off`  | "Allow Kimi sessions" is OFF in Settings | Settings → Account → Allow Kimi sessions toggle |
| `key-missing` | No row of Kimi's supply list can serve (no Kimi key, and no other row ready) | Settings → Account → Kimi API key field, or Who pays & who serves |

**Retired / unavailable model (added 2026-06-15).** If a session's selected model is no longer accepted by Moonshot — either Omniscio has removed it from the picker (e.g. the discontinued `kimi-k2-0711-preview`) or the vendor killed a still-listed id server-side — Omniscio surfaces a clear _"this Kimi model is no longer available — open the model picker and choose another"_ and parks the session as `needs_you` / `recovery_failed`, instead of silently retrying the rejected request into the generic placeholder-stuck give-up loop (which never names the real model problem). Two guards back this: a **pre-spawn refusal** (the model isn't in the current picker list) and a **placeholder-stuck config-error guard** (an anthropic-compat session that produced no output and hit the rejected-request signature). See [provider-spawn-model-availability-contract.md](../../.claude/memory/contracts/provider-spawn-model-availability-contract.md).

**The real reason, not a blanket "model unavailable."** When Moonshot rejects a request mid-session for a reason other than the model — the account is out of balance, the conversation outgrew the context window, the key became invalid, or you're rate-limited — Omniscio reads Moonshot's actual error (carried on the zero-output synthetic placeholder, the same spot the Consumer-Terms gate reads) and shows the _specific_ cause + fix (recharge / start fresh or pick a larger-context model / check the key in Settings / wait a moment) instead of the generic "model no longer available — choose another," which is now reserved for a genuinely unknown/retired model. Message-only — the session still parks as `needs_you` / `recovery_failed`. See [provider-spawn-model-availability-contract.md](../../.claude/memory/contracts/provider-spawn-model-availability-contract.md) `vendor-error-is-classified-and-named`.

**Out-of-balance is also caught at turn-end (2026-07-04).** The reason-specific surfacing above reads Moonshot's error off the _zero-output_ synthetic placeholder. But if a Kimi turn streams some output and THEN Moonshot rejects it for non-payment (`Request rejected (429) — [1113][Insufficient balance … Please recharge.]`), that arrives on the turn _buffer_, not a placeholder — and previously fell through to the generic "this turn ended without a response." A dedicated turn-end gate now catches it there too and surfaces the same terminal _"your Kimi account is out of balance — recharge, then send your message again"_ error (routed to a red `error` status). See [vendor-model-config-400-surfacing-contract.md](../../.claude/memory/contracts/vendor-model-config-400-surfacing-contract.md) (its insufficient-balance sibling gate). **That stop is the last resort:** when Kimi's supply list has another row that can serve, running out of credit moves the session to that row and resends your message instead (see [model-vendors.md](model-vendors.md)).

### Cost tracking

Spend hits the standard `api_cost_log` table because the `claude` CLI emits per-turn cost events in its `stream-json` output and `process-manager.ts` already plumbs those into `trackApiCostRaw()`. The `source` field on the cost row carries the provider ID (`kimi`), so the Settings → Usage dashboard breaks down Kimi spend separately from Claude/Codex/Gemini.

**Cost is re-priced, not taken verbatim.** The `claude` binary has no Moonshot price table, so its `total_cost_usd` bills Kimi models at Claude rates. Kimi is therefore `costReporting: 'estimated'`, and Omniscio recomputes each turn from the token counts × Kimi's real rate (`MODEL_PRICING`) via `applyAnthropicCompatReprice` — the path shared by all four anthropic-compat vendors (DeepSeek/Kimi/GLM/MiniMax) — and, via the same `repriceAnthropicCompatTurnCost`, the human's one-shot aside side-questions too, which fork against the same Moonshot endpoint and so carry the identical Claude-rate mis-price. See [central-ai-spend-contract.md](../../.claude/memory/contracts/central-ai-spend-contract.md) `anthropic-compat-cost-is-repriced`.

**Prompt-cache reads bill at the real cache-hit rate.** The legacy `kimi-k2.7-code` reads from cache at Moonshot's published **$0.19/M** — a `cacheRead` override on its `MODEL_PRICING` row, not the flat 0.1×-input default. The flagship `kimi-k3` needs no override: its real cache-hit rate ($0.30/M) already IS 0.1× of its $3/M input, so the default prices it correctly.

Telemetry: every successful Kimi spawn fires the `spawn_non_claude_session` feature event, recording `{ provider: 'kimi' }` only — no session ID, project ID, or prompt content.

## For agents

### How it works under the hood

**Spawn-env redirect, no alternate manager.** Moonshot publishes an Anthropic-compatible API for Kimi — same request/response shape as Anthropic's Messages API, just at a different base URL. So Omniscio reuses the existing `claude` CLI binary (the same one Claude sessions use) and redirects every HTTP call at spawn time by setting two environment variables on the child process:

- `ANTHROPIC_BASE_URL=https://api.moonshot.ai/anthropic` — sends every HTTP request to Moonshot's compat endpoint instead of `api.anthropic.com`.
- `ANTHROPIC_AUTH_TOKEN=<your Kimi API key>` — supersedes the Claude OAuth/API-key for this child only.

The child process never knows it isn't talking to Anthropic. Streaming, tool calls, `--resume` for multi-turn, `--output-format stream-json` parsing all "just work" because they're handled by the standard `claude` binary against an upstream that speaks the same protocol.

No alternate session manager exists for Kimi — `session-handlers.ts` gates readiness, fires the `spawn_non_claude_session` feature event, then falls through to the same `createSessionWithPrompt()` path Claude sessions use. The `provider: 'kimi'` value is stored on the session row in the database; `process-manager.ts` reads that column and injects the right spawn-env on every CLI invocation (initial spawn, resume, aside-runner).

Compared to:

- **DeepSeek** — same shape (Anthropic-compat, no binary, spawn-env redirect). The only differences are the vendor base URL and the credential field. The Phase 2 code path branches `effectiveProvider === 'deepseek' || effectiveProvider === 'kimi'` and treats them identically downstream.
- **Codex / Anti-Gravity** — separate CLI binaries with their own protocols; need dedicated `*-session-manager.ts` files. Kimi does not.
- **Gemini** — a long-lived `gemini --acp` ACP child per session (its own JSON-RPC protocol). Kimi keeps the long-lived `claude` child process; resume via `claude --resume <uuid>`.
- **OpenClaw** — remote WebSocket gateway. Kimi is plain HTTP to a vendor-hosted compat endpoint.

### Files

- [src/main/services/provider-setup/provider-readiness.ts](../../src/main/services/provider-setup/provider-readiness.ts) — single source of truth for the 2-gate readiness check (used by ChangeProviderButton, Edit Project radios, project-row cue, spawn guard)
- [src/main/process/process-manager.ts](../../src/main/process/process-manager.ts) — injects `ANTHROPIC_BASE_URL` + `ANTHROPIC_AUTH_TOKEN` per session row's `provider` column
- [src/main/ipc/session-handlers.ts](../../src/main/ipc/session-handlers.ts) — DeepSeek/Kimi spawn branch that gates readiness, fires the analytics event, and falls through to the claude path
- [src/shared/types.ts](../../src/shared/types.ts) — `ProviderId` union, `kimiApiKey`, `allowKimiSessionSpawn` setting fields
- [src/renderer/src/features/settings/sections/accounts/AccountSettings.tsx](../../src/renderer/src/features/settings/sections/accounts/AccountSettings.tsx) — Kimi section under "Show alternative AI providers"

## Related

- [deepseek-provider.md](deepseek-provider.md) — same shape (Anthropic-compat, no binary, spawn-env redirect), different vendor + key
- [model-vendors.md](model-vendors.md) — who pays for a Kimi session and which company serves it (the supply list)
- [gemini-provider.md](gemini-provider.md) — alt-CLI provider with per-turn spawn model
- [codex-provider.md](codex-provider.md) — alt-CLI provider with long-lived JSON-RPC child
- [ai-providers.md](ai-providers.md) — landing page for the full provider matrix
