Full compaction slices the raw history, which can exclude a delayed tool result and leave its tool_use open in the compacted prefix, triggering the same strict-provider 400 on the summary request. Synthesize a placeholder tool_result for such calls when projecting the compacted prefix. Also sync the micro_compaction default to false in the en/zh configuration and env-var docs.
16 KiB
Configuration files
Kimi Code CLI writes all long-term preferences — which model to use, which API key to fill in, how many steps an Agent can run per turn — into TOML (a plain-text configuration format with a clear structure) files. Change them once and they take effect on every startup. Agent and runtime settings live in config.toml; terminal-UI and client preferences (theme, editor, notifications, auto-update) live in a companion tui.toml.
Default location: ~/.kimi-code/config.toml, created automatically on first run.
Config file location
The CLI reads configuration from ~/.kimi-code/config.toml. To relocate the data directory, override it with the KIMI_CODE_HOME environment variable:
export KIMI_CODE_HOME=/path/to/kimi-home
The config file path then becomes $KIMI_CODE_HOME/config.toml. Regardless of where the directory lives, the file name is always config.toml.
::: tip
TOML field names always use snake_case, for example default_model and max_context_size. If a key contains ., you must quote it — for example [models."gpt-4.1"] — otherwise TOML treats . as a nested table separator.
:::
Complete example
The following example covers the most commonly used configuration fields. You can copy it and adjust as needed:
default_model = "kimi-code/kimi-for-coding"
default_thinking = true
default_permission_mode = "manual"
default_plan_mode = false
merge_all_available_skills = true
telemetry = true
[providers."managed:kimi-code"]
type = "kimi"
base_url = "https://api.kimi.com/coding/v1"
api_key = ""
[models."kimi-code/kimi-for-coding"]
provider = "managed:kimi-code"
model = "kimi-for-coding"
max_context_size = 262144
[thinking]
mode = "auto"
[loop_control]
max_retries_per_step = 3
reserved_context_size = 50000
[background]
max_running_tasks = 4
keep_alive_on_exit = false
[experimental]
micro_compaction = false
[[permission.rules]]
decision = "allow"
pattern = "Read"
[[permission.rules]]
decision = "deny"
pattern = "Bash(rm -rf*)"
[[hooks]]
event = "PreToolUse"
matcher = "Bash"
command = "node ~/.kimi-code/hooks/check-bash.mjs"
timeout = 5
Top-level fields
Fields in the config file fall into two categories: top-level scalars that directly control default behavior, and nested tables (providers, models, thinking, etc.) that each have their own structure, described individually in the sections below.
| Field | Type | Default | Description |
|---|---|---|---|
default_model |
string |
— | Default model alias; must be defined in models |
default_thinking |
boolean |
false |
Whether new sessions enable Thinking (deep reasoning) mode by default; can be toggled from the model menu inside a session. Even when set to true, [thinking].mode = "off" will still force Thinking off |
default_permission_mode |
string |
manual |
Default permission mode for new sessions; one of manual (prompt each time), auto (auto-approve read operations), or yolo (auto-approve everything) |
default_plan_mode |
boolean |
false |
Whether new sessions start in Plan mode (produce a plan before executing) by default |
merge_all_available_skills |
boolean |
true |
Whether to merge Agent Skills from all available directories |
extra_skill_dirs |
array<string> |
— | Extra skill search directories, layered on top of the default directories |
telemetry |
boolean |
true |
Whether anonymous telemetry is enabled; disabled only when explicitly set to false |
providers |
table |
{} |
API provider table → providers |
models |
table |
— | Model alias table → models |
thinking |
table |
— | Default parameters for Thinking mode → thinking |
loop_control |
table |
— | Agent loop control parameters → loop_control |
background |
table |
— | Background task runtime parameters → background |
experimental |
table |
— | Experimental feature overrides → experimental |
services |
table |
— | Built-in external service configuration → services |
permission |
table |
— | Initial permission rules → permission |
hooks |
array<table> |
— | Lifecycle hooks; see Hooks |
The following sections cover each of the nested tables in turn: providers, models, thinking, loop_control, background, experimental, services, and permission.
providers
Each entry in the providers table defines an API provider, keyed by a unique name. The CLI reads credentials only from here — it does not fall back to shell environment variables automatically. Running export KIMI_API_KEY in the terminal does not give any provider its key; you must write it explicitly in the config file (see Config overrides).
| Field | Type | Required | Description |
|---|---|---|---|
type |
string |
Yes | Provider type: kimi, anthropic, openai, openai_responses, google-genai, vertexai |
api_key |
string |
No | API key, written in plain text in the config file |
base_url |
string |
No | API base URL |
oauth |
table |
No | OAuth credential reference (storage and key fields); injected automatically by the login flow — normally no need to write this by hand |
env |
table<string, string> |
No | Fallback source for provider credentials; see below |
custom_headers |
table<string, string> |
No | Custom HTTP headers attached to each request |
env sub-table: You can write provider-conventional key names (such as KIMI_API_KEY) inside [providers.<name>.env] as a fallback source for api_key / base_url. This sub-table is read only from the config file and does not modify the shell environment:
[providers.kimi.env]
KIMI_API_KEY = "sk-xxx"
KIMI_BASE_URL = "https://api.moonshot.ai/v1"
Priority: api_key field > env sub-table key > if both are absent, startup fails with an error.
models
Each entry in the models table defines a model alias (the name used in default_model or the -m flag), keyed by a unique name.
| Field | Type | Required | Description |
|---|---|---|---|
provider |
string |
Yes | Name of the provider to use; must be defined in providers |
model |
string |
Yes | Model identifier sent to the server when calling the API |
max_context_size |
integer |
Yes | Maximum context length in tokens; must be at least 1 |
max_output_size |
integer |
No | Per-request output token cap (maps to max_tokens). Currently only the anthropic provider honors it; recognized Claude models are automatically clamped to the server-side maximum |
capabilities |
array<string> |
No | Capability tags to add explicitly: thinking, image_in, video_in, audio_in, tool_use. Unioned with the capabilities auto-detected by the provider — entries can only be added, never removed |
display_name |
string |
No | Name shown in the UI; falls back to model when unset |
reasoning_key |
string |
No | openai provider only. Override the field name used for reasoning content when the gateway returns it under a non-standard name; by default reasoning_content, reasoning_details, and reasoning are auto-detected |
adaptive_thinking |
boolean |
No | anthropic provider only. Force adaptive thinking on or off, overriding the version inference based on the model name. Omit to infer automatically (Claude ≥ 4.6 uses adaptive) |
When an alias contains ., use a quoted key:
[models."gpt-4.1"]
provider = "openai"
model = "gpt-4.1"
max_context_size = 1047576
You can also switch models temporarily without touching the config file — by setting KIMI_MODEL_* environment variables, the CLI synthesizes a temporary provider in memory that does not persist after restart. See Define a model from environment variables.
thinking
thinking sets the global default behavior for Thinking mode. mode = "off" forces Thinking off even when the top-level default_thinking = true.
| Field | Type | Default | Description |
|---|---|---|---|
mode |
string |
— | Trigger policy: auto (decided by the model), on (always on), off (force off) |
effort |
string |
high |
Thinking effort level: low, medium, high, xhigh, max; the levels actually available depend on the provider |
loop_control
loop_control governs the step count limit, per-step retry count, and the threshold that triggers automatic context compaction in the Agent execution loop.
| Field | Type | Default | Description |
|---|---|---|---|
max_steps_per_turn |
integer |
— | Maximum steps per turn; unset or 0 means unlimited |
max_retries_per_step |
integer |
3 |
Maximum retries after a step failure |
reserved_context_size |
integer |
— | Number of tokens reserved for model output; automatic compaction is triggered when the remaining context window falls below this value |
background
background controls the concurrency behavior of background tasks (launched via the Bash tool or the Agent tool's run_in_background=true parameter).
| Field | Type | Default | Description |
|---|---|---|---|
max_running_tasks |
integer |
— | Maximum number of background tasks running concurrently |
keep_alive_on_exit |
boolean |
false |
Whether to keep still-running background tasks when the session closes. By default, Kimi Code requests that all background tasks stop before the process exits; set this to true only when you want tasks to outlive the session |
keep_alive_on_exit can be overridden by the KIMI_CODE_BACKGROUND_KEEP_ALIVE_ON_EXIT environment variable, which takes higher priority than config.toml.
experimental
experimental stores persistent overrides for experimental-feature flags. Currently, micro_compaction is the only user-facing entry and defaults to false; set it to true to enable automatic trimming of older large tool results.
| Field | Type | Default | Description |
|---|---|---|---|
micro_compaction |
boolean |
false |
Trim older large tool results from context while preserving recent conversation |
services
services configures two built-in services: web search (moonshot_search) and web fetch (moonshot_fetch). Only these two fixed keys are recognized; other keys are ignored. Both entries share the same fields:
| Field | Type | Required | Description |
|---|---|---|---|
base_url |
string |
No | Service API URL |
api_key |
string |
No | API key |
oauth |
table |
No | OAuth credential reference, same structure as providers.*.oauth |
custom_headers |
table<string, string> |
No | Custom HTTP headers attached to each request |
[services.moonshot_search]
base_url = "https://api.moonshot.cn/v1/search"
api_key = "sk-xxx"
[services.moonshot_fetch]
base_url = "https://api.moonshot.cn/v1/fetch"
api_key = "sk-xxx"
permission
permission sets permission rules that are automatically loaded when a session starts, controlling whether the Agent needs user confirmation before calling a tool. Rules are written as a [[permission.rules]] array of tables, matched in order — the first matching rule takes effect.
| Field | Type | Required | Description |
|---|---|---|---|
decision |
string |
Yes | Action on match: allow (permit immediately), deny (reject immediately), ask (prompt each time) |
scope |
string |
No | Rule scope: turn-override, session-runtime, project, user; defaults to user |
pattern |
string |
Yes | Match pattern in the form ToolName or ToolName(arg-pattern), e.g. Read or Bash(rm -rf*) |
reason |
string |
No | Rule description for debugging and auditing |
Built-in tool names are listed in Built-in tools. Most built-in tools that accept rule arguments define their own matching subject, such as Bash(command-pattern) or Read(path-pattern). AgentSwarm, MCP tools, and custom tools can only be matched by tool name — argument patterns are not supported for them.
[[permission.rules]]
decision = "allow"
pattern = "Read"
[[permission.rules]]
decision = "allow"
pattern = "Grep"
[[permission.rules]]
decision = "deny"
pattern = "Bash(rm -rf*)"
[[permission.rules]]
decision = "ask"
pattern = "Bash"
::: tip
MCP server declarations are configured in ~/.kimi-code/mcp.json or the project-local .kimi-code/mcp.json, not in config.toml. The interactive configuration entry point is /mcp-config; see Model Context Protocol.
:::
tui.toml
Alongside config.toml, the CLI keeps terminal-UI and client preferences in a companion tui.toml in the same directory (~/.kimi-code/tui.toml, or $KIMI_CODE_HOME/tui.toml when overridden). It is created with defaults on first run, and the interactive commands /config, /theme, and /editor write to it for you — so you rarely need to edit it by hand. If the file is malformed, the CLI falls back to defaults and shows a notice instead of failing to start.
| Field | Type | Default | Description |
|---|---|---|---|
theme |
string |
auto |
Color theme: auto (follow the terminal), dark, light, or the name of a custom theme |
[editor].command |
string |
"" |
External editor command for composing long input; empty falls back to $VISUAL / $EDITOR |
[notifications].enabled |
boolean |
true |
Whether desktop notifications are sent |
[notifications].notification_condition |
string |
unfocused |
When to notify: unfocused (only when the terminal is not focused) or always |
[upgrade].auto_install |
boolean |
true |
Whether new versions are installed automatically |
# ~/.kimi-code/tui.toml
theme = "auto" # "auto" | "dark" | "light" | custom theme name
[editor]
command = "" # empty uses $VISUAL / $EDITOR
[notifications]
enabled = true
notification_condition = "unfocused" # "unfocused" | "always"
[upgrade]
auto_install = true
Changes apply on the next start, or immediately with /reload-tui (which reloads only tui.toml); /reload reloads both config.toml and tui.toml.
Project-local configuration
In addition to the user-level files under ~/.kimi-code, Kimi Code reads a project-local configuration file at <project-root>/.kimi-code/local.toml. It holds settings that are specific to one project checkout and typically should not be shared with teammates.
The file is created automatically when you add an extra workspace directory with /add-dir and choose to remember it for the project. You rarely need to edit it by hand.
[workspace]
The [workspace] table groups project-level workspace settings:
| Field | Type | Required | Description |
|---|---|---|---|
additional_dir |
array<string> |
No | Additional workspace directories, stored as absolute paths. Written automatically when you confirm "remember this directory" in /add-dir; read back on startup so the directories are available in every session of this project |
[workspace]
additional_dir = ["/absolute/path/to/shared"]
Because directories are stored as absolute paths, which are specific to your machine, we recommend adding .kimi-code/local.toml to your project's .gitignore so it is not committed.
Next steps
- Providers and models — connection examples for each provider type (Kimi, Claude, OpenAI, Gemini)
- Config overrides — priority rules for CLI options, config file, and environment variables
- Environment variables — complete list of runtime variables like
KIMI_CODE_HOME