Kode uses two complementary configuration layers:
- Global config (app-wide): model profiles, model pointers, theme, etc.
- Settings files (user/project/local):
.kode/settings.json,.kode/settings.local.json, etc. (with legacy.claudefallbacks)
This doc focuses on where the files live and how to configure models reliably.
- Default:
~/.kode.json - If
KODE_CONFIG_DIRis set:<KODE_CONFIG_DIR>/config.json
Kode also uses a data directory for logs/tasks/memory:
- Default:
~/.kode/ - If
KODE_CONFIG_DIRis set:<KODE_CONFIG_DIR>/
Legacy compatibility:
CLAUDE_CONFIG_DIRaffects only legacy read-compat roots (e.g.~/.claude), and never changes Kode’s primary config/data locations.
- Project settings:
./.kode/settings.json(legacy./.claude/settings.json) - Local settings:
./.kode/settings.local.json(legacy./.claude/settings.local.json)
Example: output style selection is stored in settings.local.json under outputStyle.
Missing settings files are optional. Existing files must be readable JSON objects;
permissions, when present, must be an object, and allow, deny, ask, and
additionalDirectories must be arrays of strings when present. Other keys are
preserved for compatibility.
An unreadable, truncated, or invalid settings file stops permission initialization.
The error identifies the file without printing its contents. CLI startup exits
nonzero, including text, JSON, and stream-JSON print modes; server session creation
fails. Repair the reported file or restore its intended policy and retry. A broken
primary file never falls back to an older .claude policy. Legacy fallback and
migration remain available when the primary file is absent.
Model configuration lives in the global config under:
modelProfiles: array of provider/model entriesmodelPointers: default assignments formain,task,compact,quick
Minimal example (illustrative):
{
"modelProfiles": [
{
"name": "o3",
"provider": "openai",
"modelName": "o3",
"baseURL": "https://api.openai.com/v1",
"apiKey": "<YOUR_API_KEY>",
"maxTokens": 8192,
"contextLength": 200000,
"isActive": true,
"createdAt": 1710000000000
}
],
"modelPointers": {
"main": "o3",
"task": "o3",
"compact": "o3",
"quick": "o3"
}
}Recommended ways to manage models:
- Interactive UI:
/model - Shareable YAML:
kode models export/kode models import - List configured profiles/pointers:
kode models list
kode models export --output kode-models.yaml
kode models import kode-models.yaml
kode models import --replace kode-models.yamlThe exported YAML defaults to apiKey: { fromEnv: ... } so you can keep secrets in environment variables.
Across Kode features (agents, Task tool overrides, etc.), you can generally reference a model using:
- Pointer:
main | task | compact | quick - Profile name:
OpenAI Main - Model name (modelName):
o3,gpt-4o,qwen2.5-coder-32b-instruct - Provider-qualified:
provider:modelName(orprovider:profileName), e.g.openai:o3
Use kode models list to see what’s currently configured.
kode config is intended for a small set of “safe” keys (theme, verbosity, a few project toggles).
# Global config keys
kode config get -g theme
kode config set -g theme dark
kode config list -g
# Project config keys (stored under projects[...] inside the global config)
kode config get enableArchitectTool
kode config set enableArchitectTool true
kode config listFor models, prefer /model or kode models import/export (not kode config set).
Anthropic environment overrides are disabled—configure Anthropic keys in Kode settings instead.
# API Keys
OPENAI_API_KEY=sk-...
# Model Selection
CLAUDE_MODEL=claude-3-5-sonnet-20241022
DEFAULT_MODEL_PROFILE=fast
# Feature Flags
ENABLE_ARCHITECT_TOOL=true
DEBUG_MODE=true
VERBOSE=true
# MCP Configuration
MCP_SERVER_URL=http://localhost:3000
MCP_TIMEOUT=30000
# Development
NODE_ENV=development
LOG_LEVEL=debugEnvironment variables override configuration files (Anthropic keys excluded):
- Check environment variable
- Check project configuration
- Check global configuration
- Use default value
The system automatically migrates old configuration formats:
function migrateConfig(config: any): Config {
// v1 to v2: Rename fields
if (config.iterm2KeyBindingInstalled) {
config.shiftEnterKeyBindingInstalled = config.iterm2KeyBindingInstalled
delete config.iterm2KeyBindingInstalled
}
// v2 to v3: Update model format
if (typeof config.model === 'string') {
config.modelProfiles = {
default: {
type: 'anthropic',
model: config.model,
},
}
delete config.model
}
return config
}Configuration files are backed up before changes:
function saveConfigWithBackup(config: Config) {
// Create backup
const backupPath = `${configPath}.backup`
fs.copyFileSync(configPath, backupPath)
try {
// Save new configuration
fs.writeFileSync(configPath, JSON.stringify(config, null, 2))
} catch (error) {
// Restore from backup on error
fs.copyFileSync(backupPath, configPath)
throw error
}
}Using Zod for runtime validation:
const ConfigSchema = z.object({
theme: z.enum(['dark', 'light']).optional(),
modelProfiles: z.record(ModelProfileSchema).optional(),
modelPointers: ModelPointersSchema.optional(),
mcpServers: z.record(MCPServerConfigSchema).optional(),
// ... other fields
})
function loadConfig(path: string): Config {
const raw = JSON.parse(fs.readFileSync(path, 'utf-8'))
return ConfigSchema.parse(raw)
}- API Keys: Must match expected format
- Model Names: Must be valid model identifiers
- URLs: Must be valid URLs for endpoints
- Paths: Must be valid file system paths
- Commands: Must not contain dangerous patterns
Affects all projects:
- User preferences (theme, keybindings)
- Model profiles and API keys
- Global MCP servers
- Auto-updater settings
Specific to current project:
- Tool permissions
- Allowed commands
- Project context
- Local MCP servers
- Cost tracking
Temporary for current session:
- Runtime flags
- Temporary permissions
- Active MCP connections
- Current model selection
{
"modelProfiles": {
"custom-llm": {
"type": "custom",
"name": "My Custom LLM",
"config": {
"baseURL": "https://my-llm-api.com",
"apiKey": "custom-key",
"model": "my-model-v1",
"headers": {
"X-Custom-Header": "value"
}
}
}
}
}{
"mcpServers": {
"filesystem": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem"],
"env": {
"ALLOWED_DIRECTORIES": "/home/user/projects"
}
},
"github": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
},
"web-api": {
"type": "sse",
"url": "https://api.example.com/mcp"
}
}
}{
"context": {
"projectType": "typescript",
"framework": "react",
"testingFramework": "jest",
"buildTool": "webpack",
"customContext": "This project uses a custom state management solution..."
}
}- Never commit API keys to version control
- Use environment variables for secrets
- Validate all configuration inputs
- Limit command permissions appropriately
- Keep global config for user preferences
- Use project config for project-specific settings
- Document custom configuration in README
- Version control project configuration
- Cache configuration in memory
- Reload only when files change
- Use efficient JSON parsing
- Minimize configuration file size
- Use verbose mode for configuration issues
- Check configuration with
config list - Validate configuration on load
- Log configuration errors clearly
-
Configuration Not Loading
- Check file permissions
- Validate JSON syntax
- Ensure correct file path
-
Settings Not Applied
- Check configuration hierarchy
- Verify environment variables
- Clear configuration cache
-
Migration Failures
- Restore from backup
- Manually update format
- Check migration logs
# Show configuration
kode config list
# Reset to defaults
kode config reset
# Show configuration paths
kode config pathsThe configuration system provides flexible, secure, and robust management of all Kode settings while maintaining backward compatibility and user-friendly defaults.