# OpenCode

Open-source terminal coding agent with a TUI, client/server architecture, and support for many model providers.

Schema: 1.0 · Data: ee5de863c30bdbe4fe7dd3e07c7e22ea9bf4ab2248dbc7c35cdbf60bc28be1db

## Configuration

### MCP

Status: supported

Configure MCP servers under the mcp key in opencode.json or opencode.jsonc. Local servers run as commands; remote servers connect over HTTP with header or OAuth auth.

- project: `opencode.json` (json) — key: mcp — JSONC (opencode.jsonc) is also supported.
- global: `~/.config/opencode/opencode.json` (json) — key: mcp
- project: `opencode.jsonc` (jsonc) — key: mcp
- global: `~/.config/opencode/opencode.jsonc` (jsonc) — key: mcp
- `type`: "local" | "remote" (required) — Server connection type. Values: local, remote
- `command`: string[] — Required 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 — Required 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.
- transports: stdio, http
- auth: oauth, headers
- Tools: supported — MCP tools are automatically available to the LLM alongside built-in tools.
- add-mcp 2.3.1 defaults new installs to opencode.jsonc and reuses existing JSON/JSONC files. This installer selection is distinct from native config merge precedence; see https://opencode.ai/docs/config/.
- 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.

Local server
```json
{
  "$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" }
    }
  }
}

```


Remote server with headers
```json
{
  "$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" }
    }
  }
}

```

Source: https://opencode.ai/docs/mcp-servers/
Checked: 2026-09-07

### Skills

Status: supported

SKILL.md instruction sets discovered from project and home directories, listed in the native skill tool and loaded on demand by the agent.

- project: `.opencode/skills/<name>/SKILL.md` (markdown) — OpenCode walks up from the working directory to the git worktree root.
- global: `~/.config/opencode/skills/<name>/SKILL.md` (markdown)
- project: `.claude/skills/<name>/SKILL.md` (markdown) — Claude Code-compatible location. Disable with OPENCODE_DISABLE_CLAUDE_CODE_SKILLS=1.
- global: `~/.claude/skills/<name>/SKILL.md` (markdown) — Claude Code-compatible location.
- project: `.agents/skills/<name>/SKILL.md` (markdown) — Agent-compatible location.
- global: `~/.agents/skills/<name>/SKILL.md` (markdown) — Agent-compatible location.
- `name`: string (required) — Skill identifier: 1-64 chars, lowercase alphanumeric with single hyphen separators, must match the directory name.
- `description`: string (required) — 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.
- invocation: automatic (skill tool)
- 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.

Skill with frontmatter
```markdown
---
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.

```


Skill permissions in opencode.json
```json
{
  "permission": {
    "skill": {
      "*": "allow",
      "internal-*": "deny",
      "experimental-*": "ask"
    }
  }
}

```

Source: https://opencode.ai/docs/skills/
Checked: 2026-07-12

### Rules

Status: supported

AGENTS.md files hold persistent project and global instructions, with CLAUDE.md fallbacks and an instructions option for extra rule files.

- project: `AGENTS.md` (markdown) — Project rules, found by traversing up from the current directory. Commit to Git.
- global: `~/.config/opencode/AGENTS.md` (markdown) — Personal rules applied across all sessions.
- project: `CLAUDE.md` (markdown) — Claude Code-compatible fallback, used only if no AGENTS.md exists.
- global: `~/.claude/CLAUDE.md` (markdown) — Claude Code-compatible fallback, used only if no ~/.config/opencode/AGENTS.md exists.
- project: `opencode.json` (json) — key: instructions — Array of paths, globs, or URLs to additional instruction files.
- `instructions`: string[] — Paths, glob patterns, or remote URLs of instruction files to include (e.g. CONTRIBUTING.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.

Reuse existing rule files
```json
{
  "$schema": "https://opencode.ai/config.json",
  "instructions": ["CONTRIBUTING.md", "docs/guidelines.md", ".cursor/rules/*.md"]
}

```

Source: https://opencode.ai/docs/rules/
Checked: 2026-07-12

### Hooks

Status: supported

Lifecycle hooks are implemented through the plugin system: JS/TS modules that hook into agent events to observe, block, or rewrite behavior.

- project: `.opencode/plugins/` (typescript) — Directory of JS/TS plugin modules, auto-loaded at startup.
- global: `~/.config/opencode/plugins/` (typescript) — Directory of JS/TS plugin modules, auto-loaded at startup.
- project: `opencode.json` (json) — key: plugin — Array of npm package names to load as plugins (regular and scoped packages).
- `plugin`: string[] — npm packages to load as plugins, e.g. ["opencode-helicone-session", "@my-org/custom-plugin"].
- events: tool.execute.before, tool.execute.after, shell.env, experimental.session.compacting, event
- 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/.

Block reads of .env files
```javascript
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")
      }
    },
  }
}

```


Notify when a session goes idle
```javascript
export const NotificationPlugin = async ({ $ }) => {
  return {
    event: async ({ event }) => {
      if (event.type === "session.idle") {
        await $`osascript -e 'display notification "Session completed!" with title "opencode"'`
      }
    },
  }
}

```

Source: https://opencode.ai/docs/plugins/
Checked: 2026-07-12

### Commands

Status: supported

Custom slash commands defined as markdown files with frontmatter or inline in opencode.json, with argument placeholders, shell output injection, and file references.

- project: `.opencode/commands/<name>.md` (markdown)
- global: `~/.config/opencode/commands/<name>.md` (markdown)
- project: `opencode.json` (json) — key: command — Inline command definitions; template is required in this form.
- `template`: string (required) — 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.
- invocation: /command-name
- 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.

Command file (.opencode/commands/test.md)
```markdown
---
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.

```


Command with arguments
```markdown
---
description: Create a new component
---

Create a new React component named $ARGUMENTS with TypeScript support.
Include proper typing and basic structure.

```

Source: https://opencode.ai/docs/commands/
Checked: 2026-07-12

### Settings

Status: supported

opencode.json (or .jsonc) configures models, agents, permissions, tools, MCP, commands, and plugins, merged across remote, global, project, and managed scopes.

- project: `opencode.json` (json) — Found in the current directory or by traversing up to the nearest Git directory. JSONC (opencode.jsonc) also supported. Schema: https://opencode.ai/config.json.
- global: `~/.config/opencode/opencode.json` (json) — User-wide preferences like providers, models, and permissions.
- enterprise: `/Library/Application Support/opencode/opencode.json` (json) — Managed config, requires admin to write. Linux: /etc/opencode/; Windows: %ProgramData%\opencode. Not user-overridable.
- project: `tui.json` (json) — TUI-specific settings; also available globally at ~/.config/opencode/tui.json.
- project: `opencode.jsonc` (jsonc)
- global: `~/.config/opencode/opencode.jsonc` (jsonc)
- `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" }. Values: allow, ask, deny
- `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. Values: manual, auto, disabled
- `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.
- 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.

Basic config
```jsonc
{
  "$schema": "https://opencode.ai/config.json",
  "model": "anthropic/claude-sonnet-4-5",
  "autoupdate": true,
  "permission": {
    "edit": "ask",
    "bash": "ask"
  }
}

```

Source: https://opencode.ai/docs/config/
Checked: 2026-07-12

## Search, browser & identification

Not researched. Unknown does not mean unsupported.
