Skip to content

Course · OpenCode

Config reference

This page collects every OpenCode config field this course writes, with what it controls, its type, its default, and the lesson that introduces it. Two files are involved: opencode.json is OpenCode’s main config file, a project copy at your repository root with a global copy at ~/.config/opencode/opencode.json, and tui.json is the separate settings file for the terminal interface, with the same two locations: tui.json beside the project’s opencode.json, and ~/.config/opencode/tui.json globally. Defaults and field shapes are as of October 2026 - where this page and the config documentation disagree, trust the doc, except where a row links the source file it was checked against.

Field Controls Type Default Introduced in
model the default model, as provider/model string none; unset, OpenCode uses the last model you used, then its own priority order (models documentation) Bring your own model
provider custom providers and per-provider model options object none; unset, the built-in providers you have credentials for are available Wire up multiple providers
permission.read reading a file "allow" | "ask" | "deny" or path map allow, except .env files: ask as of October 2026 (v1.18.32; agent.ts), which the permissions documentation describes as deny; .env.example remains allowed. A bare string such as "allow" replaces this map. If you rely on a block, set { "*.env": "deny", "*.env.*": "deny", "*.env.example": "allow" } Per-tool, per-agent
permission.edit file changes (the edit, write, and patch tools) "allow" | "ask" | "deny" or path map "allow" Per-tool, per-agent
permission.bash running shell commands "allow" | "ask" | "deny" or command map "allow" Per-tool, per-agent
permission.glob finding files by name pattern "allow" | "ask" | "deny" or pattern map "allow" Per-tool, per-agent
permission.grep searching file contents "allow" | "ask" | "deny" or pattern map "allow" Per-tool, per-agent
permission.list listing a directory "allow" | "ask" | "deny" or pattern map "allow" Per-tool, per-agent
permission.task launching a subagent "allow" | "ask" | "deny" or subagent map "allow" The three built-in subagents
permission.skill loading a skill "allow" | "ask" | "deny" or glob map "allow" Gate which agents run it
permission.lsp language-server queries "allow" | "ask" | "deny" "allow" The LSP channel
compaction.auto summarizing the session automatically when the context window fills boolean true Undo, redo & compact
compaction.prune removing old tool output to save tokens boolean false Undo, redo & compact
compaction.reserved the token buffer kept free so compaction itself does not overflow number none documented; unset, OpenCode reserves the smaller of 20,000 tokens and the model’s output limit (session source) Undo, redo & compact
instructions extra instruction files or glob patterns loaded alongside AGENTS.md string[] none documented; unset, no extra instruction files load Point at more instruction files
mcp MCP (Model Context Protocol) servers that give the agent external tools object none documented; unset, no MCP servers are configured MCP servers
agent custom agents and overrides for built-in ones (model, prompt, permissions) object none documented; unset, only the built-in agents exist Write a custom subagent

The permission.* rows are the keys this course sets. The keys name the tools the agent actually calls, and the documented list (permissions documentation, as of October 2026) has thirteen of them: read, edit, glob, grep, bash, task, skill, lsp, question, webfetch, websearch, external_directory, and doom_loop. The config schema accepts two more the doc page doesn’t list yet: list, directory listing - distinct from glob’s pattern-based search - and todowrite (permission schema, as of October 2026). Left unset, most keys default to allow; doom_loop and external_directory default to ask. These are the base defaults: built-in agents layer their own rules on top, and your config applies after both. The plan agent denies the edit tools outside its plan files, denies launching the general subagent, and does not gate bash (as of October 2026, v1.18.32; agent.ts; the agents documentation says plan sets edits and bash to ask). doom_loop triggers when the same tool call repeats three times with identical input, and external_directory triggers when a tool touches a path outside the project directory. A map value matches what the tool acts on: a file path for read and edit, the subagent type for task, the skill name for skill. The permissions documentation calls lsp non-granular for now, so the table shows it with a single action. permission.bash’s map matches flat command strings, not filesystem globs; that grammar and the last-match-wins ordering rule are covered in the per-tool, per-agent treatment.

opencode.json is not one file but a stack of sources. Config sources are loaded in this order, later sources overriding earlier ones (as of October 2026; config documentation):

  1. Remote config (.well-known/opencode) - organizational defaults
  2. Global (~/.config/opencode/opencode.json) - user preferences
  3. Custom (OPENCODE_CONFIG env var) - custom overrides
  4. Project (opencode.json in the project) - project-specific settings
  5. .opencode directories - agents, commands, plugins
  6. Inline (OPENCODE_CONFIG_CONTENT env var) - runtime overrides
  7. Managed config files (/Library/Application Support/opencode/ on macOS, /etc/opencode/ on Linux, %ProgramData%\opencode on Windows)
  8. macOS managed preferences (.mobileconfig via MDM, mobile device management) - highest priority, not user-overridable

In practice: a project opencode.json overrides your global file where both set the same key. Objects merge key by key, and instructions lists from all sources combine instead of replacing each other (as of October 2026, v1.18.32; config source). The the managed layers override everything - an administrator’s MDM-deployed settings win no matter what you write.

The merge order above is for opencode.json. For tui.json, the project file overrides the global one where both set the same key, and the OPENCODE_TUI_CONFIG environment variable points OpenCode at a custom file, which overrides the global file but not the project files (as of October 2026; config documentation and the TUI config source).

Field Controls Type Default Introduced in
theme the terminal interface’s color theme string "opencode" Keybinds & themes
keybinds keyboard shortcuts, merged with the built-in defaults object see keybinds docs Leader key & command palette
leader_timeout how long OpenCode waits for the next key after the leader key number (ms) 2000 (keybinds docs) Leader key & command palette