OpenCode is the open-source terminal AI coding agent from sst.dev, written in TypeScript and Go, runs on Bun, and speaks every major LLM provider. The surface area is large: 18 top-level CLI commands, dozens of subcommands, 60+ keyboard shortcuts in the TUI, a custom-commands system, a permissions engine, AGENTS.md project memory, MCP server management, ACP integration for IDEs, plan mode, multi-agent workflows, and 30+ environment variables. This cheat sheet condenses the entire surface into one page, with real outputs captured on Ubuntu 26.04 LTS using OpenCode 1.14.33 against Anthropic Claude.
If you came from the OpenCode setup guide or the Oh-My-OpenAgent install guide, this is the working reference to keep open while you code.
Verified working: May 2026 with OpenCode 1.14.33 on Ubuntu 26.04 LTS, tested with Anthropic Claude (24 models loaded), the OpenCode-hosted free tier, and an explicit MCP and custom-command setup.
Quick install reminder
sudo npm install -g opencode-ai
opencode --version
In the output is the version number of OpenCode installed.
1.14.33
If your CPU lacks AVX support (some default QEMU/KVM guest types) the embedded Bun runtime crashes on launch. Switch the VM CPU type to host or pick a runtime that exposes AVX2. Verify inside the guest with grep -m1 -oE 'avx[0-9a-z]*' /proc/cpuinfo. Full prerequisites and provider login flows live in the OpenCode setup walkthrough.
Top-level command map
| Command | Purpose |
|---|---|
opencode [project] | Launch the TUI in the given directory (default). |
opencode run [message..] | One-shot headless invocation. |
opencode serve | Headless HTTP API server other clients can attach to. |
opencode web | Headless server plus the OpenCode web UI. |
opencode attach <url> | Attach a TUI to a running server. |
opencode acp | Agent Client Protocol over stdin/stdout (IDE bridge). |
opencode auth (alias providers) | Manage providers and credentials. |
opencode models [provider] | List models, optionally filtered. |
opencode mcp | Manage MCP servers (add, list, auth, debug, logout). |
opencode agent | Manage agents (list, create). |
opencode session | List or delete sessions. |
opencode export [sessionID] | Export session data as JSON. |
opencode import <file> | Import session from JSON or share URL. |
opencode stats | Token usage and cost statistics. |
opencode github | Install or run the GitHub agent. |
opencode pr <number> | Fetch a GitHub PR branch and run OpenCode on it. |
opencode plugin <module> (alias plug) | Install a plugin npm module and update config. |
opencode debug | Debugging utilities (config, paths, agent, LSP, ripgrep, snapshot, scrap). |
opencode db | Database tools. |
opencode upgrade [target] | Upgrade OpenCode (npm, pnpm, bun, brew, choco, scoop, curl). |
opencode uninstall | Uninstall OpenCode and remove related files. |
opencode completion | Print shell completion script. |
Where OpenCode stores state
opencode debug paths prints every directory OpenCode uses. Real output from a fresh Ubuntu 26.04 install:
$ opencode debug paths
home /root
data /root/.local/share/opencode
bin /root/.cache/opencode/bin
log /root/.local/share/opencode/log
cache /root/.cache/opencode
config /root/.config/opencode
state /root/.local/state/opencode
tmp /tmp/opencode
- config:
~/.config/opencode/opencode.jsonplus per-user agents, commands, themes. - data: SQLite stores for sessions, messages, projects, plus
auth.jsonwith provider credentials. - cache: downloaded model lists, LSP server binaries, ripgrep.
- state: per-project run history, last session ID, snapshots.
- log: rolling log files, useful when chasing a hang or auth bug.
Authentication: providers, login, logout
# Interactive login picker (chooses provider, then auth method)
opencode auth login
# Pre-select provider
opencode auth login --provider anthropic
# Pre-select provider AND method
opencode auth login --provider openai --method api-key
# OAuth-style URL flow (self-hosted auth provider)
opencode auth login https://auth.example.internal
# Inspect what is configured
opencode auth list # alias: opencode auth ls
# Remove credentials
opencode auth logout
Keys via environment
Standard provider env vars work without running auth login at all. Easiest path on a server:
export ANTHROPIC_API_KEY="sk-ant-api03-..."
export OPENAI_API_KEY="sk-proj-..."
export GEMINI_API_KEY="aiza..."
export OPENROUTER_API_KEY="sk-or-..."
export OPENCODE_SERVER_PASSWORD="..." # only for attach mode
export OPENCODE_SERVER_USERNAME="opencode" # default, override if needed
Listing and choosing models
# Every model the configured providers expose
opencode models
# Filter to one provider
opencode models anthropic
opencode models openai
opencode models google
# Refresh the cached list from models.dev
opencode models --refresh
# Verbose mode prints metadata (context length, costs, capabilities)
opencode models anthropic --verbose
Real partial output after authenticating Anthropic:
$ opencode models anthropic --refresh
Models cache refreshed
anthropic/claude-3-5-haiku-20241022
anthropic/claude-3-5-haiku-latest
anthropic/claude-3-5-sonnet-20240620
anthropic/claude-3-5-sonnet-20241022
anthropic/claude-3-7-sonnet-20250219
anthropic/claude-haiku-4-5
anthropic/claude-haiku-4-5-20251001
anthropic/claude-opus-4-5
anthropic/claude-opus-4-5-20251101
anthropic/claude-opus-4-6
anthropic/claude-opus-4-6-fast
anthropic/claude-opus-4-7
... (24 models total)
Pick a model per invocation with -m provider/model:
opencode -m anthropic/claude-sonnet-4-6
opencode -m openai/gpt-5
opencode -m google/gemini-2.5-pro
opencode -m opencode/big-pickle # OpenCode hosted free tier
Global flags reference
| Flag | Purpose |
|---|---|
-m, --model | Choose provider/model. |
--variant | Provider-specific reasoning effort (high, max, minimal). |
--thinking | Show thinking blocks in the TUI. |
-c, --continue | Continue the last session. |
-s, --session | Continue a specific session by ID. |
--fork | Fork a session when continuing (preserves the original). |
--prompt | Seed the agent with a prompt at launch. |
--agent | Launch as a named agent (build, compaction, explore, custom). |
--share | Make the session shareable via URL. |
-f, --file | Attach files to the initial prompt (repeatable). |
--title | Title for the new session. |
--attach URL | Attach to a remote OpenCode server. |
-p, --password | Server basic-auth password. |
--dir | Directory to run in (or path on the remote server). |
--port | Port for the local server. |
--hostname | Hostname to bind on (default 127.0.0.1). |
--mdns | Enable mDNS service discovery (sets hostname to 0.0.0.0). |
--mdns-domain | Custom mDNS domain (default opencode.local). |
--cors | Additional CORS-allowed domains. |
--format | default (formatted) or json (raw nd-JSON events). |
--dangerously-skip-permissions | Auto-approve every permission. Disposable VMs only. |
--pure | Run without external plugins (debugging). |
--print-logs | Echo logs to stderr. |
--log-level | DEBUG, INFO, WARN, ERROR. |
-v, --version | Print version. |
Headless run and JSON events
opencode run drives the agent without the TUI. The building block for CI integration, cron jobs, and shell pipelines.
# One-shot
opencode run "review the latest commit for security issues" --dir /repo
# Pick a model + variant
opencode run --model anthropic/claude-sonnet-4-6 --variant max "refactor src/auth"
# Continue the previous session
opencode run "now write tests for the function you added" --continue
# Resume a specific session by ID
opencode run "explain the diff in src/api.ts" --session ses_2132323b6ffeuRlYHhPcU8DaZ6
# Attach to a long-running server
opencode run "deploy to staging" --attach http://server:4096 -p $OPENCODE_SERVER_PASSWORD
# Fully unattended (only on disposable VMs)
opencode run "rebase onto main and resolve trivial conflicts" \
--dangerously-skip-permissions \
--dir /repo
Real session capture (Anthropic Claude Haiku 4.5)
JSON event format for a real one-shot run, captured exactly as the CLI emitted it:
$ opencode run --model anthropic/claude-haiku-4-5 \
'What does this fibonacci function do? Reply in one sentence.' \
--dir /root/oc-demo --format json
{"type":"step_start","sessionID":"ses_2132323b6ffeuRlYHhPcU8DaZ6",
"part":{"id":"prt_decdce2a7001ReAIzGIccjb17u","type":"step-start"}}
{"type":"text","sessionID":"ses_2132323b6ffeuRlYHhPcU8DaZ6",
"part":{"type":"text",
"text":"The Fibonacci function generates a sequence of numbers where each
number is the sum of the two preceding ones (typically starting with
0 and 1)."}}
{"type":"step_finish","sessionID":"ses_2132323b6ffeuRlYHhPcU8DaZ6",
"part":{"reason":"stop","tokens":{"total":11168,"input":2,"output":34,
"cache":{"write":11132,"read":0}},
"cost":0.014087}}
Three event types in a clean run: step_start, one or more text chunks, then step_finish carrying token counts and cost. Tool calls insert tool_use and tool_result events between text chunks. Pipe the stream into jq to filter:
# Print only the assistant's text replies
opencode run "summarise this repo" --format json | jq -r 'select(.type=="text") | .part.text'
# Print final cost and token count
opencode run "fix the failing test" --format json | jq 'select(.type=="step_finish") | .part'
Server, web, and attach modes
The TUI runs on top of a local HTTP server. Detach the server, talk to it from another box, or open the same session in a browser.
# Headless server on a fixed port + LAN-bind
opencode serve --port 4096 --hostname 0.0.0.0
# Browser UI on top of a local server
opencode web --port 4096
# Attach a TUI from another machine
opencode attach http://10.0.1.10:4096 --password "$PW"
# mDNS auto-discovery on a homelab
opencode serve --mdns --mdns-domain ai.lab.local
opencode attach http://laptop.ai.lab.local:4096
Pair this with tmux or systemd to keep an OpenCode server running on your homelab and attach from any laptop on the LAN. Set OPENCODE_SERVER_PASSWORD in the systemd unit to require basic auth on every connection.
Agent Client Protocol (ACP)
ACP is OpenCode’s bridge to external clients (Zed, Cursor, custom IDEs). The protocol is line-delimited JSON over stdin/stdout. Run the ACP server and point your editor at it:
# Plain ACP over stdio
opencode acp
# ACP with explicit cwd and an HTTP fallback
opencode acp --cwd /repo --port 4096 --hostname 127.0.0.1
TUI keyboard shortcuts
The TUI uses a leader-key pattern (default Ctrl+x) plus direct shortcuts. Memorise the leader and the shortcuts that follow. The cheat sheet below is what you should print and pin next to your monitor.
Application control
| Action | Shortcut |
|---|---|
| Quit | Ctrl+C, Ctrl+D, or <leader>q |
| Command palette | Ctrl+P |
| Toggle theme | <leader>t |
| Toggle sidebar | <leader>b |
| Show status | <leader>s |
| Toggle tips | <leader>h |
| External editor | <leader>e |
| Suspend to background | Ctrl+Z |
| Interrupt running tool call | Escape |
Sessions
| Action | Shortcut |
|---|---|
| New session | <leader>n |
| List sessions | <leader>l |
| Session history | <leader>g |
| Export session | <leader>x |
| Compact context | <leader>c |
| Next child session | <leader>Right |
| Previous child session | <leader>Left |
| Parent session | <leader>Up |
Message navigation
| Action | Shortcut |
|---|---|
| Scroll to top | Ctrl+G or Home |
| Scroll to bottom | Ctrl+Alt+G or End |
| Page up / down | PageUp / PageDown |
| Half-page up / down | Ctrl+Alt+U / Ctrl+Alt+D |
| Copy last message | <leader>y |
| Undo last action | <leader>u |
| Redo | <leader>r |
| Toggle code block visibility | <leader>h |
Models, agents, and modes
| Action | Shortcut |
|---|---|
| Open model picker | <leader>m |
| Cycle to next recent model | F2 |
| Cycle to previous recent model | Shift+F2 |
| Open agent picker | <leader>a |
| Tab through agent options | Tab / Shift+Tab |
| Toggle plan mode | Tab in the input |
Input field
| Action | Shortcut |
|---|---|
| Submit | Enter |
| New line in input | Shift+Enter, Ctrl+Enter, or Alt+Enter |
| Move cursor by char | Ctrl+B / Ctrl+F (or arrows) |
| Jump to start / end of line | Ctrl+A / Ctrl+E |
| Extend selection | Shift+Arrows, Ctrl+Shift+A, Ctrl+Shift+E |
| Clear input | Ctrl+C |
| Paste | Ctrl+V |
Customising keybinds
{
"$schema": "https://opencode.ai/config.json",
"keybinds": {
"leader": "ctrl+x",
"messages_last": "ctrl+alt+g,end",
"messages_first": "ctrl+g,home",
"session_new": "<leader>n",
"model_cycle_recent": "f2",
"agent_picker": "<leader>a"
}
}
Separate alternative bindings with commas. Use <leader> to chain. Modifiers: ctrl, alt, shift, meta. Set a key to "none" to disable a default binding.
Slash commands inside the TUI
Built-in slash commands handle session lifecycle, sharing, and meta-tasks. Custom commands extend the set with project-specific prompts.
| Slash command | What it does |
|---|---|
/init | Generate AGENTS.md by analysing the current repo. Run once per project. |
/help | Show available commands and a quick keybind reference. |
/share | Generate a public URL for the current session transcript. |
/undo | Revert the agent’s last action (file edits, commits). |
/redo | Re-apply the last undone action. |
/connect | Re-authenticate or switch the active provider. |
/<custom> | Any user-defined command from .opencode/commands/ or ~/.config/opencode/commands/. |
@ file fuzzy search and image attach
Inside the input, type @ to open a fuzzy file picker. Useful patterns:
@src/auth.ts review this for SQL injection
@src/auth.ts @tests/auth_test.ts find shared validation logic
@docs/api-spec.md follow this spec when refactoring src/api/*
Drag-and-drop also works for images: drop a screenshot onto the TUI window and the next message attaches it for vision-capable models.
Custom commands
Custom commands are markdown files dropped under .opencode/commands/ (project) or ~/.config/opencode/commands/ (user). Each command becomes a slash command in the TUI.
Anatomy
# .opencode/commands/test.md
---
description: Run the test suite and fix failures
agent: build
model: anthropic/claude-sonnet-4-6
subtask: false
---
Run the project test suite, identify any failures, and fix them.
Test command output:
!`npm test`
Recent test files:
@tests/
Focus on: $ARGUMENTS
Frontmatter keys
| Key | Required | Purpose |
|---|---|---|
description | recommended | One-line description shown in the slash autocomplete. |
agent | optional | Force the command to run as a specific agent (default: current). |
model | optional | Override the model for this command only. |
subtask | optional (boolean) | Run inside a subagent so the main session keeps a clean context. |
Prompt placeholders
$ARGUMENTS: everything the user typed after the command name.$1,$2,$3: positional arguments.!`shell command`: inject the command’s stdout directly into the prompt.@path/to/fileor@dir/: include file or directory contents.
Invocation example:
# In the TUI input
/test src/auth/
# Translates to:
# Run the project test suite, identify any failures, and fix them.
# Test command output: <output of `npm test`>
# Recent test files: <contents of tests/ dir>
# Focus on: src/auth/
Modes vs Agents vs Skills
Three concepts shape OpenCode’s behaviour. They look similar but answer different questions.
| Concept | What it is | Where to define |
|---|---|---|
| Mode | A behavioural shape (build, plan, edit-only, read-only) that adjusts permissions and prompts. | opencode.json under "mode" key. |
| Agent | A named role with its own prompt, model, tools, permissions. Can be a primary agent (user-facing) or a subagent (called via task). | ~/.config/opencode/agents/<name>.md or .opencode/agents/<name>.md. |
| Skill | A reusable capability bundle. Lighter than an agent, often invocable from any agent. Includes prompts and tool restrictions. | .opencode/skills/<name>.md or installed via plugins. |
Built-in agents
Three agents ship by default:
- build (primary): the default agent. Full tool access subject to the permissions engine. Description: “executes tools based on configured permissions”.
- compaction (primary): summarises and compacts long sessions to free up context.
- explore (subagent): read-only investigator. Used when you want to look at code without risking edits.
Creating a custom agent
opencode agent create \
--description "review terraform plans for safety" \
--mode primary \
--permissions "bash,read,grep,glob,webfetch,task" \
--model anthropic/claude-sonnet-4-6 \
--path .opencode/agents/tf-reviewer.md
Available permission strings: bash, read, edit, glob, grep, webfetch, task, todowrite, websearch, lsp, skill. Modes: all, primary, subagent.
Multi-agent workflows
OpenCode’s task permission lets one agent dispatch another. A common production pattern uses a strict pipeline of read-only reviewers and a sandboxed implementor:
- @check: design reviewer, read-only, identifies risks across 8 axes (assumptions, failure modes, edge cases, compatibility, security, ops, scale, testability).
- @simplify: complexity reviewer, read-only, flags overengineering and YAGNI violations.
- @test: TDD test author, can write test files only, verifies RED before handoff.
- @make: implementor, sandboxed bash, file list constrained, RED → GREEN with regression check.
- @pm: project manager bridge, runs only
linearCLI commands.
Wired together with a /workflow custom command, this pattern takes a Linear issue ID, plans, tests, implements, and opens a draft PR autonomously. Read-only reviewers prevent accidental modifications, fresh per-task context prevents pollution.
Plan mode
Plan mode is a read-only review state. The agent reads, reasons, and proposes a plan but cannot write or execute. Toggle it from the input field with Tab, or pin a session in plan mode by launching with --agent explore or via the OPENCODE_EXPERIMENTAL_PLAN_MODE env var.
Use plan mode for: code reviews, architecture audits, “what would happen if I did X” exploration, security walk-throughs, dependency upgrade impact analysis. Once the plan is solid, drop out with Tab again and the agent applies it.
Permissions system
OpenCode runs every tool call through a permissions engine before execution. Rules live in opencode.json under "permission" and per-agent under each agent’s frontmatter. The engine evaluates rules top to bottom, first match wins.
Default permission set (build agent)
$ opencode debug agent build | head -20
{
"name": "build",
"description": "The default agent. Executes tools based on configured permissions.",
"permission": [
{ "permission": "*", "action": "allow", "pattern": "*" },
{ "permission": "doom_loop", "action": "ask", "pattern": "*" },
{ "permission": "external_directory", "action": "ask", "pattern": "*" },
{ "permission": "external_directory", "action": "allow",
"pattern": "/root/.local/share/opencode/tool-output/*" },
{ "permission": "external_directory", "action": "allow", "pattern": "/tmp/opencode/*" },
...
]
}
Three actions
allow: silent yes.ask: prompt the user, default for sensitive operations.deny: block silently, agent receives an error.
Common permission categories
bash <pattern>: shell commands.read <glob>: file reads.edit <glob>: file writes.external_directory <path>: writes outside project root.doom_loop: long-running loop heuristic guard.plan_enter/plan_exit: control plan-mode transitions.question: asking the user clarifying questions.
Production guardrail example
{
"permission": [
{ "permission": "bash", "pattern": "rm -rf *", "action": "deny" },
{ "permission": "bash", "pattern": "git push --force *","action": "deny" },
{ "permission": "bash", "pattern": "sudo *", "action": "deny" },
{ "permission": "bash", "pattern": "git push *", "action": "ask" },
{ "permission": "bash", "pattern": "linear *", "action": "deny" },
{ "permission": "read", "pattern": "*.env", "action": "ask" },
{ "permission": "read", "pattern": "*.env.example", "action": "allow" },
{ "permission": "read", "pattern": "*.env.*", "action": "ask" },
{ "permission": "*", "pattern": "*", "action": "allow" }
]
}
Then a single agent (the project manager) overrides linear * back to allow in its own frontmatter. Other agents stay locked out of Linear, only the PM agent can touch issues.
AGENTS.md project memory
OpenCode auto-loads AGENTS.md at the project root every session, the same way Claude Code reads CLAUDE.md from the .claude directory. Generate a starter via /init in the TUI:
# In the TUI
/init
OpenCode reads the repo, classifies it (Node/Python/Go/Rust/multi), and writes an AGENTS.md with: build commands, test commands, lint commands, project conventions, and a brief architecture summary. Edit the file by hand to encode any rule the agent should respect.
Compatibility with .claude and GEMINI.md
OpenCode also reads ~/.claude/CLAUDE.md, project-level .claude/skills, and GEMINI.md if present. Disable each individually:
OPENCODE_DISABLE_CLAUDE_CODE=1 # ignore .claude entirely
OPENCODE_DISABLE_CLAUDE_CODE_PROMPT=1 # ignore ~/.claude/CLAUDE.md
OPENCODE_DISABLE_CLAUDE_CODE_SKILLS=1 # ignore .claude/skills
Managing MCP servers
$ opencode mcp --help
Commands:
opencode mcp add add an MCP server
opencode mcp list list MCP servers and their status (alias: ls)
opencode mcp auth [name] authenticate with an OAuth-enabled MCP server
opencode mcp auth list list configured OAuth MCP servers
opencode mcp logout [name] remove OAuth credentials for an MCP server
opencode mcp debug <name> debug OAuth connection for an MCP server
Common MCP servers
# Filesystem (scoped path)
opencode mcp add filesystem npx -y @modelcontextprotocol/server-filesystem /home/user/projects
# GitHub
GITHUB_TOKEN=ghp_... opencode mcp add github npx -y @modelcontextprotocol/server-github
# Postgres
opencode mcp add postgres npx -y @modelcontextprotocol/server-postgres "postgresql://user:pass@host:5432/db"
# Context7 for live library docs
opencode mcp add context7 npx -y @upstash/context7-mcp@latest
# Sentry, Slack, Playwright, fal.ai, exa-search all follow the same pattern
MCP in opencode.json
{
"mcp": {
"github": {
"type": "local",
"command": ["npx", "-y", "@modelcontextprotocol/server-github"],
"environment": { "GITHUB_TOKEN": "{env:GITHUB_TOKEN}" }
},
"postgres": {
"type": "local",
"command": ["npx", "-y", "@modelcontextprotocol/server-postgres",
"postgresql://{env:PG_USER}:{env:PG_PASS}@db.lab.local/app"]
},
"remote-mcp": {
"type": "remote",
"url": "https://mcp.example.com",
"headers": { "Authorization": "Bearer {env:MCP_TOKEN}" }
}
}
}
Use {env:VAR_NAME} for secret expansion at runtime. type: local spawns a stdio process; type: remote connects via Streamable HTTP.
Sessions: list, delete, fork, share
$ opencode session list --help
opencode session list
list sessions
Options:
-n, --max-count limit to N most recent sessions
--format output format [choices: "table", "json"] [default: "table"]
# Recent sessions in a table
opencode session list -n 10
# JSON for scripting
opencode session list --max-count 50 --format json | jq '.[].id'
# Delete by ID
opencode session delete ses_2132323b6ffeuRlYHhPcU8DaZ6
# Continue most recent
opencode -c
# Continue specific session
opencode -s ses_2132323b6ffeuRlYHhPcU8DaZ6
# Fork before continuing (preserves the original)
opencode -c --fork
# Generate a shareable URL
opencode --share -m anthropic/claude-sonnet-4-6 --prompt "explain auth flow"
Export and import
# Full export with raw transcript
opencode export ses_2132323b6ffeuRlYHhPcU8DaZ6 > session.json
# Sanitised export (redacts secrets, file paths, prompts)
opencode export ses_2132323b6ffeuRlYHhPcU8DaZ6 --sanitize > session-redacted.json
# Re-import on another machine
opencode import session.json
opencode import https://opncd.ai/s/abc123
Real session JSON shape
{
"id": "ses_2132323b6ffeuRlYHhPcU8DaZ6",
"title": "What does this fibonacci function do",
"model": "anthropic/claude-haiku-4-5",
"agent": "build",
"time": { "created": 1777795391000, "updated": 1777795392442 },
"stats": { "deletions": 0, "additions": 0, "files": 0 },
"permission": [
{ "permission": "question", "pattern": "*", "action": "deny" },
{ "permission": "plan_enter", "pattern": "*", "action": "deny" },
...
],
"messages": [ /* transcript */ ]
}
Stats and cost tracking
$ opencode stats --days 7
┌────────────────────────────────────────────────────────┐
│ OVERVIEW │
├────────────────────────────────────────────────────────┤
│Sessions 1 │
│Messages 2 │
│Days 7 │
└────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────┐
│ COST & TOKENS │
├────────────────────────────────────────────────────────┤
│Total Cost $0.01 │
│Avg Cost/Day $0.00 │
│Avg Tokens/Session 11.2K │
│Median Tokens/Session 11.2K │
│Input 2 │
│Output 34 │
│Cache Read 0 │
│Cache Write 11.1K │
└────────────────────────────────────────────────────────┘
Useful flags:
--days N: rolling window. Default is all-time.--tools N: top N tools by call count. Default is all.--models: per-model breakdown. Pass a number to limit to top N.--project SLUG: filter to one project. Empty string filters to current project.
GitHub agent and PR workflows
# Install the GitHub agent (writes a .github/workflows/opencode.yml)
opencode github install
# Run it locally for testing
opencode github run
# Test with a mocked event payload
opencode github run --event issue_comment --token $GH_PAT
# Pull a PR and immediately open OpenCode on it
opencode pr 1234
The GitHub agent reacts to /opencode mentions in PR comments. Run opencode github run --event with a mocked payload during workflow development to verify behaviour without pushing branches.
Plugins
# Install per-project
opencode plugin some-opencode-plugin
# Install globally
opencode plugin some-opencode-plugin --global
# Replace an existing version
opencode plugin some-opencode-plugin --force
opencode --pure disables every plugin for one invocation. Useful for narrowing down a misbehaving session to OpenCode itself.
Debugging utilities
| Subcommand | Purpose |
|---|---|
opencode debug paths | Print all data, config, cache, state directories. |
opencode debug config | Print the resolved config (after merging user + project). |
opencode debug startup | Print startup timing in ms. |
opencode debug skill | List discovered skills. |
opencode debug agent <name> | Show a named agent’s full configuration. |
opencode debug lsp | Inspect Language Server Protocol bridges. |
opencode debug rg | Verify the bundled ripgrep binary works. |
opencode debug file | File-system bridge sanity check. |
opencode debug snapshot | Inspect or replay session snapshots. |
opencode debug scrap | List every project OpenCode has run in. |
opencode debug wait | Wait indefinitely. Used for protocol probing. |
Real outputs from a fresh box:
$ opencode debug startup
989.441416 # ms
$ opencode debug skill
[] # no skills installed yet
$ opencode debug config
{
"agent": {},
"mode": {},
"plugin": [],
"command": {},
"username": "root"
}
$ opencode debug scrap
[ { "id": "global", "worktree": "/", "time": {...}, "sandboxes": [] }, ... ]
opencode.json full reference
OpenCode reads two config files in this priority order:
./.opencode.jsonat the project root.~/.config/opencode/opencode.jsonfor user-level defaults.
Annotated reference covering every important key:
{
"$schema": "https://opencode.ai/config.json",
"model": "anthropic/claude-sonnet-4-6",
"small_model": "anthropic/claude-haiku-4-5",
"share": "manual",
"autoshare": false,
"theme": "system",
"username": "yourname",
"keybinds": {
"leader": "ctrl+x",
"session_new": "<leader>n",
"model_cycle_recent": "f2"
},
"experimental": { "hooks": true, "plan_mode": true },
"plugin": [
"@opencode-ai/plugin-prettier",
"./plugins/local-plugin.js"
],
"agent": {
"tf-reviewer": {
"description": "Read-only Terraform plan reviewer",
"mode": "primary",
"model": "anthropic/claude-sonnet-4-6",
"tools": { "edit": false, "bash": false, "read": true, "grep": true }
}
},
"mode": {
"review": {
"tools": { "edit": false, "bash": false }
}
},
"command": {
"test": { "template": "Run tests and fix failures: $ARGUMENTS" }
},
"mcp": {
"context7": {
"type": "local",
"command": ["npx", "-y", "@upstash/context7-mcp@latest"]
}
},
"permission": [
{ "permission": "bash", "pattern": "rm -rf *", "action": "deny" },
{ "permission": "bash", "pattern": "git push *","action": "ask" },
{ "permission": "*", "pattern": "*", "action": "allow"}
],
"lsp": {
"typescript": { "command": ["typescript-language-server", "--stdio"] }
},
"formatter": {
"*.py": "ruff format -",
"*.{ts,tsx,js,jsx}": "prettier --stdin-filepath {file}"
}
}
Inline config via env
For container or CI environments, ship the entire config inline:
export OPENCODE_CONFIG_CONTENT='{"model":"anthropic/claude-sonnet-4-6","permission":[...]}'
opencode run "fix the failing tests"
Or point at an alternative path:
export OPENCODE_CONFIG=/etc/opencode/prod.json
export OPENCODE_CONFIG_DIR=/etc/opencode
Environment variables
Core
| Variable | Purpose |
|---|---|
OPENCODE_CONFIG | Override path to opencode.json. |
OPENCODE_CONFIG_DIR | Override the entire config directory. |
OPENCODE_CONFIG_CONTENT | Inline JSON config (for CI / containers). |
OPENCODE_TUI_CONFIG | Override path to TUI config. |
OPENCODE_PERMISSION | Inline JSON permissions array. |
OPENCODE_AUTO_SHARE | Auto-share every session (boolean). |
OPENCODE_DISABLE_AUTOUPDATE | Skip update checks. |
OPENCODE_DISABLE_AUTOCOMPACT | Disable automatic context compaction. |
OPENCODE_DISABLE_MOUSE | Disable TUI mouse input. |
OPENCODE_DISABLE_LSP_DOWNLOAD | Skip auto-download of language servers. |
OPENCODE_DISABLE_DEFAULT_PLUGINS | Disable bundled plugins. |
OPENCODE_DISABLE_MODELS_FETCH | Skip remote models.dev fetch. |
OPENCODE_ENABLE_EXA | Enable Exa web search integration. |
OPENCODE_ENABLE_EXPERIMENTAL_MODELS | Show experimental models in models. |
OPENCODE_MODELS_URL | Custom models.dev-compatible URL. |
Server / auth
| Variable | Purpose |
|---|---|
OPENCODE_SERVER_PASSWORD | Enable HTTP basic auth on opencode serve. |
OPENCODE_SERVER_USERNAME | Auth username (default opencode). |
OPENCODE_GIT_BASH_PATH | Custom Git Bash path on Windows. |
Claude/Gemini interop
| Variable | Purpose |
|---|---|
OPENCODE_DISABLE_CLAUDE_CODE | Skip .claude directory entirely. |
OPENCODE_DISABLE_CLAUDE_CODE_PROMPT | Skip ~/.claude/CLAUDE.md. |
OPENCODE_DISABLE_CLAUDE_CODE_SKILLS | Skip .claude/skills loading. |
Experimental
Master flag OPENCODE_EXPERIMENTAL=1 enables every experimental feature. Otherwise, opt in individually:
| Variable | Purpose |
|---|---|
OPENCODE_EXPERIMENTAL_PLAN_MODE | Plan mode (Tab toggle in input). |
OPENCODE_EXPERIMENTAL_FILEWATCHER | File-watcher integration. |
OPENCODE_EXPERIMENTAL_DISABLE_FILEWATCHER | Disable file-watcher. |
OPENCODE_EXPERIMENTAL_LSP_TOOL | Experimental LSP tool integration. |
OPENCODE_EXPERIMENTAL_LSP_TY | Python TY language server. |
OPENCODE_EXPERIMENTAL_OXFMT | Use the oxfmt formatter. |
OPENCODE_EXPERIMENTAL_MARKDOWN | Markdown processing improvements. |
OPENCODE_EXPERIMENTAL_ICON_DISCOVERY | Icon detection in TUI. |
OPENCODE_EXPERIMENTAL_OUTPUT_TOKEN_MAX | LLM response token cap. |
OPENCODE_EXPERIMENTAL_BASH_DEFAULT_TIMEOUT_MS | Default bash command timeout. |
OPENCODE_EXPERIMENTAL_DISABLE_COPY_ON_SELECT | Don’t auto-copy on selection. |
OPENCODE_EXPERIMENTAL_EXA | Exa search experimental features. |
Themes
Themes change the TUI’s colour palette. Cycle with <leader>t or set the default in opencode.json:
{ "theme": "system" } // follow OS dark/light
{ "theme": "dark" }
{ "theme": "light" }
{ "theme": "tokyo-night" }
{ "theme": "catppuccin" }
Custom themes drop into ~/.config/opencode/themes/<name>.json.
Oh-My-OpenAgent extensions
Oh-My-OpenAgent (omoa) is a community plugin manager that ships pre-built agents, themes, and skill bundles. Most-used commands once installed via the Oh-My-OpenAgent install guide:
omoa list # available bundles
omoa install <name> # add an agent or theme bundle
omoa update # pull updates
omoa search <term> # find a bundle
Bundles drop their files under ~/.config/opencode/agents/ and ~/.config/opencode/skills/. OpenCode picks them up next launch.
Upgrade and uninstall
# Upgrade to latest using the same install method
opencode upgrade
# Pin a specific version
opencode upgrade 1.14.33
# Force install method
opencode upgrade --method npm
opencode upgrade --method bun
opencode upgrade --method curl
opencode upgrade --method brew
opencode upgrade --method choco
opencode upgrade --method scoop
# Uninstall (with options)
opencode uninstall # full clean
opencode uninstall --keep-config # preserve ~/.config/opencode
opencode uninstall --keep-data # preserve ~/.local/share/opencode
opencode uninstall --dry-run # preview removal
opencode uninstall --force # skip confirmations
Common errors and fixes
Error: “CPU lacks AVX support”
The bundled Bun runtime requires AVX2. Most cloud VMs and modern laptops have it. If your hypervisor passes a generic CPU type, the runtime crashes on launch. Fix on Proxmox: stop the VM, set cpu: host, restart. On QEMU directly: pass -cpu host. Check support inside the guest with grep -m1 -oE 'avx[0-9a-z]*' /proc/cpuinfo.
Error: “Performing one time database migration”
Informational on first launch. The CLI builds a SQLite store under ~/.local/share/opencode/. Can take 10 to 30 seconds, longer on slow disks. Wait for sqlite-migration:done before assuming a hang.
Error: “no provider configured”
Run opencode auth login and finish the flow, or export the right env var (ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY) before launching. opencode auth list confirms what is currently configured.
Issue: attach mode rejected with 401
The remote server requires basic auth and you did not pass the password. Either set OPENCODE_SERVER_PASSWORD in your env or pass -p <password>. The server prints the expected password on first start if you launched with opencode serve and did not set one explicitly.
Issue: Bash commands time out unexpectedly
Long-running commands (test suites, builds) hit the default bash timeout. Raise it with OPENCODE_EXPERIMENTAL_BASH_DEFAULT_TIMEOUT_MS=300000 in the environment, or per-command via the timeout field in custom command frontmatter.
OpenCode vs Claude Code vs Aider vs Codex CLI
- OpenCode: open-source, server-mode native, multi-provider, web UI, ACP for IDE integration, sophisticated permissions and multi-agent workflows. Best when you want a fleet-of-agents setup or self-hosted access from multiple machines.
- Claude Code: deepest agent ecosystem, hooks, skills, plugins, polished UX. See the Claude Code cheat sheet.
- Aider: git-native, repo-map-aware, broadest provider routing. See the Aider cheat sheet.
- Codex CLI: tight focus, OpenAI-only, sharpest at short refactors. See the Codex CLI cheat sheet.
- Gemini CLI: free OAuth tier, 1M-token context. See the Gemini CLI cheat sheet.
- For a deeper head-to-head, see OpenCode vs Claude Code vs Cursor.
Frequently asked questions
Where is the OpenCode config file?
User-level config is at ~/.config/opencode/opencode.json. Project-level overrides go in ./.opencode.json at the repo root. Project values override user values. Inspect the merged result with opencode debug config. Override the path entirely with OPENCODE_CONFIG=/path/to/file.
Does OpenCode have a free tier?
Yes. The OpenCode team hosts five free models under the opencode/ provider (opencode/big-pickle, opencode/gpt-5-nano, plus three preview slots). Run opencode models opencode to see the current set. Quota is throttled per IP.
How do I add an MCP server in OpenCode?
Two paths. The CLI: opencode mcp add walks you through the interactive flow. The config file: edit opencode.json and add an entry under the mcp key with type, command, and optional environment. Then run opencode mcp list to verify.
Can OpenCode work with Ollama?
Yes. Add Ollama as an OpenAI-compatible provider in opencode.json by pointing the OpenAI provider at http://localhost:11434/v1. Then launch with -m ollama/llama3.3. Pair with the Ollama commands cheat sheet for model management.
How do I share an OpenCode session?
Launch with --share, or invoke /share inside a running session. OpenCode prints a public URL pointing at the session transcript on the OpenCode share service. Use opencode export <sessionID> --sanitize first to redact sensitive content before sharing.
What is plan mode?
Plan mode is a read-only state where the agent reads, reasons, and proposes a plan but cannot write or run shell commands. Toggle it from the input field with Tab. Useful for code reviews, audits, and “what would happen if” exploration before letting the agent touch anything.
How do I create a custom slash command?
Drop a markdown file under .opencode/commands/<name>.md (project-scoped) or ~/.config/opencode/commands/<name>.md (user-scoped). The frontmatter sets description, optional agent, optional model, optional subtask. The body is the prompt template, with placeholders like $ARGUMENTS, $1, !`shell`, and @file.
Keep this open while you work
OpenCode releases roughly every two weeks, and the surface keeps growing. When a new version ships check the freshness block at the top of this page and re-read the section that changed. Pair this with the OpenCode setup guide for first-time install, the Oh-My-OpenAgent install guide if you use the community plugin manager, and the OpenCode vs Claude Code vs Cursor comparison when picking your daily driver.