Use when configuring OpenCode (opencode.json), setting up providers, agents, MCP servers, LSP servers, permissions, or any opencode.json configuration questions
Complete reference for OpenCode configuration surfaces, not just opencode.json. Covers configuration files, environment variables, variable substitution ({env:...} and {file:...}), provider credentials, precedence order, and all major OpenCode settings including models, providers, agents, permissions, commands, MCP servers, LSP servers, formatters, server settings, and advanced behavior toggles.
Use this document with the following mental model:
{env:VAR} / {file:path} substitution lets config files reference secrets or external file contents without hardcoding themOpenCode configuration comes from four different mechanisms. Users often only look for opencode.json settings first, but some important behavior is configured elsewhere.
| Surface | Best for | Typical examples |
| ---------------------------- | ------------------------------------------------------ | -------------------------------------------------------------------------------------- |
| Config files | Persistent user/project configuration | model, provider, agent, permission, mcp, lsp, formatter |
| Environment variables | Runtime overrides, CI, startup behavior, feature flags | OPENCODE_CONFIG, OPENCODE_SERVER_PASSWORD, OPENCODE_DISABLE_LSP_DOWNLOAD |
| Variable substitution | Keeping secrets and deploy-specific values out of JSON | {env:ANTHROPIC_API_KEY}, {file:~/.secrets/openai-key} |
| Provider credential env vars | Authenticating LLM providers | ANTHROPIC_API_KEY, OPENAI_API_KEY, AWS_PROFILE, GOOGLE_APPLICATION_CREDENTIALS |
Quick rule of thumb:
{env:...}Use these rules when deciding how to express a configuration answer.
model, provider, agent, permission, command, mcp, lsp, formatter, and server{env:VAR} inside config when{env:...}.opencode.json, do not assume it is unsupported; check whether it is env-driven.OPENCODE_* runtime flags.These are common incorrect conclusions that agents may make when reading OpenCode config docs.
opencode.json, it is not configurable.”Incorrect. Some meaningful OpenCode behavior is env-only or env-first. Examples include:
OPENCODE_SERVER_PASSWORDOPENCODE_SERVER_USERNAMEOPENCODE_DISABLE_LSP_DOWNLOADOPENCODE_MODELS_PATHOPENCODE_CONFIG_CONTENTIncorrect. There are at least three different roles:
These should not be mixed together when explaining configuration.
Usually incorrect. The preferred pattern is:
{env:...}server object.”Incorrect. The server object configures network behavior. HTTP basic auth is controlled by OPENCODE_SERVER_PASSWORD and OPENCODE_SERVER_USERNAME.
lsp object.”Incorrect. LSP server definitions live under lsp, but runtime installation/download behavior is controlled by env vars such as OPENCODE_DISABLE_LSP_DOWNLOAD.
OpenCode loads configurations in the following order (later overrides earlier):
.well-known/opencode (organization defaults)~/.config/opencode/opencode.json{,c} (user global config, also reads legacy config.json)OPENCODE_CONFIG environment variableopencode.json or opencode.jsonc in project root (searched upward).opencode Directory - Auto-discovered agents, commands, plugins, and config from multiple .opencode locations:
.opencode/ directories (searched upward from project root)~/.opencode/ (user home directory)OPENCODE_CONFIG_DIR environment variable (if set)OPENCODE_CONFIG_CONTENT environment variable/Library/Application Support/opencode/opencode.json{,c}C:\ProgramData\opencode\opencode.json{,c}/etc/opencode/opencode.json{,c}Supports JSON and JSONC (JSON with Comments) formats:
{
"$schema": "https://opencode.ai/config.json",
// This is a comment
"theme": "opencode",
"model": "anthropic/claude-sonnet-4-5",
}
$schemastring"https://opencode.ai/config.json"themestring"opencode", "dracula", "nord"usernamestring"Alice"logLevel"DEBUG" | "INFO" | "WARN" | "ERROR""INFO"autoupdateboolean | "notify"truetrue - Automatically download and install updatesfalse - Disable auto-updates"notify" - Only notify about new versionsshare"manual" | "auto" | "disabled""manual""manual" - Share manually via /share command"auto" - Automatically share new sessions"disabled" - Completely disable sharingsnapshotbooleanNote: Configuration values support
{env:VAR_NAME}and{file:path}variable substitution. See Variable Substitution for details.
modelstringprovider/model{
"model": "anthropic/claude-sonnet-4-5",
}
small_modelstringprovider/model{
"small_model": "anthropic/claude-haiku-4-5",
}
providerobjectSee also: Environment Variables for model-source env vars like
OPENCODE_MODELS_URL,OPENCODE_MODELS_PATH,OPENCODE_DISABLE_MODELS_FETCH,OPENCODE_ENABLE_EXPERIMENTAL_MODELS, and provider credential env vars likeANTHROPIC_API_KEY,OPENAI_API_KEY, andAWS_*.
{
"provider": {
"anthropic": {
"name": "Anthropic", // Display name
"npm": "@ai-sdk/anthropic", // npm package name
"options": {
"apiKey": "{env:ANTHROPIC_API_KEY}", // API key
"baseURL": "https://api.anthropic.com/v1", // Custom endpoint
"timeout": 300000, // Request timeout (ms), default 300000 (5 min). Set to false to disable entirely.
"setCacheKey": true, // Enable prompt caching
"enterpriseUrl": "https://github.example.com", // GitHub Enterprise URL (for copilot provider)
},
"models": {
"claude-sonnet-4-5": {
"name": "Claude Sonnet 4.5",
"limit": {
"context": 200000, // Context window
"output": 8192, // Maximum output
},
"variants": {
// Variant-specific configuration
"extended": {
"disabled": false, // Disable this variant
},
},
},
},
"whitelist": ["claude-*"], // Allowed model list (glob patterns)
"blacklist": ["claude-2"], // Blocked model list (glob patterns)
},
},
}
{
"provider": {
"amazon-bedrock": {
"options": {
"region": "us-east-1",
"profile": "my-aws-profile",
"endpoint": "https://bedrock-runtime.us-east-1.vpce-xxxxx.amazonaws.com",
},
},
},
}
disabled_providersstring[]enabled_providers){
"disabled_providers": ["openai", "gemini"],
}
enabled_providersstring[]{
"enabled_providers": ["anthropic", "openai"],
}
default_agentstring"build""build", "plan"agentobject{
"agent": {
"code-reviewer": {
"description": "Code review expert",
"mode": "subagent", // "primary" | "subagent" | "all"
"model": "anthropic/claude-sonnet-4-5",
"variant": "extended", // Default model variant
"prompt": "You are a code review expert...",
"temperature": 0.3, // 0.0-1.0
"top_p": 0.9, // 0.0-1.0
"steps": 10, // Maximum agentic iteration steps
"color": "#FF5733", // Hex color or theme color
"hidden": false, // Hide from @ autocomplete (subagent only)
"disable": false, // Disable this agent
"options": {}, // Custom key-value pairs passed to the agent
"permission": {
// Agent-specific permissions
"edit": "deny",
"bash": "ask",
},
},
},
}
build - Primary agent, full-access for development workplan - Primary agent, read-only for analysis and code explorationgeneral - Subagent for complex searches and multistep tasksexplore - Subagent for code explorationtitle - Primary agent (hidden, internal) for title generationsummary - Primary agent (hidden, internal) for summarizationcompaction - Primary agent (hidden, internal) for context compaction"primary" - Primary agent, shown in UI model selector"subagent" - Subagent, called by other agents via delegation"all" - Both primary and subagent"#FF5733""primary", "secondary", "accent", "success", "warning", "error", "info"permissionobject"allow" - Allow execution"ask" - Require user confirmation"deny" - Deny execution{
"permission": {
// File operations
"read": "allow", // Read files
"edit": "ask", // Edit/write files
"glob": "allow", // File search
"grep": "allow", // Content search
"list": "allow", // List directories
// Execution operations
"bash": "ask", // Execute shell commands
"task": "allow", // Call subagents
// External access
"external_directory": "ask", // Access external directories
"webfetch": "allow", // Access web pages
"websearch": "allow", // Search engines
"codesearch": "allow", // Code search
// Other tools
"todowrite": "allow", // Write TODOs
"todoread": "allow", // Read TODOs
"question": "allow", // Ask user
"skill": "allow", // Call skills
"lsp": "allow", // LSP operations
"doom_loop": "allow", // Doom loop detection
// Wildcard support
"mymcp_*": "ask", // MCP server tools
},
}
Permissions that support PermissionRule (read, edit, glob, grep, list, bash, task, external_directory, lsp, skill) can use pattern-based rules:
{
"permission": {
"read": {
"*.env": "deny", // Deny reading .env files
"secrets/*": "deny", // Deny reading secrets directory
"*": "allow", // Allow other files
},
"bash": {
"rm -rf*": "deny", // Deny dangerous commands
"*": "ask", // Other commands require confirmation
},
},
}
Note: todowrite, todoread, question, webfetch, websearch, codesearch, and doom_loop only accept simple permission values ("allow" | "ask" | "deny"), not pattern-based rules.
commandobject{
"command": {
"test": {
"template": "Run full test suite and show coverage report",
"description": "Run tests",
"agent": "build", // Optional: specify agent
"model": "anthropic/claude-haiku-4-5", // Optional: specify model
"subtask": false, // Run as subtask
},
"component": {
"template": "Create React component named $ARGUMENTS",
"description": "Create component",
},
},
}
$ARGUMENTS - Command argumentskeybindsobject"none" to disable a keybind.{
"keybinds": {
// Leader key
"leader": "ctrl+x", // Default: ctrl+x
// App control
"app_exit": "ctrl+c,ctrl+d,<leader>q",
// Session management
"session_new": "<leader>n",
"session_list": "<leader>l",
"session_timeline": "<leader>g",
"session_rename": "ctrl+r",
"session_delete": "ctrl+d",
"session_share": "none",
"session_unshare": "none",
"session_compact": "<leader>c",
"session_interrupt": "escape",
"session_export": "<leader>x",
"session_fork": "none",
"session_child_cycle": "<leader>right",
"session_child_cycle_reverse": "<leader>left",
"session_parent": "<leader>up",
// Stash management
"stash_delete": "ctrl+d",
// Model and agent
"model_list": "<leader>m",
"model_cycle_recent": "f2",
"model_cycle_recent_reverse": "shift+f2",
"model_cycle_favorite": "none",
"model_cycle_favorite_reverse": "none",
"model_provider_list": "ctrl+a",
"model_favorite_toggle": "ctrl+f",
"agent_list": "<leader>a",
"agent_cycle": "tab",
"agent_cycle_reverse": "shift+tab",
"variant_cycle": "ctrl+t",
"command_list": "ctrl+p",
// Input control
"input_submit": "return",
"input_newline": "shift+return,ctrl+return,alt+return,ctrl+j",
"input_clear": "ctrl+c",
"input_paste": "ctrl+v",
// Message navigation
"messages_page_up": "pageup,ctrl+alt+b",
"messages_page_down": "pagedown,ctrl+alt+f",
"messages_line_up": "ctrl+alt+y",
"messages_line_down": "ctrl+alt+e",
"messages_half_page_up": "ctrl+alt+u",
"messages_half_page_down": "ctrl+alt+d",
"messages_first": "ctrl+g,home",
"messages_last": "ctrl+alt+g,end",
"messages_next": "none",
"messages_previous": "none",
"messages_last_user": "none",
"messages_copy": "<leader>y",
"messages_undo": "<leader>u",
"messages_redo": "<leader>r",
"messages_toggle_conceal": "<leader>h",
// History navigation
"history_previous": "up",
"history_next": "down",
// UI control
"sidebar_toggle": "<leader>b",
"scrollbar_toggle": "none",
"username_toggle": "none",
"theme_list": "<leader>t",
"editor_open": "<leader>e",
"status_view": "<leader>s",
"tool_details": "none",
"tips_toggle": "<leader>h",
"display_thinking": "none",
"terminal_suspend": "ctrl+z",
"terminal_title_toggle": "none",
},
}
The above covers the most commonly customized keybinds. OpenCode also supports extensive input editing keybinds (cursor movement, selection, word operations, etc.) with Emacs-style defaults. See official documentation for the full list: https://opencode.ai/docs/keybinds/
tuiobject{
"tui": {
"scroll_speed": 3, // Scroll speed multiplier (minimum: 0.001)
"scroll_acceleration": {
"enabled": true, // macOS-style inertial scrolling
},
"diff_style": "auto", // "auto" | "stacked"
},
}
scroll_speed - Mouse wheel speed multiplier (effective when scroll_acceleration.enabled is false)scroll_acceleration.enabled - Enable inertial scrolling (higher priority than scroll_speed)diff_style - Diff rendering style
"auto" - Adaptive based on terminal width"stacked" - Always show single columnserverobjectopencode serve and opencode web commandsImportant: The
serverobject controls network behavior like port, hostname, mDNS, and CORS. HTTP basic auth is not configured here; it is controlled by environment variablesOPENCODE_SERVER_PASSWORDandOPENCODE_SERVER_USERNAME. See Environment Variables.
{
"server": {
"port": 4096, // Listen port
"hostname": "0.0.0.0", // Listen address
"mdns": true, // Enable mDNS service discovery
"mdnsDomain": "myproject.local", // Custom mDNS domain (default: opencode.local)
"cors": [
// CORS allowed origins
"http://localhost:5173",
"https://app.example.com",
],
},
}
pluginstring[]{
"plugin": [
"opencode-helicone-session", // npm package
"@my-org/custom-plugin", // Scoped package
"opencode-skills@1.2.3", // Specific version
"file:///absolute/path/to/plugin.ts", // Local file
],
}
OpenCode automatically scans for plugins in:
.opencode/plugin/*.{ts,js}.opencode/plugins/*.{ts,js}~/.config/opencode/plugin/*.{ts,js}~/.config/opencode/plugins/*.{ts,js}~/.opencode/plugin/*.{ts,js}~/.opencode/plugins/*.{ts,js}skillsobject{
"skills": {
"paths": [
// Additional skill directories
"/path/to/skills",
"~/my-skills",
],
"urls": [
// Remote skill URLs
"https://example.com/.well-known/skills/",
],
},
}
mcpobjecttype field.{
"mcp": {
"my-mcp": {
"type": "local",
"command": ["npx", "-y", "my-mcp-server"], // Command and args as a single array
"environment": {
// Environment variables (note: "environment", not "env")
"API_KEY": "{env:MY_API_KEY}",
},
"enabled": true, // Enable/disable (default: true)
"timeout": 5000, // Request timeout in ms (default: 5000)
},
},
}
{
"mcp": {
"remote-mcp": {
"type": "remote",
"url": "https://mcp.example.com/sse",
"headers": {
// Custom request headers
"Authorization": "Bearer {env:MCP_TOKEN}",
},
"oauth": {
// OAuth authentication (optional)
"clientId": "my-client-id",
"clientSecret": "{env:OAUTH_SECRET}",
"scope": "read write",
},
// Set "oauth": false to disable OAuth auto-detection
"enabled": true,
"timeout": 5000,
},
},
}
Local (type: "local"):
type - Must be "local"command - Command and arguments as a string array (e.g., ["npx", "-y", "server"])environment - Environment variablesenabled - Whether enabled (default: true)timeout - Request timeout in milliseconds (default: 5000)Remote (type: "remote"):
type - Must be "remote"url - Remote MCP endpoint URLheaders - Custom HTTP headersoauth - OAuth config object, or false to disable OAuth auto-detectionenabled - Whether enabled (default: true)timeout - Request timeout in milliseconds (default: 5000){
"mcp": {
"existing-mcp": {
"enabled": false,
},
},
}
lspobject | falsefalse to disable all LSP servers.See also: Environment Variables for runtime LSP behavior flags like
OPENCODE_DISABLE_LSP_DOWNLOAD,OPENCODE_EXPERIMENTAL_LSP_TOOL, andOPENCODE_EXPERIMENTAL_LSP_TY.
{
"lsp": {
// Disable a built-in LSP server
"typescript": {
"disabled": true,
},
// Add a custom LSP server
"my-lsp": {
"command": ["my-language-server", "--stdio"],
"extensions": [".myext", ".myx"], // Required for custo
<!-- Content truncated for initial SEO render. Open the source file tab for the full file. -->
npx skills add fkxxyz/opencode-configuration下载完整 Skill 目录,包含 SKILL.md 及所有相关文件
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer