Jesse A. Green / notebook

opencode User Guide

Generated June 2026 from anomalyco/opencode at 3cf1cef

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

opencode is an AI coding agent that runs in your terminal. You point it at a project, type what you want in plain language, and it reads your code, edits files, runs commands, and works alongside you — all from a fast, keyboard-driven terminal interface (TUI). It is provider-agnostic: you bring your own model (Anthropic, OpenAI, Google, GitHub Copilot, OpenRouter, local models, and more) or use the hosted opencode Zen gateway.

This guide covers everything you need to install opencode, drive it from the terminal, connect a model, work across sessions, extend it with agents, custom commands, MCP servers, and plugins, automate it in CI with the GitHub agent, and troubleshoot the things that commonly go wrong.

Note

opencode is the CLI/TUI documented here. It is part of a larger ecosystem that also includes a desktop app, an editor extension, an SDK, and a hosted console. Those companion products are described in the Admin Guide. This guide is for the person sitting at a terminal getting work done.


1. Quick Start

Get from zero to your first AI-assisted change in about two minutes.

macOS / Linux (curl)

curl -fsSL https://opencode.ai/install | bash

npm

npm install -g opencode-ai

Homebrew (macOS)

brew install opencode

Windows (Scoop)

scoop install opencode

Once installed, open a terminal in a project you want to work on and start opencode:

cd ~/code/my-project
opencode

The first time you run it, you will need to connect a model provider. Run the login flow and pick a provider:

opencode auth login
┌  Add credential
│
◆  Select provider
│  ● opencode          recommended
│  ○ Anthropic
│  ○ OpenAI            ChatGPT Plus/Pro or API key
│  ○ Google
│  ○ OpenRouter
└

Pick a provider, follow the prompts (OAuth in your browser, or paste an API key), and you are ready. Back in the TUI, type a request and press Enter:

> Add a --verbose flag to the CLI that prints the resolved config path

opencode reads the relevant files, proposes edits, asks permission before running anything risky, and shows you a live stream of what it is doing.

Tip

Not sure what model you have access to? Run opencode models to list every model from every provider you have authenticated. Switch models inside the TUI any time with the <leader> m keybind (the leader key is Ctrl+x by default).


2. Installation

2.1 Requirements

Requirement Detail
Operating system macOS, Linux, or Windows
Terminal A modern terminal emulator with 256-color and mouse support
Model access An account or API key with at least one supported provider (or opencode Zen)
Git (recommended) Project-scoped config, agents, and the GitHub agent assume a git repository
sqlite3 (optional) Only needed if you want to open an interactive DB shell with opencode db

opencode ships as a self-contained binary built on the Bun runtime — you do not need to install Node.js or Bun separately for the curl/Homebrew/Scoop installs. The npm/pnpm/bun/yarn packages install the opencode-ai package globally.

2.2 Installation methods

opencode tracks how it was installed so that opencode upgrade and opencode uninstall use the matching mechanism. Supported methods:

curl (script)

curl -fsSL https://opencode.ai/install | bash

Installs a standalone binary into ~/.opencode/bin and adds it to your shell PATH.

npm / pnpm / bun / yarn

npm install -g opencode-ai
# or
pnpm add -g opencode-ai
# or
bun add -g opencode-ai
# or
yarn global add opencode-ai

Homebrew

brew install opencode

Chocolatey / Scoop (Windows)

choco install opencode
# or
scoop install opencode

2.3 Verify the install

opencode --version
1.16.0
opencode --help

The help banner lists every available command. If opencode is not found after a curl install, restart your shell or ensure ~/.opencode/bin is on your PATH.

Important

On native Windows, opencode falls back to Git Bash utilities (such as less) for some features. If you have Git for Windows installed, opencode discovers it automatically. You can point opencode at a specific Git Bash with the OPENCODE_GIT_BASH_PATH environment variable.

2.4 Upgrading

opencode upgrade
┌  Upgrade
│  Using method: curl
│  From 1.16.0 → 1.16.1
◇  Upgrade complete
└  Done

Upgrade to a specific version, or force a particular install method:

opencode upgrade 1.16.1
opencode upgrade --method npm

If the detected method is unknown (for example, opencode lives somewhere managed by a package manager opencode cannot detect), it asks before proceeding.

Note

opencode checks for updates automatically. To turn this off, set the environment variable OPENCODE_DISABLE_AUTOUPDATE=true. To always be notified about available updates, set OPENCODE_ALWAYS_NOTIFY_UPDATE=true.

2.5 Uninstalling

opencode uninstall

This removes opencode's data, cache, config, and state directories, cleans the PATH entry from your shell config (for curl installs), and runs the matching package-manager uninstall when applicable. Preview without deleting anything:

opencode uninstall --dry-run

Keep your config and/or session data while removing the binary:

opencode uninstall --keep-config --keep-data
Flag Alias Effect
--keep-config -c Preserve configuration files
--keep-data -d Preserve session data and snapshots
--dry-run Show what would be removed without removing
--force -f Skip the confirmation prompt

3. Connecting a Model Provider

opencode never ships its own model. Before it can do anything useful you must connect at least one provider. Credentials are stored locally in auth.json inside opencode's data directory.

3.1 Logging in

opencode auth login

auth is an alias for the providers command, so opencode providers login is identical. The interactive flow lets you pick a provider and then either run an OAuth flow (browser-based) or paste an API key, depending on what the provider supports.

Skip the interactive selection by passing the provider and/or method directly:

opencode auth login --provider anthropic
opencode auth login --provider openai --method "API Key"

Tip

Several providers print extra setup hints during login:

  • opencode (Zen): create a key at https://opencode.ai/auth
  • OpenAI: works with a ChatGPT Plus/Pro subscription or an API key
  • Vercel AI Gateway: create a token at https://vercel.link/ai-gateway-token
  • Amazon Bedrock: uses a bearer token or the standard AWS credential chain (AWS_PROFILE, AWS_REGION, IAM roles, EKS IRSA)
  • Cloudflare AI Gateway: configure CLOUDFLARE_GATEWAY_ID, CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_API_TOKEN

3.2 Provider login methods

Provider Typical auth Notes
opencode API key The hosted Zen gateway — one key, many models. Recommended for getting started.
anthropic OAuth or API key Claude models
openai OAuth (ChatGPT) or API key GPT models
google API key Gemini models
github-copilot OAuth Use your Copilot subscription
openrouter API key Aggregator across many models
vercel API key Vercel AI Gateway
amazon-bedrock Bearer token / AWS chain See note above
snowflake-cortex Account + PAT Prompts for account identifier and a programmatic access token
Any other API key Choose Other, enter a provider id, then configure it in opencode.json

You can also authenticate against a self-hosted auth provider that exposes a /.well-known/opencode endpoint:

opencode auth login https://auth.example.com

opencode reads the well-known document, runs its auth.command, and stores the resulting token under the provider key.

3.3 Listing and removing credentials

opencode auth list
┌  Credentials ~/.local/share/opencode/auth.json
│  Anthropic    oauth
│  OpenAI       api
└  2 credentials

┌  Environment
│  Anthropic    ANTHROPIC_API_KEY
└  1 environment variable

The command shows both stored credentials and any provider environment variables it detects active in your shell. Remove a stored credential interactively:

opencode auth logout

Note

Provider API keys set via environment variables (for example ANTHROPIC_API_KEY, OPENAI_API_KEY) are picked up automatically — you do not have to run auth login if the key is already in your environment.

3.4 Browsing available models

opencode models
opencode/claude-sonnet-4-6
opencode/gpt-5.5
anthropic/claude-opus-4-8
openai/gpt-5.5
google/gemini-3-pro

Filter by provider, see full metadata (including costs), or refresh the catalog from models.dev:

opencode models anthropic
opencode models --verbose
opencode models --refresh

The model catalog is sourced from models.dev. opencode-prefixed providers are listed first.


4. The Terminal Interface (TUI)

Running opencode with no arguments opens the interactive TUI in your current directory. This is the primary way to use opencode.

4.1 Anatomy of a session

The TUI shows your conversation with the agent in the main pane and an input prompt at the bottom. As the agent works, it streams its actions inline: each tool it uses (reading a file, editing, running a shell command, searching) appears as a labeled event, and the agent's prose responses render as Markdown.

You type a request, press Enter, and the agent goes to work. You can keep typing follow-ups, interrupt it, switch models or agents, review diffs, and manage sessions — all without leaving the keyboard.

4.2 The leader key

Many shortcuts are triggered through a leader key — a prefix you press, release, then follow with another key. The default leader is Ctrl+x. For example, <leader> m means: press Ctrl+x, release, then press m to open the model list.

There is a short timeout (2 seconds by default) to complete a leader sequence. You can change the leader key and timeout in your TUI config (see §11).

Tip

Press the which-key panel shortcut (Ctrl+Alt+k) to see available leader bindings as you type them. opencode shows you what each pending key does.

4.3 Essential keybindings

These are the default bindings you will use most. All are configurable.

Session & conversation

Action Default key Description
New session <leader> n Start a fresh conversation
List sessions <leader> l Browse and switch sessions
Session timeline <leader> g View the session's history timeline
Rename session Ctrl+r Rename the current session
Compact session <leader> c Summarize/compact the conversation to free context
Interrupt Esc Stop the agent mid-response
Export session <leader> x Open the session transcript in your editor
Share session (unbound by default) Create a shareable link

Models, agents, and variants

Action Default key Description
List models <leader> m Pick a model
Cycle recent models F2 / Shift+F2 Next / previous recently used model
List agents <leader> a Pick a primary agent
Cycle agents Tab / Shift+Tab Next / previous agent
Cycle variants Ctrl+t Cycle model reasoning-effort variants

Navigation & viewing

Action Default key Description
Command palette Ctrl+p List and run available commands
Toggle sidebar <leader> b Show/hide the sidebar
List themes <leader> t Switch color theme
Open external editor <leader> e Edit your prompt in $EDITOR
Scroll messages PageUp / PageDown Page through the transcript
First / last message Ctrl+g / Ctrl+Alt+g Jump to start / end
Copy message <leader> y Copy the focused message
Undo / redo message <leader> u / <leader> r Revert or re-apply the agent's last change

Application

Action Default key Description
Exit Ctrl+c, Ctrl+d, or <leader> q Quit opencode
Suspend (POSIX) Ctrl+z Suspend to the shell (disabled on native Windows)
Toggle help (unbound by default) Open the help dialog

Note

The full set of bindings — including the dozens of text-editing shortcuts for the prompt input (word motions, selection, undo/redo, line operations) — is listed in the keybinding reference at the end of this guide.

4.4 Mentioning files and running shell snippets in prompts

Inside the prompt you can reference files with @:

> Refactor @src/auth.ts to use the new SessionService and update @src/cli/index.ts

Typing @ triggers a file autocomplete. The mentioned files are attached as context for the agent.

4.5 Attaching to a running server

If you have a headless opencode server running (see §10), you can drive it interactively from another terminal. Inside the TUI this is the "attach" workflow; from the command line, opencode run --interactive --attach connects an interactive session to a remote server.


5. Running opencode Non-Interactively (opencode run)

opencode run sends a single prompt, streams the result to stdout, and exits when the session goes idle. This is the workhorse for scripting, automation, and one-off questions.

5.1 Basic usage

opencode run "Explain what src/server/server.ts does"

The agent processes the request and streams its work and final answer to your terminal. Pipe input in from stdin:

git diff | opencode run "Review this diff and flag any bugs"

Pipe output to a file or another tool:

opencode run "List every public API endpoint and its HTTP method" > endpoints.txt

5.2 run options

Option Alias Description
--continue -c Continue the last session
--session <id> -s Continue a specific session by id
--fork Fork the session before continuing (requires --continue or --session)
--share Share the session and print a link
--model <provider/model> -m Choose the model, e.g. anthropic/claude-opus-4-8
--agent <name> Use a specific primary agent
--variant <name> Model reasoning-effort variant (e.g. high, max, minimal)
--format <default|json> Human-formatted output, or raw JSON events for scripting
--file <path> -f Attach one or more files to the message (repeatable)
--title <text> Set the session title (truncated prompt if no value)
--command <name> Run a slash-command; use the message for its arguments
--thinking Show the model's thinking/reasoning blocks
--interactive -i Run in the direct interactive split-footer mode
--attach <url> Attach to a running server, e.g. http://localhost:4096
--dir <path> Directory to run in (or remote path when attaching)
--port <n> Port for the local server (random if omitted)
--username <name> -u Basic-auth username when attaching (default opencode)
--password <pw> -p Basic-auth password when attaching
--dangerously-skip-permissions Auto-approve any permission not explicitly denied — dangerous

5.3 Continuing and forking sessions

Pick up where you left off:

opencode run --continue "Now add tests for that change"

Continue a specific session and branch it so the original is untouched:

opencode run --session ses_abc123 --fork "Try a different approach using streams"

5.4 Choosing a model and effort

opencode run -m anthropic/claude-opus-4-8 --variant high "Design the migration plan"

The --variant controls provider-specific reasoning effort. Common values are minimal, high, and max, but the exact set depends on the model.

5.5 Machine-readable output

opencode run --format json "Summarize the README" > out.jsonl

In JSON mode, opencode emits one JSON object per line for each event (text, tool_use, step_start, step_finish, error, …), each stamped with a timestamp and session id. This is the format to parse in scripts and pipelines.

Warning

In non-interactive run, the agent cannot ask you questions or pause for planning — those permissions are denied automatically so the run never blocks waiting for input. By default, any other permission the agent requests (for example, an undeclared shell command) is auto-rejected and logged. Pass --dangerously-skip-permissions to auto-approve instead, but only in trusted, sandboxed environments.

5.6 Running a slash-command from the CLI

opencode run --command review "src/auth.ts"

This invokes the review command (a custom command you have defined — see §7) and passes src/auth.ts as its arguments.


6. Agents

An agent is a named persona with its own system prompt, allowed permissions, and (optionally) a pinned model. opencode ships with built-in agents and lets you define your own. Agents come in three modes:

Mode Meaning
primary Acts as a main agent you talk to directly
subagent Can be invoked by another agent to handle a delegated task
all Can act in both roles

6.1 Listing agents

opencode agent list
build (primary)
  {}
plan (all)
  { "edit": "deny", "bash": "deny" }

Each agent prints its name, mode, and its permission map. Built-in (native) agents are listed first.

6.2 Creating an agent

opencode agent create

The interactive flow asks where to save it (global or current project), what the agent should do, which permissions to allow, and which mode to use. opencode uses your model to generate the agent's identifier and system prompt for you.

Create one fully non-interactively (useful in scripts):

opencode agent create \
  --description "Review code for security issues only; never edit files" \
  --mode subagent \
  --permissions "read,grep,glob" \
  --model anthropic/claude-opus-4-8

The --permissions flag (alias --tools) takes a comma-separated subset of:

bash, read, edit, glob, grep, webfetch, task, todowrite, websearch, lsp, skill

Anything you omit is set to deny. Permissions are keyed by capability, not raw tool name — for example, edit gates the write/edit/patch tools together.

6.3 How agents are stored

A created agent is a Markdown file with YAML frontmatter:

---
description: When to use this agent (shown to other agents for delegation)
mode: subagent
permission:
  edit: deny
  bash: deny
---

You are a security reviewer. You read code and report vulnerabilities...

opencode loads agents from agent/ or agents/ directories — globally in your config directory, or per-project under .opencode/agents/. The filename (minus .md) becomes the agent name.

6.4 Using an agent

In the TUI, cycle agents with Tab / Shift+Tab or pick one with <leader> a. From the CLI:

opencode run --agent plan "Outline the steps to add OAuth without writing code"

Tip

A common pattern is a read-only plan agent (edit and bash denied) that you use to design a change, then switch to a build agent with full permissions to execute it.


7. Custom Commands

Commands are reusable prompt templates you trigger by name. They live as Markdown files in command/ or commands/ directories (globally or under .opencode/commands/), where the filename becomes the command name.

A command file is a Markdown template — its body is the prompt, and its frontmatter can pin a model, agent, and other options. Templates support:

  • File references with @path — the file's contents are inlined into the prompt.
  • Shell substitution with !`command` — the command runs and its output is inlined.

Example commands/review.md:

---
description: Security-focused code review
---

Review the following file for security issues. Be specific and cite line numbers.

@$ARGUMENTS

Current branch: !`git branch --show-current`

Run it from the TUI's command palette (Ctrl+p) or from the CLI:

opencode run --command review src/auth.ts

Note

Commands, agents, and plugins are all auto-discovered from your project's .opencode/ directory and merged with your global config. This means a repository can ship its own opencode workflow that every contributor gets automatically.


8. Connecting MCP Servers

opencode is a Model Context Protocol client. MCP servers give the agent extra tools — filesystem access, web APIs, databases, internal services, and so on. Servers can be local (a command opencode runs) or remote (an HTTP URL, optionally OAuth-protected).

8.1 Adding a server

opencode mcp add

The wizard asks for a name, whether the server is local or remote, the command or URL, and (for remote servers) whether it needs OAuth. Your answers are written into opencode.json (project or global, your choice), preserving any comments in the file.

A local server entry looks like this:

{
  "mcp": {
    "filesystem": {
      "type": "local",
      "command": ["opencode", "x", "@modelcontextprotocol/server-filesystem"]
    }
  }
}

A remote server with OAuth:

{
  "mcp": {
    "my-server": {
      "type": "remote",
      "url": "https://example.com/mcp",
      "oauth": {
        "clientId": "your-client-id",
        "clientSecret": "your-client-secret"
      }
    }
  }
}

Note

Remote MCP servers support OAuth by default. You only need the oauth block if the server requires a pre-registered client; otherwise opencode attempts dynamic client registration automatically.

8.2 Listing and checking servers

opencode mcp list
┌  MCP Servers
│  ✓ filesystem  connected
│    opencode x @modelcontextprotocol/server-filesystem
│  ⚠ my-server  needs authentication
│    https://example.com/mcp
└  2 server(s)

Status icons: ✓ connected, ○ disabled / not initialized, ⚠ needs authentication, ✗ failed or needs client registration.

8.3 Authenticating an OAuth server

opencode mcp auth my-server

opencode opens your browser to complete the OAuth flow (and prints the URL if it cannot open a browser automatically). List OAuth-capable servers and their status:

opencode mcp auth list

Remove stored credentials for a server:

opencode mcp logout my-server

8.4 Debugging a connection

opencode mcp debug my-server

This probes the server over HTTP, reports the status code and any WWW-Authenticate header, inspects stored tokens (and whether they are expired), and walks through the OAuth discovery flow without completing authorization — invaluable when a server "needs authentication" but you are not sure why.


9. Plugins

Plugins extend opencode itself — adding hooks, new providers, themes, or behavior — and are distributed as npm packages or local files.

9.1 Installing a plugin

opencode plugin <module>

plug is an alias. Install into the global config or force-replace an existing version:

opencode plugin my-org/opencode-plugin-foo --global
opencode plugin my-org/opencode-plugin-foo --force

opencode installs the npm package, reads its manifest to detect what it provides (a server plugin, a TUI plugin, or TUI themes), and updates the appropriate config file (opencode.json for server plugins, tui.json for TUI plugins/themes).

Flag Alias Description
--global -g Install into the global config instead of the project
--force -f Replace an existing plugin version

9.2 Auto-discovered local plugins

Drop a .ts or .js file into your project's .opencode/plugin/ (or plugins/) directory and opencode loads it automatically — no install step. This is the fastest way to prototype a plugin or ship a project-specific one.

Tip

Run opencode without any external plugins for a clean, reproducible session with the global --pure flag (or set OPENCODE_PURE=1):

opencode --pure

10. Running opencode as a Server

opencode can run headless and expose an HTTP API. This powers editor extensions, the desktop app, remote/attach workflows, and the Agent Client Protocol (ACP).

10.1 Headless server

opencode serve
opencode server listening on http://127.0.0.1:4096

Control the bind address and port through the network options:

opencode serve --port 4096 --hostname 0.0.0.0

Caution

When OPENCODE_SERVER_PASSWORD is not set, the server is unsecured — anyone who can reach the port can drive your agent and access your files. opencode prints a warning in this case. Set a password (and optionally a username via OPENCODE_SERVER_USERNAME) before binding to anything other than localhost.

10.2 Web interface

opencode web

This starts the server and opens a browser-based interface, printing local and network URLs. When bound to 0.0.0.0, it lists each non-internal network address so you can reach it from another device on your LAN.

10.3 Attaching the CLI to a server

# Non-interactive against a remote server
opencode run --attach http://localhost:4096 "What changed in the last session?"

# Interactive against a remote server
opencode run --interactive --attach http://localhost:4096

Provide credentials with --username / --password (or the OPENCODE_SERVER_USERNAME / OPENCODE_SERVER_PASSWORD environment variables), and target a working directory on the remote with --dir.

10.4 ACP (Agent Client Protocol)

opencode acp

Starts an ACP server over stdin/stdout so ACP-compatible clients (for example, certain editors) can drive opencode as their agent backend. --cwd sets the working directory.


11. Customizing the TUI

TUI-specific settings — theme, keybindings, scroll behavior, notification sounds — live in a dedicated tui.json file (not opencode.json). opencode looks for tui.json in your global config directory and in project .opencode/ directories, merging them so the closest file wins.

Important

Earlier versions kept theme, keybinds, and tui keys inside opencode.json. opencode now migrates these into tui.json automatically the first time it runs, backing up the original. If you still have them in opencode.json, move them to tui.json.

11.1 Example tui.json

{
  "$schema": "https://opencode.ai/tui.json",
  "theme": "opencode",
  "leader_timeout": 2000,
  "scroll_speed": 1,
  "diff_style": "auto",
  "mouse": true,
  "keybinds": {
    "leader": "ctrl+x",
    "session_new": "<leader>n",
    "model_list": "<leader>m"
  },
  "attention": {
    "enabled": true,
    "notifications": true,
    "sound": true,
    "volume": 0.4
  }
}

11.2 TUI settings

Key Type Default Description
theme string opencode Color theme name
keybinds object — Per-action key overrides (see appendix)
leader_timeout integer (ms) 2000 Time allowed to complete a leader sequence
mouse boolean true Enable mouse capture
scroll_speed number — Scroll speed multiplier (≥ 0.001)
scroll_acceleration object — { "enabled": true } to accelerate scrolling
diff_style auto | stacked auto auto adapts to terminal width; stacked always shows a single column
prompt.max_height integer — Max height of the prompt textarea
prompt.max_width integer | auto — Home-screen prompt width cap
attention.notifications boolean true Desktop notifications when the agent needs you
attention.sound boolean true Play a sound on attention events
attention.volume number 0–1 0.4 Notification sound volume
attention.sound_pack string opencode.default Named sound pack
plugin array — TUI plugins to load

Note

Notification sounds fire on different events — done, error, permission, question, and subagent_done. You can map each to a custom sound file under attention.sounds.

11.3 Changing the theme

The fastest way is in the TUI: press <leader> t to browse and apply themes live. To pin one, set theme in tui.json.

11.4 Remapping keys

Override any binding in tui.json under keybinds. A binding value can be a single chord ("ctrl+r"), a comma-separated list ("ctrl+c,ctrl+d"), a list of chords, false/"none" to disable, or an object for advanced options. Unknown keybind names are ignored with a warning, so a typo will not break startup.

{
  "keybinds": {
    "session_compact": "ctrl+k",
    "terminal_suspend": "none"
  }
}

12. Configuration (opencode.json)

Beyond the TUI, opencode reads project and global configuration from opencode.json (or opencode.jsonc, which allows comments). This file controls models, providers, agents, commands, permissions, MCP servers, instructions, and more.

12.1 Where config lives and how it merges

opencode merges config from several sources, with later sources overriding earlier ones:

  1. Global config: opencode.json / opencode.jsonc in your config directory
  2. A custom file pointed to by OPENCODE_CONFIG
  3. Project files: opencode.json walking up from your working directory to the repo root
  4. .opencode/opencode.json directories discovered up the tree
  5. Inline config via OPENCODE_CONFIG_CONTENT
  6. System-managed config (for centrally managed installs)

Array fields like instructions are concatenated and de-duplicated across sources rather than replaced.

Tip

opencode seeds a new global opencode.json with the schema reference so your editor gives you autocomplete:

{ "$schema": "https://opencode.ai/config.json" }

12.2 Common config keys

Key Description
model Default model, as provider/model
provider Per-provider overrides (custom endpoints, names, options)
enabled_providers / disabled_providers Allow- or deny-list providers
agent Inline agent definitions (merged with files in agent/)
command Inline command definitions
mcp MCP server definitions (see §8)
permission Permission rules for tools (allow/deny/ask)
tools Enable/disable tools by name (shorthand that maps onto permission)
instructions Extra instruction files/snippets always given to the agent
plugin Plugin specs to load
share Sharing mode (auto to share every session automatically)
username Display name used in transcripts (defaults to your system username)
compaction Auto-compaction settings (auto, prune)

12.3 Permissions

Permissions decide what the agent may do without asking. They are expressed per capability with an action of allow, deny, or ask:

{
  "permission": {
    "edit": "ask",
    "bash": "ask",
    "webfetch": "allow"
  }
}

The tools shorthand maps booleans onto permissions (true → allow, false → deny); note that write, edit, and patch all collapse onto the single edit permission.

Caution

Setting edit or bash to allow lets the agent change files or run shell commands without confirmation. Use ask (the safe default behavior in interactive mode) unless you are in a throwaway sandbox.

12.4 Variable substitution

Config values support two substitutions:

  • {env:VAR_NAME} — replaced with an environment variable's value
  • {file:./path} — replaced with the contents of a file (relative to the config file, or ~/... for your home directory)
{
  "provider": {
    "my-gateway": {
      "options": { "apiKey": "{env:MY_GATEWAY_KEY}" }
    }
  },
  "instructions": ["{file:./CONVENTIONS.md}"]
}

12.5 Project instructions

opencode reads project instruction files (such as AGENTS.md) and your configured instructions so the agent always knows your conventions. Anything you would otherwise repeat in every prompt — coding standards, architecture notes, "always run the linter" — belongs here.


13. Sessions: History, Stats, Export & Import

Every conversation is a session, persisted locally so you can resume, inspect, share, and analyze it.

13.1 Listing sessions

opencode session list
Session ID            Title                          Updated
──────────────────────────────────────────────────────────────
ses_abc123…           Add --verbose flag             Today 14:22
ses_def456…           Refactor auth service          Yesterday

Limit the count or get JSON:

opencode session list --max-count 20
opencode session list --format json

Long lists are paged through your pager (less, or more on Windows) automatically.

13.2 Deleting a session

opencode session delete ses_abc123

13.3 Usage statistics

opencode stats
┌────────────────────────────────────────────────────────┐
│                       OVERVIEW                         │
├────────────────────────────────────────────────────────┤
│ Sessions                                            142 │
│ Messages                                          1,873 │
│ Days                                                 30 │
└────────────────────────────────────────────────────────┘

stats aggregates token usage and cost across your sessions, plus tool-usage and model-usage breakdowns. Scope and detail are controllable:

Option Description
--days <n> Limit to the last N days (0 = today only; omit for all time)
--tools <n> Show only the top N tools
--models [n] Show model statistics (optionally top N)
--project <id> Filter to a project (empty string = current project)
opencode stats --days 7 --models 5 --project ""

13.4 Exporting a session

opencode export > session.json

With no session id, opencode prompts you to pick one. Redact sensitive content (file text, paths, tool output) for safe sharing:

opencode export ses_abc123 --sanitize > session.redacted.json

The diagnostic data and transcript are written to stdout as JSON; status messages go to stderr, so piping to a file gives you clean JSON.

13.5 Importing a session

opencode import ./session.json
opencode import https://opencode.ai/share/abc123

Import accepts a local JSON file or a share URL, reconstructs the session locally, and stores it in your database.

13.6 Sharing sessions

Share a session to get a public link (handy for asking for help or showing your work):

  • In the TUI: bind and press the session_share action, or set "share": "auto" in config to share automatically.
  • From the CLI: add --share to opencode run.

A shared session prints a URL like https://opencode.ai/s/<id>.

Warning

Sharing publishes the session transcript — including file snippets and tool output — to a public URL. Review what is in a session before sharing, and use opencode export --sanitize if you need a redacted copy instead. Sharing can be disabled organization-wide via OPENCODE_DISABLE_SHARE.

13.7 Inspecting the local database

opencode stores sessions in a local SQLite database. Power users can query it directly:

opencode db path                              # print the DB file path
opencode db "SELECT id, title FROM session"   # run a query (TSV by default)
opencode db "SELECT * FROM session" --format json
opencode db                                    # open an interactive sqlite3 shell

Caution

The database is opencode's own storage. Reading is safe; writing or altering schema can corrupt your sessions. Treat opencode db as read-only unless you know exactly what you are doing.


14. The GitHub Agent

opencode can run inside GitHub Actions and respond to issues and pull requests — summarizing threads, reviewing code, and implementing changes that it pushes as commits or PRs.

14.1 Installing it

From inside a git repository:

opencode github install

The installer opens the GitHub App install page, waits for you to install opencode-agent on the repo, asks which provider and model to use, and writes a .github/workflows/opencode.yml workflow file. It then prints next steps.

14.2 What the workflow looks like

The generated workflow triggers on issue and PR-review comments and runs the agent when a comment mentions it:

name: opencode

on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]

jobs:
  opencode:
    if: |
      contains(github.event.comment.body, ' /oc') ||
      startsWith(github.event.comment.body, '/oc') ||
      contains(github.event.comment.body, ' /opencode') ||
      startsWith(github.event.comment.body, '/opencode')
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
      pull-requests: read
      issues: read
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
        with:
          persist-credentials: false
      - name: Run opencode
        uses: anomalyco/opencode/github@latest
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
        with:
          model: anthropic/claude-opus-4-8

After committing the workflow and adding the provider's API key as a repository or org secret, you trigger the agent.

14.3 Using it

In any issue or PR comment, mention the agent:

/oc summarize this thread
/opencode implement the fix described above and open a PR
  • On an issue, the agent creates a new branch, does the work, and opens a PR that closes the issue.
  • On a pull request, it works on the PR's branch (local or fork) and pushes its changes, then comments with a summary.
  • A bare mention (/oc alone) on a PR review comment asks the agent to review the commented lines; on an issue thread it summarizes the thread.

The agent adds an 👀 reaction while it works and removes it when done, and only acts for users with write access to the repo.

Note

The GitHub agent also supports scheduled and manual (workflow_dispatch) runs, where you supply the prompt via a PROMPT input. Image attachments in comments are downloaded and passed to the agent. Sessions from agent runs can be shared automatically (controlled by the SHARE input).

14.4 Checking out a PR locally

To review or continue a PR on your own machine, opencode can fetch it and start a session — importing the linked opencode session if the PR description contains one:

opencode pr 1234

This requires the gh CLI installed and authenticated. It checks out the PR (adding a fork remote if needed) and launches opencode.


15. The opencode Console (Zen Accounts)

If you use the hosted opencode Zen gateway or belong to an organization, the console command manages your account and org selection from the terminal.

opencode console login      # log in to the console (device-code flow)
opencode console logout     # log out of an account
opencode console switch     # switch the active organization
opencode console orgs       # list your orgs
opencode console open       # open the active console account in a browser

login walks you through a device-code flow: opencode shows a URL and a code, opens your browser, and polls until you authorize. Once you have an active org, opencode can pull org-managed configuration and provider access automatically.

Note

Zen lets you use many models behind a single key and (for organizations) centrally managed providers and config. If you authenticate as a provider with opencode auth login and pick opencode, you are using Zen.


16. Global Flags

These flags work with any command:

Flag Alias Description
--help -h Show help for opencode or a subcommand
--version -v Print the version number
--print-logs Print logs to stderr
--log-level <level> DEBUG, INFO, WARN, or ERROR
--pure Run without external plugins

Generate a shell completion script:

opencode completion >> ~/.bashrc   # or your shell's rc file

17. Useful Environment Variables

opencode reads a number of environment variables. The ones most relevant to daily use:

Variable Purpose
OPENCODE_CONFIG Path to a specific config file to load
OPENCODE_CONFIG_DIR Additional config directory to load from
OPENCODE_CONFIG_CONTENT Inline JSON config (highest project precedence)
OPENCODE_DISABLE_PROJECT_CONFIG Ignore project-level config
OPENCODE_PERMISSION Inline JSON permission overrides
OPENCODE_PURE Run without external plugins (same as --pure)
OPENCODE_SERVER_PASSWORD / OPENCODE_SERVER_USERNAME Auth for serve / web / attach
OPENCODE_DISABLE_AUTOUPDATE Turn off automatic update checks
OPENCODE_ALWAYS_NOTIFY_UPDATE Always notify when an update is available
OPENCODE_DISABLE_AUTOCOMPACT Disable automatic conversation compaction
OPENCODE_DISABLE_PRUNE Disable context pruning
OPENCODE_DISABLE_SHARE Disable session sharing entirely
OPENCODE_DISABLE_MOUSE Disable mouse capture in the TUI
OPENCODE_GIT_BASH_PATH Path to Git Bash (Windows)
OPENCODE_TUI_CONFIG Path to a specific tui.json
Provider keys (ANTHROPIC_API_KEY, OPENAI_API_KEY, …) Auto-detected provider credentials

Note

Variables prefixed OPENCODE_EXPERIMENTAL_… toggle experimental features (workspaces, session switcher, file watcher, and others). Set OPENCODE_EXPERIMENTAL=true to opt into the experimental set, or enable individual flags. Experimental features may change or be removed.


18. Troubleshooting

Error: You must provide a message or a command

Cause: You ran opencode run with no prompt, no --command, and nothing piped on stdin. Solution: Provide a prompt: opencode run "your request", pipe input (cat file | opencode run "..."), or use --command. Prevention: In scripts, always pass an explicit message or pipe content.

Error: --fork requires --continue or --session

Cause: --fork was used without specifying which session to fork. Solution: Add --continue (to fork the last session) or --session <id> (to fork a specific one).

Error: Session not found

Cause: The session id passed to --session, session delete, or export does not exist locally. Solution: Run opencode session list to find the correct id. If the session lives on another machine or a share, opencode import it first.

Error: Invalid model <value>. Model must be in the format "provider/model"

Cause: A model was passed without the provider/ prefix (commonly in the GitHub agent's model: input or --model). Solution: Use the full id, e.g. anthropic/claude-opus-4-8, not claude-opus-4-8. List valid ids with opencode models.

Error: Provider not found: <id>

Cause: You filtered opencode models <provider> (or referenced a provider) that you have not authenticated or that does not exist. Solution: Run opencode auth list to see configured providers and opencode auth login to add one. Refresh the catalog with opencode models --refresh.

Error: Comments must mention /opencode or /oc

Cause: The GitHub agent ran on a comment that does not mention it. Solution: Include /oc or /opencode in the comment. You can customize the trigger phrases via the workflow's MENTIONS input.

Error: User <name> does not have write permissions

Cause: The GitHub agent was triggered by a user without write access to the repository. Solution: Only repository collaborators with write or admin permission can run the agent. Grant access or have an authorized user trigger it.

Error: PROMPT input is required for ... events

Cause: A scheduled or workflow_dispatch (or issues) GitHub run started without a PROMPT, which those event types require. Solution: Supply a PROMPT input in the workflow for non-comment triggers.

Error: PROMPT_TOO_LARGE / "Input exceeds context window of this model"

Cause: The prompt (often plus attached files) is larger than the model's context window. Solution: In the TUI, compact the session (<leader> c) or start a new one (<leader> n). Attach fewer/smaller files, or switch to a model with a larger context window (<leader> m). The error lists the files in the prompt and their sizes.

Error: Unauthorized: request was blocked by a gateway or proxy...

Cause: A provider request returned 401/403 from a gateway — usually a missing or expired token. Solution: Re-authenticate: opencode auth login <your provider URL>. Check that any required environment variables (API keys, gateway tokens) are set.

Error: Could not find git repository. Please run this command from a git repository.

Cause: opencode github install or opencode pr was run outside a git repo (or one without a GitHub origin). Solution: cd into a cloned git repository whose origin points at GitHub.

Error: Could not fetch an OIDC token. Make sure to add 'id-token: write' to your workflow permissions.

Cause: The GitHub workflow is missing the id-token: write permission the agent needs to exchange an app token. Solution: Add permissions: { id-token: write, ... } to the job (the generated workflow includes it).

Warning: OPENCODE_SERVER_PASSWORD is not set; server is unsecured.

Cause: You started serve/web without a password. Solution: Set OPENCODE_SERVER_PASSWORD (and optionally OPENCODE_SERVER_USERNAME) before exposing the server beyond localhost. See §10.1.

opencode enters an auto-compaction loop / stops responding

Cause: The session repeatedly compacts when context is tight. Solution: Start a fresh session (<leader> n). As a workaround you can disable automatic compaction with OPENCODE_DISABLE_AUTOCOMPACT=true, though long sessions may then hit context limits.

Startup hangs in a project with .opencode/node_modules/

Cause: A large node_modules directory under .opencode/ slows project scanning. Solution: Keep .opencode/node_modules/ out of the way; opencode writes a .gitignore in config dirs to exclude installed plugin dependencies. Remove stray node_modules you did not intend to commit.

Ctrl+Z suspends opencode instead of editing text (Linux)

Cause: Ctrl+Z is bound to terminal suspend by default on POSIX systems. Solution: Remap terminal_suspend to "none" and/or input_undo to your preference in tui.json (see §11.4). On native Windows this is handled automatically.

Cannot paste from the clipboard

Cause: Terminal or platform clipboard integration, or a copy-on-select conflict. Solution: Paste is bound to Ctrl+v by default. On Windows, opencode disables copy-on-select by default; you can toggle this with OPENCODE_EXPERIMENTAL_DISABLE_COPY_ON_SELECT.


19. Frequently Asked Questions

Q: Do I need an OpenAI/Anthropic API key, or can I use my existing subscription? You can use either. OpenAI works with a ChatGPT Plus/Pro subscription via OAuth or with an API key; GitHub Copilot uses your Copilot subscription; Anthropic supports OAuth or an API key. You can also use the hosted opencode Zen gateway with a single key.

Q: Which models can I use? Any model from any provider you have authenticated. The catalog comes from models.dev. Run opencode models to list them, and switch any time with <leader> m.

Q: How do I change the model for a single run? opencode run -m provider/model "your prompt", or in the TUI press <leader> m. Set a default with model in opencode.json.

Q: Where is my data stored? Locally. Sessions live in a SQLite database (find it with opencode db path); credentials in auth.json; config in your config directory. Nothing is sent anywhere except to the model provider you chose (and to the share service if you explicitly share a session).

Q: Is opencode safe to let edit my files and run commands? By default, in interactive mode, opencode asks before edits and shell commands. You control this per capability via permission/tools config and per agent. Avoid --dangerously-skip-permissions outside sandboxes.

Q: How do I stop the agent mid-task? Press Esc in the TUI to interrupt. In run, send Ctrl+c.

Q: My context filled up — what do I do? Compact the session with <leader> c, or start a new one with <leader> n. opencode also auto-compacts; you can disable that with OPENCODE_DISABLE_AUTOCOMPACT.

Q: Can I use opencode without internet access to a cloud model? Yes, if you connect a local/self-hosted model endpoint as a provider (for example, an OpenAI-compatible local server). Configure it under provider in opencode.json.

Q: How do I share a session with a teammate? Use --share on opencode run, the share keybind in the TUI, or "share": "auto". You will get a public URL. Use opencode export --sanitize if you need a redacted copy instead.

Q: How do I add a tool the agent doesn't have? Connect an MCP server (opencode mcp add) to give the agent new tools, or write a plugin (opencode plugin <module>).

Q: What's the difference between an agent and a command? An agent is a persona (system prompt + permissions + model) you converse with. A command is a reusable prompt template you trigger by name. You can combine them: a command can specify which agent runs it.

Q: How do I run opencode in CI? Use the GitHub agent (opencode github install) for issue/PR automation, or opencode run --format json in any pipeline for scripted, machine-readable runs.

Q: How do I completely remove opencode? opencode uninstall (add --keep-config/--keep-data to preserve those). It removes data, cache, config, and state directories and the PATH entry.

Q: Why does opencode want to write a .gitignore in my config directory? When it installs the @opencode-ai/plugin dependency into a .opencode directory, it ignores node_modules, lockfiles, and the generated package.json so they are not committed.

Q: Can I disable telemetry/sharing across my org? Set OPENCODE_DISABLE_SHARE to disable sharing. Organization-managed installs can also enforce config centrally (see the Admin Guide).


Appendix A: Keybinding Reference

All bindings are overridable under keybinds in tui.json. The leader key defaults to Ctrl+x; <leader> below means "press the leader, then the key shown."

Application

Action Key Description
app_exit ctrl+c, ctrl+d, <leader>q Exit the application
command_list ctrl+p List available commands
terminal_suspend ctrl+z Suspend terminal (disabled on Windows)
which_key_toggle ctrl+alt+k Toggle the which-key panel

Sessions

Action Key Description
session_new <leader>n Create a new session
session_list <leader>l List all sessions
session_timeline <leader>g Show session timeline
session_rename ctrl+r Rename session
session_delete ctrl+d Delete session
session_interrupt escape Interrupt the current response
session_compact <leader>c Compact the session
session_export <leader>x Export session to editor
session_background ctrl+b Background synchronous subagents
session_pin_toggle ctrl+f Pin/unpin in the session list
session_quick_switch_1…9 <leader>1…<leader>9 Switch to a quick-slot session
session_parent / session_child_first up / <leader>down Move to parent / first child session

Models, agents, variants

Action Key Description
model_list <leader>m List available models
model_cycle_recent f2 Next recently used model
model_cycle_recent_reverse shift+f2 Previous recently used model
agent_list <leader>a List agents
agent_cycle / agent_cycle_reverse tab / shift+tab Next / previous agent
variant_cycle ctrl+t Cycle model variants

Messages & viewing

Action Key Description
messages_page_up / messages_page_down pageup / pagedown Scroll a page
messages_first / messages_last ctrl+g / ctrl+alt+g First / last message
messages_copy <leader>y Copy message
messages_undo / messages_redo <leader>u / <leader>r Undo / redo a change
messages_toggle_conceal <leader>h Toggle code-block concealment

Appearance & panels

Action Key Description
theme_list <leader>t Switch theme
sidebar_toggle <leader>b Toggle sidebar
editor_open <leader>e Open external editor
status_view <leader>s View status

Diff viewer

Action Key Description
diff_close escape, q Close diff viewer
diff_toggle enter, space Toggle item
diff_next_file / diff_previous_file n / p Next / previous file
diff_toggle_view v Split vs. unified
diff_toggle_file_tree b Toggle file tree

Prompt input (selection of common bindings)

Action Key Description
input_submit return Submit input
input_newline shift+return, ctrl+j Insert a newline
input_paste ctrl+v Paste from clipboard
input_word_forward / input_word_backward alt+f / alt+b Move by word
input_delete_word_backward ctrl+w Delete previous word
input_undo / input_redo ctrl+- / ctrl+. Undo / redo in the input
history_previous / history_next up / down Cycle prompt history

Note

This is a representative subset. The complete list of input-editing bindings (visual-line motions, buffer home/end, selection variants) is defined in opencode and surfaced in the which-key panel (Ctrl+Alt+k).