Settings & Config

Command Code stores configuration in two main kinds of JSON file: config.json for your personal preferences, and the settings.json family for how the agent behaves in a project. A few smaller files hold MCP servers, keybindings, credentials, and scheduled jobs. This page is the complete reference - every key, where it lives, how it's resolved, and its default.

~/.commandcode/ (user-level) ├── config.json ← your preferences: model, theme, provider… ├── settings.json ← your global hooks, permissions, MCP, skills, mods ├── auth.jsoncredentials (managed by login; don't hand-edit) ├── keybindings.json ← keybinding overrides ├── mcp.json ← user-scope MCP servers ├── cron/jobs.json ← scheduled jobs (machine-managed) └── projects/{project}/ ├── config.json ← per-project state (taste onboarding progress) └── mcp.jsonlocal (per-project) MCP servers <project>/.commandcode/ (project-level) ├── settings.json ← shared with your team, commit this └── settings.local.json ← your personal overrides, don't commit this <project>/.mcp.json ← project-scope MCP servers, commit this

No file is created just by launching Command Code. Files appear the first time something is written - your first model or theme change creates config.json, and approving a command for a project creates settings.local.json. Until then, built-in defaults apply.

~/.commandcode/config.json is a single user-level file. It's yours: it never lives in a repository, and Command Code updates it for you as you use the CLI (for example when you pick a model with /model or switch themes with /theme). It's written with 0600 permissions.

KeyTypeWhat it doesDefault
providerstringSelected auth provider: anthropic, github-copilot, codex, or command-code-
modelstringDefault model for new sessionsCurated default model
themedark | lightTerminal themedark
compactModedefault | fastAuto-compact aggressivenessdefault
reasoningEffortobjectPer-model reasoning effort, keyed by model id. Values: low, medium, high, xhigh, maxProvider default
featureModelsobjectModel overrides for background features, keyed by feature. Keys: titleGeneration, compaction, toolDescription, tasteOnboarding, tasteLearning, branchSummarization. Managed by /configure-modelsCurated defaults
collapsePastedTextbooleanCollapse long pasted/dictated text (>300 chars) into a [first words… +NL] tokentrue
tasteLearningbooleanGlobal toggle for taste learningtrue
ideContextEnabledbooleanIDE context integrationtrue
autoInstallExtensionbooleanAuto-install the IDE extension on startuptrue
forceOAuthbooleanRequire OAuth, disallow API-key authfalse
defaultExportFormathtml | jsonl | mdFormat a bare /export writeshtml
defaultShareGistFormathtml | jsonl | mdFormat a bare /share gist postshtml
treeFilterModestringDefault /tree filter: default, no-tools, user-only, labeled-only, alldefault
branchSummarySkipPromptbooleanNever prompt for a branch summary in /treefalse
onDemandToolDescriptionsbooleanGenerate the permission prompt's command explanation only on ctrl+etrue
installedbooleanFirst-install detection (machine-written)-
firstMessageSentbooleanFirst-message detection (machine-written)-

You rarely need to edit this file directly - slash commands like /model, /theme, /effort, /config, and /configure-models manage it for you.

Note

The /config overlay surfaces a curated subset of these keys for point-and-click editing (theme, compact mode, force-OAuth, tree filter, on-demand tool descriptions, branch-summary prompt, export/share formats, taste learning, and the feature-model rows). The rest are still valid on disk - reasoning effort is managed by /effort, and the default permission mode is session-only.

Settings files hold the things that shape how the agent behaves: model, permissions, hooks, MCP servers, skills, and mods. Unlike config.json, they exist at multiple scopes and are deep-merged.

ScopeFileUse it for
Project local<project>/.commandcode/settings.local.jsonPersonal overrides for one project. Approved permissions are saved here. Add it to .gitignore.
Project<project>/.commandcode/settings.jsonTeam-shared rules. Commit it so everyone gets the same hooks and permissions.
User~/.commandcode/settings.jsonYour defaults across every project.

The legacy ~/.commandcode/config.json also feeds this layer as the lowest-precedence source for seven overlapping keys (model, theme, compactMode, forceOAuth, tasteLearning, featureModels, reasoningEffort).

Top-level keys

KeyTypeWhat it doesDefault
modelstringMain model id for the sessionCurated default
effortstringGlobal reasoning effort-
reasoningEffortobjectPer-model reasoning effort override-
permissionsobjectPermission rules and toggles (see below){}
permissionModestringLegacy default mode; superseded by permissions.defaultModedefault
hooksobjectLifecycle hooks (see below)-
themestringTerminal theme-
tasteLearningbooleanTaste-learning gate (per-project override)true
compactModedefault | fastAuto-compact aggressivenessdefault
forceOAuthbooleanRequire OAuth-
featureModelsobjectPer-feature model overrides-
providersobjectBring-your-own provider configuration-
pluginsstring[]Plugin list-
skillsstring[]Extra skill directories (~/ expands; relative paths resolve to the project root)-
disableSkillShellExecutionbooleanDisable dynamic !`…` shell placeholders in skill bodiesfalse
disableScratchpadbooleanDisable the per-session scratchpad directoryfalse
mcpobjectInline MCP servers: { "servers": [ … ] }-
modsobjectDeclarative mod config: { sources?, paths?, disabled? }-
disabledSkillsstring[]Skill names to disable (unioned across layers)-

permissions

Rules that allow, ask, or deny operations, plus a few related toggles. See Permissions for the rule syntax and matching behavior.

{ "permissions": { "allow": ["Bash(npm test)", "Bash(pnpm build)"], "ask": ["Bash(git push:*)"], "deny": ["Bash(rm -rf:*)"], "defaultMode": "default", "additionalDirectories": ["../shared-lib"], "disableBypass": false } }
KeyTypeWhat it does
allowstring[]Rules that auto-approve matching operations
askstring[]Rules that always prompt
denystring[]Rules that always block
defaultModestringDefault permission mode: default, auto-accept, plan, or bypass
additionalDirectoriesstring[]Extra in-workspace directories (~/ expands; relative paths resolve to the project root)
disableBypassboolean | stringtrue (or "disable") makes bypass / --yolo mode unenterable

The four rule lists (allow, ask, deny, additionalDirectories) union across every scope rather than being overwritten, so a rule added at any level always applies. When you approve a command with "don't ask again for this project," it's written to settings.local.json.

hooks

Hooks run shell scripts at lifecycle events. Only four events are recognized: PreToolUse, PostToolUse, Stop, and SessionStart.

{ "hooks": { "PreToolUse": [ { "matcher": "shell", "hooks": [ { "type": "command", "command": "./scripts/guard.sh", "timeout": 30 } ] } ] } }

Each handler must be { "type": "command", "command": "…" }, with an optional timeout (in seconds, 0600), async, and failClosed. See Hooks for the full schema and event payloads.

MCP servers

MCP servers can be declared inline under mcp.servers in settings.json, but the dedicated files below are the usual home. See MCP for the entry schema.

PathContentsEdit by hand?
~/.commandcode/auth.jsonCommand-provider API credentials, written 0600No - managed by /login and /logout
~/.commandcode/keybindings.jsonKeybinding overrides, merged over the defaults (id → key or id → key[])Yes - see Keybindings
~/.commandcode/mcp.json (or .mcp.json)User-scope MCP servers: { "mcpServers": { … } }Yes
<project>/.mcp.jsonProject-scope MCP servers (commit this)Yes
~/.commandcode/projects/{project}/mcp.jsonLocal (per-project) MCP serversVia CLI
~/.commandcode/cron/jobs.jsonDurable scheduled / cron jobsNo - machine-managed
~/.commandcode/telemetry-install-idAnonymous per-machine telemetry idNo - machine-managed

MCP scope precedence (low → high): settings.json mcp.servers < user mcp.json < project .mcp.json < local projects/{project}/mcp.json.

Command Code also reads a handful of environment variables as configuration:

VariableWhat it does
COMMAND_CODE_API_KEYCommand-provider API key; overrides auth.json when set
CMD_ZDR1 enables Zero-Data-Retention mode (pauses ZDR-incompatible feature models)
COMMANDCODE_SKIP_UPDATESSkip the auto-updater
COMMANDCODE_SCRATCHPAD / COMMANDCODE_SCRATCHPAD_BASEOverride the per-session scratchpad location or base directory
MCP_TOOL_TIMEOUTPer-request MCP tool timeout, in milliseconds
MAX_MCP_OUTPUT_TOKENSCap on MCP tool output tokens (default 25000)
DO_NOT_TRACKStandard opt-out that disables telemetry
HOME / USERPROFILEHome directory used to resolve ~/.commandcode

When the same setting is defined in more than one place, the more specific scope wins:

  1. <project>/.commandcode/settings.local.json - highest
  2. <project>/.commandcode/settings.json
  3. ~/.commandcode/settings.json
  4. ~/.commandcode/config.json (legacy fields only) - lowest

Maps are deep-merged and scalars overwrite, except the permission rule lists (allow, ask, deny, additionalDirectories), which union across all layers.

The model for a session is resolved separately, since it can be set in more ways:

  1. --model flag - highest
  2. /model picked during the session
  3. model in settings.json / config.json
  4. Built-in default - lowest

A running session reads its default model from config.json once at startup. Changing the default in another terminal (or editing the file by hand) doesn't affect sessions that are already running - new sessions pick it up.

  • Commit <project>/.commandcode/settings.json so your team shares hooks and permission rules, and code review sees changes to them.
  • Gitignore settings.local.json - it holds your personal approvals and overrides:
.commandcode/settings.local.json
  • Never commit ~/.commandcode files. They're user-level by design; auth.json holds credentials.
  • Let slash commands manage config.json rather than editing it by hand.

~/.commandcode/projects/{project}/config.json holds machine-written state for each project you use Command Code in - currently taste onboarding progress (tasteOnboarding: completed/skipped flags, learned and skipped sessions, last learning date). It lives in your home directory, not the repository, and Command Code manages it entirely - you never need to edit it.