AI

OpenCode CLI Cheat Sheet – Commands and Workflows

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.

Original content from computingforgeeks.com - post 167358

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

CommandPurpose
opencode [project]Launch the TUI in the given directory (default).
opencode run [message..]One-shot headless invocation.
opencode serveHeadless HTTP API server other clients can attach to.
opencode webHeadless server plus the OpenCode web UI.
opencode attach <url>Attach a TUI to a running server.
opencode acpAgent Client Protocol over stdin/stdout (IDE bridge).
opencode auth (alias providers)Manage providers and credentials.
opencode models [provider]List models, optionally filtered.
opencode mcpManage MCP servers (add, list, auth, debug, logout).
opencode agentManage agents (list, create).
opencode sessionList or delete sessions.
opencode export [sessionID]Export session data as JSON.
opencode import <file>Import session from JSON or share URL.
opencode statsToken usage and cost statistics.
opencode githubInstall 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 debugDebugging utilities (config, paths, agent, LSP, ripgrep, snapshot, scrap).
opencode dbDatabase tools.
opencode upgrade [target]Upgrade OpenCode (npm, pnpm, bun, brew, choco, scoop, curl).
opencode uninstallUninstall OpenCode and remove related files.
opencode completionPrint 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.json plus per-user agents, commands, themes.
  • data: SQLite stores for sessions, messages, projects, plus auth.json with 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

FlagPurpose
-m, --modelChoose provider/model.
--variantProvider-specific reasoning effort (high, max, minimal).
--thinkingShow thinking blocks in the TUI.
-c, --continueContinue the last session.
-s, --sessionContinue a specific session by ID.
--forkFork a session when continuing (preserves the original).
--promptSeed the agent with a prompt at launch.
--agentLaunch as a named agent (build, compaction, explore, custom).
--shareMake the session shareable via URL.
-f, --fileAttach files to the initial prompt (repeatable).
--titleTitle for the new session.
--attach URLAttach to a remote OpenCode server.
-p, --passwordServer basic-auth password.
--dirDirectory to run in (or path on the remote server).
--portPort for the local server.
--hostnameHostname to bind on (default 127.0.0.1).
--mdnsEnable mDNS service discovery (sets hostname to 0.0.0.0).
--mdns-domainCustom mDNS domain (default opencode.local).
--corsAdditional CORS-allowed domains.
--formatdefault (formatted) or json (raw nd-JSON events).
--dangerously-skip-permissionsAuto-approve every permission. Disposable VMs only.
--pureRun without external plugins (debugging).
--print-logsEcho logs to stderr.
--log-levelDEBUG, INFO, WARN, ERROR.
-v, --versionPrint 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

ActionShortcut
QuitCtrl+C, Ctrl+D, or <leader>q
Command paletteCtrl+P
Toggle theme<leader>t
Toggle sidebar<leader>b
Show status<leader>s
Toggle tips<leader>h
External editor<leader>e
Suspend to backgroundCtrl+Z
Interrupt running tool callEscape

Sessions

ActionShortcut
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

ActionShortcut
Scroll to topCtrl+G or Home
Scroll to bottomCtrl+Alt+G or End
Page up / downPageUp / PageDown
Half-page up / downCtrl+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

ActionShortcut
Open model picker<leader>m
Cycle to next recent modelF2
Cycle to previous recent modelShift+F2
Open agent picker<leader>a
Tab through agent optionsTab / Shift+Tab
Toggle plan modeTab in the input

Input field

ActionShortcut
SubmitEnter
New line in inputShift+Enter, Ctrl+Enter, or Alt+Enter
Move cursor by charCtrl+B / Ctrl+F (or arrows)
Jump to start / end of lineCtrl+A / Ctrl+E
Extend selectionShift+Arrows, Ctrl+Shift+A, Ctrl+Shift+E
Clear inputCtrl+C
PasteCtrl+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 commandWhat it does
/initGenerate AGENTS.md by analysing the current repo. Run once per project.
/helpShow available commands and a quick keybind reference.
/shareGenerate a public URL for the current session transcript.
/undoRevert the agent’s last action (file edits, commits).
/redoRe-apply the last undone action.
/connectRe-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

KeyRequiredPurpose
descriptionrecommendedOne-line description shown in the slash autocomplete.
agentoptionalForce the command to run as a specific agent (default: current).
modeloptionalOverride the model for this command only.
subtaskoptional (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/file or @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.

ConceptWhat it isWhere to define
ModeA behavioural shape (build, plan, edit-only, read-only) that adjusts permissions and prompts.opencode.json under "mode" key.
AgentA 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.
SkillA 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 linear CLI 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

SubcommandPurpose
opencode debug pathsPrint all data, config, cache, state directories.
opencode debug configPrint the resolved config (after merging user + project).
opencode debug startupPrint startup timing in ms.
opencode debug skillList discovered skills.
opencode debug agent <name>Show a named agent’s full configuration.
opencode debug lspInspect Language Server Protocol bridges.
opencode debug rgVerify the bundled ripgrep binary works.
opencode debug fileFile-system bridge sanity check.
opencode debug snapshotInspect or replay session snapshots.
opencode debug scrapList every project OpenCode has run in.
opencode debug waitWait 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:

  1. ./.opencode.json at the project root.
  2. ~/.config/opencode/opencode.json for 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

VariablePurpose
OPENCODE_CONFIGOverride path to opencode.json.
OPENCODE_CONFIG_DIROverride the entire config directory.
OPENCODE_CONFIG_CONTENTInline JSON config (for CI / containers).
OPENCODE_TUI_CONFIGOverride path to TUI config.
OPENCODE_PERMISSIONInline JSON permissions array.
OPENCODE_AUTO_SHAREAuto-share every session (boolean).
OPENCODE_DISABLE_AUTOUPDATESkip update checks.
OPENCODE_DISABLE_AUTOCOMPACTDisable automatic context compaction.
OPENCODE_DISABLE_MOUSEDisable TUI mouse input.
OPENCODE_DISABLE_LSP_DOWNLOADSkip auto-download of language servers.
OPENCODE_DISABLE_DEFAULT_PLUGINSDisable bundled plugins.
OPENCODE_DISABLE_MODELS_FETCHSkip remote models.dev fetch.
OPENCODE_ENABLE_EXAEnable Exa web search integration.
OPENCODE_ENABLE_EXPERIMENTAL_MODELSShow experimental models in models.
OPENCODE_MODELS_URLCustom models.dev-compatible URL.

Server / auth

VariablePurpose
OPENCODE_SERVER_PASSWORDEnable HTTP basic auth on opencode serve.
OPENCODE_SERVER_USERNAMEAuth username (default opencode).
OPENCODE_GIT_BASH_PATHCustom Git Bash path on Windows.

Claude/Gemini interop

VariablePurpose
OPENCODE_DISABLE_CLAUDE_CODESkip .claude directory entirely.
OPENCODE_DISABLE_CLAUDE_CODE_PROMPTSkip ~/.claude/CLAUDE.md.
OPENCODE_DISABLE_CLAUDE_CODE_SKILLSSkip .claude/skills loading.

Experimental

Master flag OPENCODE_EXPERIMENTAL=1 enables every experimental feature. Otherwise, opt in individually:

VariablePurpose
OPENCODE_EXPERIMENTAL_PLAN_MODEPlan mode (Tab toggle in input).
OPENCODE_EXPERIMENTAL_FILEWATCHERFile-watcher integration.
OPENCODE_EXPERIMENTAL_DISABLE_FILEWATCHERDisable file-watcher.
OPENCODE_EXPERIMENTAL_LSP_TOOLExperimental LSP tool integration.
OPENCODE_EXPERIMENTAL_LSP_TYPython TY language server.
OPENCODE_EXPERIMENTAL_OXFMTUse the oxfmt formatter.
OPENCODE_EXPERIMENTAL_MARKDOWNMarkdown processing improvements.
OPENCODE_EXPERIMENTAL_ICON_DISCOVERYIcon detection in TUI.
OPENCODE_EXPERIMENTAL_OUTPUT_TOKEN_MAXLLM response token cap.
OPENCODE_EXPERIMENTAL_BASH_DEFAULT_TIMEOUT_MSDefault bash command timeout.
OPENCODE_EXPERIMENTAL_DISABLE_COPY_ON_SELECTDon’t auto-copy on selection.
OPENCODE_EXPERIMENTAL_EXAExa 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.

Related Articles

Automation Set Up Kind Kubernetes with Nginx Ingress Using Terraform Ansible Semaphore – Manage Ansible Tasks from A Web UI Automation Setup Puppet Master and Agent on Ubuntu 24.04 Automation k0s vs k3s vs microk8s Kubernetes Distributions Comparison

Leave a Comment

Press ESC to close