OpenCode
CLISST
Open-source terminal coding agent with a TUI, client/server architecture, and support for many model providers.
MCP
SupportedConfigure MCP servers under the mcp key in opencode.json. Local servers run as commands; remote servers connect over HTTP with header or OAuth auth.
Config files
| Path | Scope | Format | Key |
|---|---|---|---|
opencode.jsonJSONC (opencode.jsonc) is also supported. | Project | json | mcp |
~/.config/opencode/opencode.json | Global | json | mcp |
Fields
| Field | Type | Description |
|---|---|---|
type* | "local" | "remote" | Server connection type. |
command* | string[] | For local servers: command and arguments to run the MCP server. |
environment | record<string, string> | Environment variables to set when running a local server. |
cwd | string | Working directory for a local server process. Relative paths resolve from the workspace. |
url* | string | For remote servers: URL of the remote MCP server. |
headers | record<string, string> | Headers to send with requests to a remote server (e.g. Authorization). |
oauth | { clientId?: string, clientSecret?: string, scope?: string } | false | OAuth config for pre-registered client credentials, or false to disable automatic OAuth detection. |
enabled | boolean | Enable or disable the MCP server on startup. |
timeout | number | Timeout in ms for fetching tools from the MCP server. Defaults to 5000. |
Capabilities
Examples
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"my-local-mcp-server": {
"type": "local",
"command": ["npx", "-y", "my-mcp-command"],
"enabled": true,
"environment": { "MY_ENV_VAR": "my_env_var_value" }
}
}
}{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"my-remote-mcp": {
"type": "remote",
"url": "https://my-mcp-server.com",
"enabled": true,
"headers": { "Authorization": "Bearer MY_API_KEY" }
}
}
}- •Local servers use type 'local' with command as an array; remote servers use type 'remote' with url.
- •OAuth is automatic for remote servers: OpenCode detects 401 responses, uses Dynamic Client Registration (RFC 7591), and stores tokens in ~/.local/share/opencode/mcp-auth.json. Manage with `opencode mcp auth|list|logout|debug`.
- •MCP tools register with the server name as prefix and can be enabled/disabled globally or per agent via the tools option with glob patterns (e.g. "my-mcp*": false).
- •Organizations can ship default MCP servers via a .well-known/opencode remote config; local configs override them per server.
Skills
SupportedSKILL.md instruction sets discovered from project and home directories, listed in the native skill tool and loaded on demand by the agent.
Config files
| Path | Scope | Format | Key |
|---|---|---|---|
.opencode/skills/<name>/SKILL.mdOpenCode walks up from the working directory to the git worktree root. | Project | markdown | — |
~/.config/opencode/skills/<name>/SKILL.md | Global | markdown | — |
.claude/skills/<name>/SKILL.mdClaude Code-compatible location. Disable with OPENCODE_DISABLE_CLAUDE_CODE_SKILLS=1. | Project | markdown | — |
~/.claude/skills/<name>/SKILL.mdClaude Code-compatible location. | Global | markdown | — |
.agents/skills/<name>/SKILL.mdAgent-compatible location. | Project | markdown | — |
~/.agents/skills/<name>/SKILL.mdAgent-compatible location. | Global | markdown | — |
Fields
| Field | Type | Description |
|---|---|---|
name* | string | Skill identifier: 1-64 chars, lowercase alphanumeric with single hyphen separators, must match the directory name. |
description* | string | What the skill does and when to use it (1-1024 chars). |
license | string | Optional license identifier. |
compatibility | string | Optional compatibility hint. |
metadata | record<string, string> | Optional string-to-string metadata map. |
Examples
---
name: git-release
description: Create consistent releases and changelogs
license: MIT
compatibility: opencode
metadata:
audience: maintainers
---
## What I do
- Draft release notes from merged PRs
- Propose a version bump
## When to use me
Use this when you are preparing a tagged release.{
"permission": {
"skill": {
"*": "allow",
"internal-*": "deny",
"experimental-*": "ask"
}
}
}- •Skills are loaded on demand via the native skill tool: available skills are listed in the tool description and the agent calls skill({ name }) to load the full content.
- •Claude-compatible (.claude/skills/) and agent-compatible (.agents/skills/) locations are also searched, in projects and in the home directory.
- •Only name, description, license, compatibility, and metadata frontmatter fields are recognized; unknown fields are ignored.
- •Access is controlled with pattern-based permissions under permission.skill in opencode.json (allow/deny/ask), overridable per agent; set tools.skill = false to disable skills for an agent entirely.
Rules
SupportedAGENTS.md files hold persistent project and global instructions, with CLAUDE.md fallbacks and an instructions option for extra rule files.
Config files
| Path | Scope | Format | Key |
|---|---|---|---|
AGENTS.mdProject rules, found by traversing up from the current directory. Commit to Git. | Project | markdown | — |
~/.config/opencode/AGENTS.mdPersonal rules applied across all sessions. | Global | markdown | — |
CLAUDE.mdClaude Code-compatible fallback, used only if no AGENTS.md exists. | Project | markdown | — |
~/.claude/CLAUDE.mdClaude Code-compatible fallback, used only if no ~/.config/opencode/AGENTS.md exists. | Global | markdown | — |
opencode.jsonArray of paths, globs, or URLs to additional instruction files. | Project | json | instructions |
Fields
| Field | Type | Description |
|---|---|---|
instructions | string[] | Paths, glob patterns, or remote URLs of instruction files to include (e.g. CONTRIBUTING.md, .cursor/rules/*.md). |
Examples
{
"$schema": "https://opencode.ai/config.json",
"instructions": ["CONTRIBUTING.md", "docs/guidelines.md", ".cursor/rules/*.md"]
}- •Run /init to scan the repo and generate or improve the project AGENTS.md.
- •Precedence: local files found by traversing up from the current directory (AGENTS.md wins over CLAUDE.md), then ~/.config/opencode/AGENTS.md, then ~/.claude/CLAUDE.md.
- •Claude Code compatibility can be disabled with OPENCODE_DISABLE_CLAUDE_CODE=1 (all) or OPENCODE_DISABLE_CLAUDE_CODE_PROMPT=1 (only ~/.claude/CLAUDE.md).
- •The instructions option accepts paths, glob patterns, and remote URLs (fetched with a 5s timeout); all instruction files are combined with AGENTS.md.
Hooks
SupportedLifecycle hooks are implemented through the plugin system: JS/TS modules that hook into agent events to observe, block, or rewrite behavior.
Config files
| Path | Scope | Format | Key |
|---|---|---|---|
.opencode/plugins/Directory of JS/TS plugin modules, auto-loaded at startup. | Project | typescript | — |
~/.config/opencode/plugins/Directory of JS/TS plugin modules, auto-loaded at startup. | Global | typescript | — |
opencode.jsonArray of npm package names to load as plugins (regular and scoped packages). | Project | json | plugin |
Fields
| Field | Type | Description |
|---|---|---|
plugin | string[] | npm packages to load as plugins, e.g. ["opencode-helicone-session", "@my-org/custom-plugin"]. |
Examples
export const EnvProtection = async ({ project, client, $, directory, worktree }) => {
return {
"tool.execute.before": async (input, output) => {
if (input.tool === "read" && output.args.filePath.includes(".env")) {
throw new Error("Do not read .env files")
}
},
}
}export const NotificationPlugin = async ({ $ }) => {
return {
event: async ({ event }) => {
if (event.type === "session.idle") {
await $`osascript -e 'display notification "Session completed!" with title "opencode"'`
}
},
}
}- •There is no declarative shell-hook config; hooks are functions returned by plugin modules written in JavaScript or TypeScript (typed via @opencode-ai/plugin).
- •The generic event hook receives bus events such as session.idle, session.created, file.edited, permission.asked, tool.execute.before/after, message.updated, and tui.* events.
- •tool.execute.before can throw to block a tool call or mutate args to rewrite input; shell.env injects environment variables into all shell execution.
- •Plugins can also register custom tools via the tool helper, and experimental.session.compacting customizes or replaces the compaction prompt.
- •Plugin load order: global config, project config, ~/.config/opencode/plugins/, .opencode/plugins/. npm plugins are installed with Bun and cached in ~/.cache/opencode/node_modules/.
Commands
SupportedCustom slash commands defined as markdown files with frontmatter or inline in opencode.json, with argument placeholders, shell output injection, and file references.
Config files
| Path | Scope | Format | Key |
|---|---|---|---|
.opencode/commands/<name>.md | Project | markdown | — |
~/.config/opencode/commands/<name>.md | Global | markdown | — |
opencode.jsonInline command definitions; template is required in this form. | Project | json | command |
Fields
| Field | Type | Description |
|---|---|---|
template* | string | The prompt sent to the LLM when the command runs (the markdown body in file-based commands). |
description | string | Brief description shown in the TUI when typing the command. |
agent | string | Agent that executes the command. Subagents trigger a subagent invocation by default. |
subtask | boolean | Force the command to run as a subagent invocation to keep it out of the primary context. |
model | string | Model override for this command. |
Examples
---
description: Run tests with coverage
agent: build
---
Run the full test suite with coverage report and show any failures.
Focus on the failing tests and suggest fixes.---
description: Create a new component
---
Create a new React component named $ARGUMENTS with TypeScript support.
Include proper typing and basic structure.- •The markdown file name becomes the command name; the frontmatter defines properties and the body becomes the prompt template.
- •Templates support $ARGUMENTS, positional $1/$2/$3 arguments, !`command` to inject shell output, and @path to include file contents.
- •Custom commands can override built-in commands like /init, /undo, /redo, /share, and /help.
Settings
Supportedopencode.json (or .jsonc) configures models, agents, permissions, tools, MCP, commands, and plugins, merged across remote, global, project, and managed scopes.
Config files
| Path | Scope | Format | Key |
|---|---|---|---|
opencode.jsonFound in the current directory or by traversing up to the nearest Git directory. JSONC (opencode.jsonc) also supported. Schema: https://opencode.ai/config.json. | Project | json | — |
~/.config/opencode/opencode.jsonUser-wide preferences like providers, models, and permissions. | Global | json | — |
/Library/Application Support/opencode/opencode.jsonManaged config, requires admin to write. Linux: /etc/opencode/; Windows: %ProgramData%\opencode. Not user-overridable. | Enterprise | json | — |
tui.jsonTUI-specific settings; also available globally at ~/.config/opencode/tui.json. | Project | json | — |
Fields
| Field | Type | Description |
|---|---|---|
model | string | Default model in provider/model format, e.g. anthropic/claude-sonnet-4-5. |
small_model | string | Separate model for lightweight tasks like title generation. |
provider | object | Provider configuration: API keys, base URLs, custom models, timeouts. |
agent | object | Specialized agent definitions with per-agent prompt, model, tools, and permissions. |
default_agent | string | Primary agent used when none is specified (e.g. build or plan). |
permission | object | Approval rules per tool or pattern, e.g. { "edit": "ask", "bash": "ask" }. |
tools | record<string, boolean> | Enable or disable tools (including MCP tools) globally, with glob pattern support. |
mcp | object | MCP server definitions (see MCP surface). |
instructions | string[] | Additional instruction files (see Rules surface). |
command | object | Inline custom command definitions (see Commands surface). |
plugin | string[] | npm packages to load as plugins (see Hooks surface). |
share | "manual" | "auto" | "disabled" | Conversation sharing behavior. Default manual. |
autoupdate | boolean | "notify" | Automatically download updates on startup, or notify only. |
snapshot | boolean | Track file changes for undo/revert. Disable for large repos. |
formatter | boolean | object | Enable code formatters, or configure overrides and custom formatters. |
lsp | boolean | object | Enable LSP servers, or configure overrides and custom servers. |
compaction | { auto?: boolean, prune?: boolean, reserved?: number } | Context compaction behavior. |
server | { port?: number, hostname?: string, mdns?: boolean, cors?: string[] } | Server settings for opencode serve and opencode web. |
disabled_providers | string[] | Providers to never load, even if credentials are available. Takes priority over enabled_providers. |
enabled_providers | string[] | Allowlist of providers; all others are ignored. |
Examples
{
"$schema": "https://opencode.ai/config.json",
"model": "anthropic/claude-sonnet-4-5",
"autoupdate": true,
"permission": {
"edit": "ask",
"bash": "ask"
}
}- •Precedence (later overrides earlier): remote .well-known/opencode config, global config, OPENCODE_CONFIG path, project config, .opencode directories, OPENCODE_CONFIG_CONTENT, managed config files, macOS managed preferences (MDM).
- •Configs are merged, not replaced: non-conflicting keys from all sources are preserved.
- •Values support {env:VARIABLE_NAME} and {file:path} substitution.
- •TUI-specific settings (theme, keybinds, scroll, notifications) live in a separate tui.json with schema https://opencode.ai/tui.json.
- •On macOS, managed preferences deploy via .mobileconfig in the ai.opencode.managed preference domain; Linux uses /etc/opencode/, Windows %ProgramData%\opencode.