Skip to content

5.1b Advanced Configuration

Master all OpenCode configuration options to build a fully customized development environment.

📝 Course Notes

Key takeaways from this lesson:

Advanced Configuration Notes

What You'll Be Able to Do

  • Configure the interface (TUI, keybinds, server)
  • Configure behavior (share, compaction, watcher)
  • Configure features (Provider, tools, permissions, agents, commands, MCP, etc.)
  • Use experimental features
  • Configure custom API URLs for models

Your Current Pain Points

  • Want to customize keybinds
  • Want to control which tools the AI can use
  • Want to batch disable certain MCP tools
  • Want to configure privately deployed APIs for models
  • Want to know what hidden configurations exist

When to Use This

  • When you need: Full control over OpenCode's behavior
  • And you don't want: To be limited by default settings

Interface Configuration

TUI Configuration

json
{
  "tui": {
    "scroll_speed": 3,
    "scroll_acceleration": {
      "enabled": true
    },
    "diff_style": "auto"
  }
}
FieldDescriptionDefault
scroll_speedScroll speed multiplier (minimum 0.001)3
scroll_acceleration.enabledEnable macOS-style accelerated scrollingfalse
diff_styleDiff display style"auto"

scroll_acceleration.enabled takes precedence over scroll_speed. When enabled, scroll_speed is ignored.

diff_style options:

  • "auto" - Adapts based on terminal width
  • "stacked" - Always displays in single column

Keybinds Configuration

Customize keyboard shortcuts:

json
{
  "keybinds": {
    "leader": "ctrl+x",
    "session_new": "<leader>n",
    "session_compact": "<leader>c",
    "model_list": "<leader>m",
    "agent_list": "<leader>a",
    "session_interrupt": "escape"
  }
}

Note: The config key is keybinds (plural!), unlike permission/agent which use singular.

Leader Key

Most shortcuts use a leader key prefix to avoid terminal conflicts:

json
{
  "keybinds": {
    "leader": "ctrl+x"
  }
}

Default is ctrl+x. Press the leader key followed by the shortcut, e.g., ctrl+x then n to create a new session.

Disabling Keybinds

Set the value to "none" to disable:

json
{
  "keybinds": {
    "session_compact": "none"
  }
}

Common Keybinds

Config KeyDefaultDescription
app_exitctrl+c,ctrl+d,<leader>qExit application
session_new<leader>nNew session
session_list<leader>lSession list
session_interruptescapeInterrupt current operation
session_compact<leader>cCompact session
model_list<leader>mModel list
agent_list<leader>aAgent list
agent_cycletabSwitch Agent
command_listctrl+pCommand list
messages_undo<leader>uUndo message
messages_redo<leader>rRedo message

For the complete keybinds list, see Quick Reference/Keybinds.

Server Configuration

Configure the server for opencode serve and opencode web commands:

json
{
  "server": {
    "port": 4096,
    "hostname": "0.0.0.0",
    "mdns": true,
    "mdnsDomain": "opencode.local",
    "cors": ["http://localhost:5173"]
  }
}
FieldDescription
portListen port
hostnameListen address (defaults to 0.0.0.0 when mdns is enabled)
mdnsEnable mDNS service discovery (LAN devices can discover)
mdnsDomainCustom domain for mDNS service (default opencode.local)
corsList of allowed CORS origins

Behavior Configuration

Share Configuration

Control session sharing behavior:

json
{
  "share": "manual"
}
ValueDescription
"manual"Manual sharing (default), use /share command
"auto"Automatically share new sessions
"disabled"Disable sharing feature

Compaction Configuration

Control context compaction behavior:

json
{
  "compaction": {
    "auto": true,
    "prune": true,
    "reserved": 10000
  }
}
FieldDescriptionDefault
autoAuto-compact when context is fulltrue
pruneRemove old tool outputs to save tokenstrue
reservedToken buffer during compaction, reserves enough window to prevent overflow-

Watcher Configuration

Configure file watcher ignore patterns:

json
{
  "watcher": {
    "ignore": ["node_modules/**", "dist/**", ".git/**", "*.log"]
  }
}

Use glob syntax to exclude noisy directories and reduce file watcher overhead.

Instructions Configuration

Specify additional instruction files (merged with AGENTS.md):

json
{
  "instructions": [
    "CONTRIBUTING.md",
    "docs/guidelines.md",
    ".cursor/rules/*.md",
    "packages/*/AGENTS.md"
  ]
}

Supports glob patterns. Use cases:

  • Reuse existing rule files (e.g., Cursor's rules)
  • Share team coding standards
  • Include subproject rules in monorepos

Feature Configuration

Provider Configuration

Configure AI providers and their models:

jsonc
{
  "provider": {
    "anthropic": {
      "options": {
        "apiKey": "{env:ANTHROPIC_API_KEY}",
        "baseURL": "https://custom-anthropic.example.com/v1",
        "timeout": 600000,
        "setCacheKey": true
      },
      "models": {
        "claude-sonnet-4-5": {
          "provider": {
            "api": "https://custom-api.example.com/v1"
          }
        }
      }
    }
  }
}

Provider-level Options

FieldDescription
options.apiKeyAPI key, supports {env:VAR_NAME} environment variable replacement
options.baseURLCustom API base URL (for proxies or private deployments)
options.timeoutRequest timeout (milliseconds), set to false to disable
options.setCacheKeyEnable Prompt Caching (Anthropic only)
options.enterpriseUrlGitHub Enterprise URL (Copilot only)

Model-level Custom API URL

Added in v1.1.60+

Configure independent API URL for individual models:

jsonc
{
  "provider": {
    "openai": {
      "models": {
        "gpt-4o": {
          "provider": {
            "api": "https://api.custom-openai.com/v1"
          }
        }
      }
    }
  }
}

Use cases:

  • Use different deployments of the same provider (e.g., Azure OpenAI in different regions)
  • Test privately deployed models
  • Configure model-specific proxy servers

Whitelist/Blacklist

Control available models:

json
{
  "provider": {
    "openai": {
      "whitelist": ["gpt-4o", "gpt-4o-mini"],
      "blacklist": ["gpt-3.5-turbo"]
    }
  }
}
FieldDescription
whitelistOnly allow these models
blacklistDisable these models

whitelist and blacklist are mutually exclusive. When both exist, whitelist takes precedence.

Tools Configuration

Control tools available to the LLM:

json
{
  "tools": {
    "write": false,
    "bash": false,
    "webfetch": true
  }
}

All tools are enabled by default. Set to false to disable.

Wildcards

The tools key is ultimately converted to permission rules, so wildcards work indirectly through the permission system:

json
{
  "tools": {
    "mymcp_*": false
  }
}

Disables all tools from the MCP server named mymcp.

Recommend using permission configuration directly for wildcard control with finer-grained allow/ask/deny options.

Tools vs Permission

tools is a legacy configuration that automatically converts to permission:

tools settingEquivalent permission
"write": false"edit": "deny"
"bash": false"bash": "deny"

Recommend using permission configuration for finer-grained control (allow/ask/deny). See 5.5 Permissions.

Permission Configuration

Fine-grained permission control:

json
{
  "permission": {
    "edit": "ask",
    "bash": {
      "*": "ask",
      "git *": "allow",
      "npm *": "allow",
      "rm *": "deny"
    }
  }
}

Note: The config key is permission (singular), not permissions.

For detailed configuration, see 5.5 Permissions.

Agent Configuration

Configure Agent behavior:

jsonc
{
  "agent": {
    "code-reviewer": {
      "description": "Code review expert",
      "mode": "subagent",
      "model": "anthropic/claude-opus-4-5-thinking",
      "prompt": "You are a code review expert...",
      
      // Advanced configuration
      "temperature": 0.3,
      "top_p": 0.9,
      "steps": 50,
      "color": "#FF5733",
      "hidden": true,
      
      // Permissions
      "permission": {
        "edit": "deny"
      }
    }
  }
}

Note: The config key is agent (singular), not agents.

Advanced Configuration Fields

FieldTypeDescription
temperaturenumberCreativity parameter (0-1), lower is more deterministic
top_pnumberNucleus sampling parameter (0-1)
variantstringDefault model variant (only effective when using the model configured for this Agent)
stepsnumberMaximum iteration steps
colorstringHex color (e.g., #FF5733) or theme color name (e.g., primary)
hiddenbooleanHide from @ menu (only effective for subagents)

maxSteps is deprecated, use steps instead.

For detailed configuration, see 5.2 Custom Agents.

Command Configuration

Define commands in the configuration file:

jsonc
{
  "command": {
    "test": {
      "template": "Run tests and show failed results",
      "description": "Run tests",
      "agent": "build",
      "model": "anthropic/claude-opus-4-5-thinking"
    },
    "component": {
      "template": "Create a React component named $ARGUMENTS",
      "description": "Create new component"
    }
  }
}

Note: The config key is command (singular), not commands.

FieldDescription
templateCommand template, $ARGUMENTS represents the argument
descriptionCommand description
agentAgent to use
modelModel to use
subtaskWhether to run as a subtask

For detailed configuration, see 5.4 Custom Commands.

Formatter Configuration

Configure code formatters:

json
{
  "formatter": {
    "prettier": {
      "disabled": true
    },
    "custom-prettier": {
      "command": ["npx", "prettier", "--write", "$FILE"],
      "environment": {
        "NODE_ENV": "development"
      },
      "extensions": [".js", ".ts", ".jsx", ".tsx"]
    }
  }
}

Note: The config key is formatter (singular), not formatters.

Set to false to completely disable formatting:

json
{
  "formatter": false
}

For detailed configuration, see 5.18 Formatters.

MCP Configuration

Configure MCP servers:

json
{
  "mcp": {
    "context7": {
      "type": "local",
      "command": ["npx", "-y", "@upstash/context7-mcp"]
    },
    "sentry": {
      "type": "remote",
      "url": "https://mcp.sentry.dev/mcp",
      "headers": {
        "Authorization": "Bearer your-token"
      },
      "oauth": {
        "clientId": "xxx",
        "clientSecret": "xxx",
        "scope": "read write"
      }
    }
  }
}

Remote MCP servers support headers (custom request headers) and oauth (OAuth authentication). Set oauth to false to disable automatic OAuth detection.

For detailed configuration, see 5.7 MCP Extensions.

Plugin Configuration

Load npm plugins:

json
{
  "plugin": ["opencode-helicone-session", "@my-org/custom-plugin"]
}

You can also place local plugins (.ts or .js files) in the .opencode/plugin/ directory.

For detailed configuration, see 5.12 Plugin System.

LSP Configuration

Configure LSP servers:

json
{
  "lsp": {
    "typescript": {
      "disabled": true
    },
    "custom-lsp": {
      "command": ["my-lsp-server", "--stdio"],
      "extensions": [".custom", ".myext"],
      "env": {
        "DEBUG": "true"
      },
      "initialization": {
        "settings": {}
      }
    }
  }
}
FieldDescription
disabledDisable this LSP
commandStartup command
extensionsFile extensions (required for custom LSP)
envEnvironment variables
initializationLSP initialization configuration

Set to false to disable all LSP:

json
{
  "lsp": false
}

For detailed configuration, see 5.19 LSP Servers.


Experimental Features

json
{
  "experimental": {
    "batch_tool": true,
    "openTelemetry": true,
    "continue_loop_on_deny": false
  }
}
FieldDescription
batch_toolEnable batch tools
openTelemetryEnable OpenTelemetry tracing
disable_paste_summaryDisable automatic summary when pasting large text
primary_toolsList of tools restricted to Primary Agent only
continue_loop_on_denyContinue loop when tool is denied
mcp_timeoutGlobal timeout for MCP requests (milliseconds)

⚠️ Experimental features may change or be removed at any time.

About Hooks

Hook functionality is implemented through the plugin system, not the experimental configuration. See 5.12c Hooks.


Complete Configuration Example

jsonc
{
  "$schema": "https://opencode.ai/config.json",
  
  // === Models ===
  "model": "anthropic/claude-opus-4-5-thinking",
  "small_model": "anthropic/claude-haiku-4-5",
  "default_agent": "build",
  
  // === Provider ===
  "provider": {
    "anthropic": {
      "options": {
        "apiKey": "{env:ANTHROPIC_API_KEY}",
        "timeout": 600000,
        "setCacheKey": true
      }
    },
    "openai": {
      "models": {
        "gpt-4o": {
          "provider": {
            "api": "https://custom-api.example.com/v1"
          }
        }
      }
    }
  },
  "disabled_providers": ["gemini"],
  
  // === User ===
  "username": "Developer",
  
  // === Interface ===
  "theme": "catppuccin",
  "tui": {
    "scroll_speed": 3,
    "diff_style": "auto"
  },
  "keybinds": {
    "leader": "ctrl+x",
    "session_new": "<leader>n"
  },
  
  // === Server ===
  "server": {
    "port": 4096,
    "hostname": "localhost"
  },
  
  // === Behavior ===
  "share": "manual",
  "compaction": {
    "auto": true,
    "prune": true
  },
  "autoupdate": true,
  "watcher": {
    "ignore": ["node_modules/**", "dist/**"]
  },
  "instructions": ["CONTRIBUTING.md"],
  
  // === Permissions ===
  "permission": {
    "edit": "ask",
    "bash": {
      "*": "ask",
      "git *": "allow"
    }
  },
  
  // === Agent ===
  "agent": {
    "code-reviewer": {
      "description": "Code review expert",
      "mode": "subagent",
      "temperature": 0.2,
      "permission": {
        "edit": "deny"
      }
    }
  },
  
  // === Commands ===
  "command": {
    "test": {
      "template": "Run tests",
      "description": "Run test suite"
    }
  },
  
  // === Formatter ===
  "formatter": {
    "prettier": {
      "disabled": false
    }
  },
  
  // === MCP ===
  "mcp": {
    "context7": {
      "type": "local",
      "command": ["npx", "-y", "@upstash/context7-mcp"]
    }
  }
}

Common Pitfalls

IssueCauseSolution
Used keybindWrong key nameShould be keybinds (plural)
Used permissionsWrong key nameShould be permission (singular)
Used agentsWrong key nameShould be agent (singular)
Used commandsWrong key nameShould be command (singular)
Used formattersWrong key nameShould be formatter (singular)
Used tui.themeWrong key nameUse theme directly
tools config not workingLegacy configRecommend using permission
baseURL not workingWrong locationShould be in provider.options.baseURL, not top-level
Model API URL not workingWrong fieldModel-level uses provider.api, Provider-level uses options.baseURL
Keybind conflictsTerminal conflictUse leader key prefix
LSP customization failedMissing extensionsCustom LSP must specify extensions

Config Key Quick Reference

Config ItemCorrect KeyCommon Mistake
Providerproviderproviders
Permissionpermissionpermissions
Agentagentagents
Commandcommandcommands
Formatterformatterformatters
Keybindskeybindskeybind
Themethemetui.theme

Lesson Summary

You learned:

  1. Interface configuration: TUI, keybinds, server
  2. Behavior configuration: share, compaction, watcher, instruction files
  3. Feature configuration: Provider, tools, permissions, agents, commands, formatters, MCP, plugins, LSP
  4. Experimental features: batch tools, OpenTelemetry, etc.
  5. Custom model API URLs (v1.1.60+)


Next Lesson Preview

In the next lesson, we'll learn how to create custom Agents.