Config
Create opencode.jsonc in your project to configure OpenCode. Add the schema for editor validation, then set only the options you need.
{
"$schema": "https://opencode.ai/config.json",
"model": "anthropic/claude-sonnet-5-5",
}You can also ask OpenCode to update this file for you.
Format#
OpenCode supports JSON and JSONC. Use JSONC when you want comments or trailing commas.
{
"$schema": "https://opencode.ai/config.json",
// Use this model by default.
"model": "anthropic/claude-sonnet-5-5",
}Locations#
Put managed, machine-wide settings in the system configuration directory:
| Platform | Directory |
|---|---|
| macOS | /Library/Application Support/opencode |
| Linux | /etc/opencode |
| Windows | %ProgramData%\opencode |
The system directory works like the global directory. Besides
opencode.json(c), it loads agents/, commands/, skills/, and plugins/
for every user on the machine:
/etc/opencode/
├── opencode.json
├── agents/review.md
├── commands/release.md
└── skills/deploy/SKILL.md
On macOS, OpenCode also reads managed preferences that MDM tools deploy for the
ai.opencode.managed domain. A user-specific profile replaces the
machine-wide one:
/Library/Managed Preferences/<user>/ai.opencode.managed.plist
/Library/Managed Preferences/ai.opencode.managed.plist
Managed settings have the highest precedence, so users and projects cannot override the values they set, and managed preferences override the system directory. Settings alone cannot stop users from adding providers, MCP servers, agents, or plugins; use policies in managed configuration to enforce restrictions.
Put user settings for every project in the global configuration:
~/.config/opencode/opencode.json(c)
Put project settings in either of these files:
/home/user/projects/my-app/opencode.json(c)
/home/user/projects/my-app/.opencode/opencode.json(c)
OpenCode searches from the current directory to the filesystem root. It first
merges direct opencode.json(c) files from the farthest directory to the
closest, then merges files inside .opencode directories in the same order.
This means every discovered .opencode config overrides every direct config.
Use one form throughout a directory tree unless you need that behavior.
For example, start OpenCode from /home/user/projects/acme/packages/web:
/etc/opencode/opencode.json
~/.config/opencode/opencode.json
/home/user/projects/acme/
├── opencode.json
└── packages/
└── web/
├── opencode.json
└── src/
OpenCode applies these files from lowest to highest precedence:
~/.config/opencode/opencode.json/home/user/projects/acme/opencode.json/home/user/projects/acme/packages/web/opencode.json/etc/opencode/opencode.json
The package config overrides matching settings from the repository config, which overrides the global config. The system config overrides all of them. Settings that do not conflict are preserved. Policies from global and project files evaluate in the reverse order, and system policies outrank all of them.
Schema#
The complete OpenCode configuration schema is available at opencode.ai/config.json.
Add the $schema field to your configuration file to enable validation and
autocomplete in editors that support JSON Schema:
{
"$schema": "https://opencode.ai/config.json"
}Use the schema as the source of truth for available fields, accepted values, and nested configuration shapes.
Shell#
Set the shell used by the terminal and shell tools.
{
"shell": "/bin/zsh",
}
Model#
Set the default model in provider/model format. The root default currently
does not retain a #variant; agent and command model references can select one.
{
"model": "anthropic/claude-sonnet-5-5",
}
See the models guide for model selection and local models.
Agent#
Choose the primary agent used when a session does not select one explicitly.
{
"default_agent": "build",
}
See the agents guide for built-in and custom agents.
Updates#
Control update checks from the global config. Set update to "disable" to
skip them, "notify" to show available updates before installing them, or
"auto" to install updates automatically. When omitted, update defaults to "notify".
Automatic installation does not restart a running server. Restart it manually to activate the installed update. Project-level values are ignored.
{
"update": "notify",
}
Username#
Set a username. OpenCode accepts this field but does not display it in conversations.
{
"username": "alice",
}
Permissions#
Define ordered rules that allow, deny, or ask before an agent uses a tool on a matching resource.
{
"permissions": [
{
"action": "shell",
"resource": "git push *",
"effect": "ask",
},
],
}
See the permissions guide for rule matching and available actions.
Policies#
Allow or deny use of a provider, hard-deny a permission check, or block an MCP server, skill, or plugin, with ordered statements that broader configuration can override.
{
"policies": [
{ "action": "provider.use", "resource": "*", "effect": "deny" },
{ "action": "provider.use", "resource": "anthropic", "effect": "allow" },
{ "action": "tool.use", "resource": "shell:git push *", "effect": "deny" },
],
}
See the policies guide for matching, precedence across configuration files, and Console-managed policy.
Agents#
Override built-in agents or define specialized agents with their own model, instructions, mode, and permissions.
{
"agents": {
"reviewer": {
"description": "Review changes without editing files",
"mode": "subagent",
"system": "Focus on correctness, security, and missing tests.",
"permissions": [{ "action": "edit", "resource": "*", "effect": "deny" }],
},
},
}
See the agents guide for all agent options and file-based agents.
Snapshots#
Enable or disable filesystem snapshots used by undo and revert behavior.
{
"snapshots": false,
}
See the snapshots guide for undo and redo behavior.
Watcher#
Ignore files and directories that should not trigger filesystem updates.
{
"watcher": {
"ignore": ["dist/**", "coverage/**"],
},
}
Formatter#
Format files after the write, edit, or patch tools change them. Set
formatter to true to enable available built-in formatters.
{
"formatter": true,
}
See the formatters guide for built-ins and custom formatters.
Media#
Control how oversized images loaded by the read tool are resized or rejected
before they are sent to a model.
{
"media": {
"image": {
"auto_resize": true,
"max_width": 2000,
"max_height": 2000,
"max_base64_bytes": 5242880,
},
},
}
See the attachments guide for image processing and limits.
Output#
Set the maximum number of lines and bytes retained from a tool result.
{
"tool_output": {
"max_lines": 2000,
"max_bytes": 51200,
},
}
Search#
Choose how OpenCode searches the web. Use "random" to select an available
provider automatically.
{
"websearch": {
"provider": "random",
},
}
See the web search guide for providers, credentials, selection, rate limits, and disabling search.
MCP#
Configure local and remote Model Context Protocol servers. Global
mcp.timeout values apply to servers defined in configuration files; each
server’s timeout overrides them.
{
"mcp": {
"servers": {
"playwright": {
"type": "local",
"command": ["bunx", "@playwright/mcp"],
},
},
},
}
See the MCP guide for remote servers, OAuth, environment variables, and timeouts.
Compaction#
Control automatic context compaction and how much recent context it preserves.
{
"compaction": {
"auto": true,
"keep": {
"tokens": 15000,
},
"buffer": "15%",
},
}
buffer is the share of the model’s context window kept free before automatic compaction starts.
Local summaries remain the default. Opt into native provider compaction for both automatic and manual requests with a provider or model policy:
{
"providers": {
"openai": {
"settings": { "compaction": { "type": "native" } },
"models": {
"gpt-6.1-sol": { "settings": { "compaction": { "type": "summary" } } },
},
},
},
}
A model setting overrides the provider setting. Automatic compaction uses the
selected model’s usable input budget. Provider checkpoints keep recent user messages within the same
compaction.keep.tokens budget that local summaries use for their retained tail.
Top-level compaction.auto: false disables new automatic compaction without
discarding installed checkpoints. See the compaction guide for
budgeting and overflow recovery.
Warming#
Keep recently active model sessions warm with periodic transient requests.
Warming is disabled by default; set it to true to use the four-minute idle
interval and 30-minute active window.
{
"warming": {
"prompt": "Do not perform any work. Reply with exactly: OK",
"interval": "4 minutes",
"duration": "30 minutes",
},
}
See the warming guide for request behavior, customization, and cost considerations.
Skills#
Add directories or URLs that OpenCode should search for agent skills.
{
"skills": ["./team-skills", "https://example.com/.well-known/skills/"],
}
See the skills guide for skill structure and automatic discovery under .opencode/skills/.
Commands#
Define reusable slash commands as named prompt templates.
{
"commands": {
"review": {
"description": "Review the current changes",
"template": "Review the current diff for correctness and missing tests.",
},
},
}
See the commands guide for arguments, models, agents, and file-based commands.
Instructions#
Declare additional instruction files, globs, or HTTP(S) URLs. OpenCode loads
them alongside discovered AGENTS.md files.
{
"instructions": ["CONTRIBUTING.md", "docs/guidelines/*.md"],
}
See the instructions guide for project instructions and AGENTS.md.
References#
Make local directories or Git repositories available as named supporting context.
{
"references": {
"docs": {
"path": "../product-docs",
"description": "Product behavior and terminology",
},
"effect": {
"repository": "Effect-TS/effect",
"branch": "main",
},
},
}
See the references guide for shorthand, visibility, and path resolution.
Worktrees#
Set the parent directory for new local worktrees. OpenCode appends the requested or generated worktree name.
{
"worktree": {
"directory": "../worktrees",
},
}
Relative paths resolve against the project’s saved canonical checkout. This applies to global and project
configuration alike; absolute paths are used as-is, and ~/ resolves
against the user’s home directory.
For example, this global configuration places new worktrees under each project’s own .lane/trees/ directory:
{
"worktree": {
"directory": ".lane/trees",
},
}
Without this setting, creation uses the server’s data directory under worktree/<first-six-project-ID-characters>.
Worktree creation and refresh load configuration from the project’s saved canonical checkout, including when other
clones share its project ID. Changing it does not move existing worktrees.
Git is the built-in default. A plugin that registers a strategy automatically becomes the
default in that plugin runtime. Project operations use the canonical checkout’s runtime. Strategy-specific options
belong to that plugin, not the worktree config object.
Plugins#
Load plugins from packages or local plugin directories. Use the object form when a plugin accepts options.
{
"plugins": [
"opencode-example-plugin",
{
"package": "./plugins/local",
"options": {
"enabled": true,
},
},
],
}
See the plugins guide for plugin loading and configuration.
Providers#
Configure providers and add or override their models, request settings, headers, and model variants.
{
"providers": {
"openai": {
"models": {
"gpt-6.1-sol-custom": {
"modelID": "gpt-6.1-sol",
"name": "GPT-6.1 Sol Custom",
"limit": {
"context": 200000,
"output": 32000,
},
},
},
},
},
}
Provider settings.transport: "websocket" selects its session WebSocket.
See the providers guide for credentials, custom endpoints, provider packages, the WebSocket transport, and model configuration.
Variables#
You can use variable substitution in your config files to reference environment variables and file contents. Place references inside JSON strings.
Env vars#
Use {env:VARIABLE_NAME} to substitute environment variables:
{
"$schema": "https://opencode.ai/config.json",
"model": "{env:OPENCODE_MODEL}",
"providers": {
"anthropic": {
"settings": {
"apiKey": "{env:ANTHROPIC_API_KEY}",
},
},
},
}If the environment variable is not set, it will be replaced with an empty string.
Files#
Use {file:path/to/file} to substitute the contents of a file:
{
"$schema": "https://opencode.ai/config.json",
"providers": {
"openai": {
"settings": {
"apiKey": "{file:~/.secrets/openai-key}",
},
},
},
}File paths can be:
- Relative to the config file directory
- Absolute, or starting with
~/for your home directory
If the file does not exist, it will be replaced with an empty string.
These are useful for:
- Keeping sensitive data like API keys in separate files.
- Sharing common configuration snippets across multiple config files.
Experimental#
All experimental settings live under the experimental key:
{
"$schema": "https://opencode.ai/config.json",
"experimental": {
"todo": true,
"subagent_depth": 2,
"background_compaction": true,
"image_generate": { "model": "openai/gpt-image-2" },
"location_idle_timeout": "4 hours",
},
}Todos#
Set todo to true to give agents a todowrite tool for tracking multi-step work. Defaults to false.
Subagent depth#
subagent_depth sets how deeply subagents can start their own subagents. Defaults to 1, so a subagent cannot
start another subagent.
Background compaction#
Set background_compaction to true to write the compaction summary in the background before it is needed, so
automatic compaction doesn’t pause the session. Defaults to false. See
Compaction for how it works.
{
"experimental": {
"background_compaction": true,
},
}
Image generation#
image_generate sets the default model for the experimental_image_generate tool, as
providerID/modelID, optionally with #variant. When that model isn’t available or can’t handle a request, OpenCode
picks another image model automatically.
{
"experimental": {
"image_generate": {
"model": "openai/gpt-image-2",
},
},
}
Location idle timeout#
location_idle_timeout controls how long a project location can go without session activity before OpenCode unloads
its services. It takes a duration such as "2 hours" and defaults to "60 minutes". Running sessions and background
jobs keep a location loaded. Set it to false to never unload idle locations. Project config can override the global
value.
{
"experimental": {
"location_idle_timeout": false,
},
}
Deprecated policies#
experimental.policies is deprecated. Use top-level policies instead. The old key still works and
merges into policies.