Configuration

# Configuration Kit looks for configuration in the following locations, in order of priority: 1. CLI flags 2. Environment variables (with `KIT_` prefix) 3. `./.kit.yml` / `./.kit.yaml` / `./.kit.json` (project-local) 4. `~/.kit.yml` / `~/.kit.yaml` / `~/.kit.json` (global) ## Basic configuration Create `~/.kit.yml`: ```yaml model: anthropic/claude-sonnet-latest max-tokens: 8192 temperature: 0.7 stream: true ``` ## All configuration keys | Key | Type | Default | Description | |-----|------|---------|-------------| | `model` | string | `anthropic/claude-sonnet-latest` | Model to use (provider/model format) | | `max-tokens` | int | `8192` | Base cap for output tokens. Auto-raised per-model up to 32768 when the model's catalog ceiling is higher and no explicit value is set. Use [`modelSettings[provider/model].maxTokens`](#per-model-settings) to override per-model. | | `temperature` | float | `0.7` | Randomness 0.0–1.0 | | `top-p` | float | `0.95` | Nucleus sampling 0.0–1.0 | | `top-k` | int | `40` | Limit top K tokens | | `stream` | bool | `true` | Enable streaming output | | `debug` | bool | `false` | Enable debug logging | | `compact` | bool | `false` | Enable compact output mode | | `system-prompt` | string | — | System prompt text or file path | | `max-steps` | int | `0` | Maximum agent steps (0 = unlimited) | | `thinking-level` | string | `off` | Extended thinking: off, none, minimal, low, medium, high | | `provider-api-key` | string | — | API key for the provider | | `provider-url` | string | — | Base URL for provider API | | `tls-skip-verify` | bool | `false` | Skip TLS certificate verification | | `frequency-penalty` | float | `0.0` | Penalize frequent tokens (0.0–2.0) | | `presence-penalty` | float | `0.0` | Penalize present tokens (0.0–2.0) | | `stop-sequences` | list | — | Custom stop sequences | | `theme` | object or string | — | UI theme ([inline overrides or file path](/themes)) | | `prompt-templates` | bool | `true` | Enable prompt template loading | | `prompt-template` | string | — | Specific template to load by name | | `no-skills` | bool | `false` | Disable skill loading (auto-discovery and explicit) | | `skill` | list | — | Explicit skill files or directories to load (disables auto-discovery) | | `skills-dir` | string | — | Override the project-local directory used for skill auto-discovery | ## Environment variables Any configuration key can be set via environment variable with the `KIT_` prefix. Hyphens become underscores: ```bash export KIT_MODEL="openai/gpt-4o" export KIT_MAX_TOKENS="8192" export KIT_TEMPERATURE="0.5" ``` Provider API keys use their own environment variables: ```bash export ANTHROPIC_API_KEY="sk-..." export OPENAI_API_KEY="sk-..." export GOOGLE_API_KEY="..." ``` ## MCP server configuration Add external MCP servers to your `.kit.yml`: ```yaml mcpServers: filesystem: type: local command: ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed"] environment: LOG_LEVEL: "info" allowedTools: ["read_file", "write_file"] excludedTools: ["delete_file"] search: type: remote url: "https://mcp.example.com/search" pubmed: type: remote url: "https://pubmed.mcp.example.com" noOAuth: true # skip OAuth for public servers headers: - "ApiKey: ${env://API_KEY}" # required env var - "X-Tenant: ${env://TENANT_ID:-default}" # with fallback default builds: type: remote url: "https://builds.mcp.example.com" tasksMode: always # always run tools/call as async tasks (Phase 1 MVP) ``` ### MCP server fields | Field | Type | Description | |-------|------|-------------| | `type` | string | `local` (stdio) or `remote` (streamable HTTP) | | `command` | list | Command and args for local servers | | `environment` | map | Environment variables for the server process | | `url` | string | URL for remote servers | | `allowedTools` | list | Whitelist of tool names to expose | | `excludedTools` | list | Blacklist of tool names to hide | | `noOAuth` | bool | Skip OAuth for this server (for public servers that don't require auth) | | `headers` | list of strings | HTTP headers to attach to every request, each as a `"Key: Value"` string. Values support env-substitution: `${env://VAR}` or `${env://VAR:-default}`. | | `tasksMode` | string | When to augment `tools/call` with MCP task metadata: `auto` (default — only when the server advertises task support), `never`, or `always`. See [MCP tasks](#mcp-tasks-long-running-tools). | A legacy format with `transport`, `args`, and `env` fields is also supported; `headers` works in both the current and legacy formats. ### MCP tasks (long-running tools) Kit advertises [MCP task support](https://modelcontextprotocol.io/specification/2025-11-25/basic/utilities/tasks) during `initialize` so servers can respond to `tools/call` with a `CreateTaskResult` (a task ID + `working` status) instead of blocking until the operation finishes. Kit then polls `tasks/get` / `tasks/result` until the task reaches a terminal state, and best-effort `tasks/cancel`s on context cancellation. This avoids HTTP/SSE proxy timeouts on long builds, deploys, and batch jobs, and lets the user/agent abort cleanly with Ctrl-C. **Per-server `tasksMode`:** | Value | Behaviour | |-------|-----------| | `auto` (default) | Augment `tools/call` with task metadata only when the server advertised `tasks/toolCalls` capability. Servers that don't advertise it run synchronously, exactly as before. | | `never` | Always issue `tools/call` synchronously, regardless of server capability. | | `always` | Always opt into task augmentation, even when the server didn't advertise the capability. The server may still respond synchronously — this just expresses client intent unconditionally. | Defaults are safe: any existing MCP server keeps its previous behaviour bit-for-bit. SDK consumers can also override the mode programmatically and plug in a progress callback — see [SDK options](/sdk/options#mcp-tasks). ## Custom models Define custom models in your `.kit.yml` for use with the `custom` provider. This is useful for self-hosted models or API endpoints not in the built-in database: ```yaml customModels: my-model: name: "My Custom Model" baseUrl: "http://localhost:8080/v1" apiKey: "my-secret-key" reasoning: true temperature: true cost: input: 0.002 output: 0.004 limit: context: 128000 output: 32000 ``` ### Custom model fields | Field | Type | Required | Description | |-------|------|----------|-------------| | `name` | string | Yes | Display name for the model | | `baseUrl` | string | No | Per-model base URL override; when set, `--provider-url` is not required | | `apiKey` | string | No | Per-model API key override | | `reasoning` | bool | No | Whether the model supports reasoning/thinking | | `temperature` | bool | No | Whether the model supports temperature adjustment | | `cost.input` | float | No | Cost per 1K input tokens | | `cost.output` | float | No | Cost per 1K output tokens | | `limit.context` | int | Yes | Maximum context window in tokens | | `limit.output` | int | No | Maximum output tokens | Use with a per-model `baseUrl` (no `--provider-url` needed): ```bash kit --model custom/my-model "Hello" ``` Or override the base URL at runtime: ```bash kit --provider-url "http://localhost:8080/v1" --model custom/my-model "Hello" ``` When `--provider-url` is specified without `--model`, Kit defaults to `custom/custom` which has zero cost tracking and a 262K context window. ## Per-model settings Override generation parameters and system prompt on a per-model basis using `modelSettings`: ```yaml modelSettings: anthropic/claude-sonnet-4-5-20250929: temperature: 0.3 maxTokens: 8192 systemPrompt: "You are a concise coding assistant." openai/gpt-4o: temperature: 0.7 frequencyPenalty: 0.5 ``` ### Per-model fields | Field | Type | Description | |-------|------|-------------| | `temperature` | float | Temperature override for this model | | `maxTokens` | int | Max output tokens override | | `topP` | float | Top-p override | | `topK` | int | Top-k override | | `frequencyPenalty` | float | Frequency penalty override | | `presencePenalty` | float | Presence penalty override | | `stopSequences` | list | Stop sequences override | | `thinkingLevel` | string | Thinking level override | | `systemPrompt` | string | Per-model system prompt (used when no explicit prompt is set) | Settings from `modelSettings` and `customModels.params` act as model-level defaults — explicit CLI flags, `KIT_*` environment variables, global config values, and SDK `Options.*` fields all take precedence over them. When switching models via `/model` or `SetModel()`, if the new model has a per-model system prompt and no custom global prompt was set, the per-model prompt automatically replaces the previous one. ### Precedence summary For the generation and provider parameters documented above, the resolved value at runtime comes from the first source that sets it: 1. CLI flag (e.g. `--max-tokens`, `--temperature`, `--provider-api-key`) 2. SDK `Options.X` when embedding Kit as a library (`kit.Options.MaxTokens`, `Temperature`, `ProviderAPIKey`, etc.) 3. `KIT_*` environment variable (`KIT_MAX_TOKENS`, `KIT_TEMPERATURE`, ...) 4. `.kit.yml` / `.kit.yaml` / `.kit.json` (project-local, then global) 5. Per-model defaults (`modelSettings[provider/model]` / `customModels[...].params`) 6. Provider-level defaults (e.g. Anthropic's own temperature default) 7. SDK last-resort floor — currently an 8192 output-token ceiling matching the CLI `--max-tokens` default, auto-raised per-model up to 32768 when the model's catalog ceiling is higher See the [SDK options reference](/sdk/options) for the full list of `kit.Options` fields that map to these keys. ## Theme configuration ```yaml # Inline partial overrides (unspecified fields inherit from default) theme: primary: light: "#8839ef" dark: "#cba6f7" error: dark: "#FF0000" ``` ```yaml # Reference external theme file theme: "./themes/my-custom-theme.yml" ``` See [Themes](/themes) for the full theme file format, built-in themes, and the extension theme API. ## Preferences persistence Kit automatically saves your UI preferences across sessions to `~/.config/kit/preferences.yml`: - **Theme** — Set via `/theme ` or `ctx.SetTheme()` - **Model** — Set via `/model ` or the model selector - **Thinking level** — Set via `/thinking ` or Shift+Tab cycling These preferences are restored on next launch. Precedence (highest to lowest): 1. CLI flags (`--model`, `--thinking-level`) 2. Config file (`model:`, `thinking-level:`) 3. Saved preferences (`~/.config/kit/preferences.yml`) 4. Default values