Skip to content

Configuring OpenCode

OpenCode is the open-source TypeScript agent from SST. Its main differentiator is provider neutrality: you point it at Anthropic, OpenAI, Google, Bedrock, Ollama, llama.cpp, or any of 75+ supported backends. This makes it the natural choice when you need to run an agent against a local model.

A naming clarification before we start: there used to be another tool called OpenCode by Charm. They renamed theirs to Crush (github.com/charmbracelet/crush). When current docs say “OpenCode” they mean the SST one.

The universal install script is the recommended path:

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

Other paths: npm install -g opencode-ai, brew install anomalyco/tap/opencode, pacman -S opencode, choco install opencode. A Docker image lives at ghcr.io/anomalyco/opencode.

Run opencode to enter the TUI. From there:

  1. /connect opens a provider picker that handles OAuth or accepts an API key.
  2. /init writes a starter AGENTS.md based on your repo.

CLI auth equivalents:

Terminal window
opencode auth login
opencode auth list
opencode auth logout

Credentials live at ~/.local/share/opencode/auth.json, not in opencode.json. This means project config is safe to commit.

Default model is set in config. Switch per session with /models in the TUI, or with --model on the CLI.

{
"model": "anthropic/claude-sonnet-4-5",
"small_model": "anthropic/claude-haiku-4-5"
}

The provider/model format makes provider switches one-line edits: openai/gpt-5.4, google/gemini-2.5-pro, ollama/qwen2.5-coder:32b.

OpenCode uses AGENTS.md, the same convention as Codex. Discovery walks up from cwd until it finds one. Falls back to CLAUDE.md if no AGENTS.md exists, then to ~/.config/opencode/AGENTS.md.

/init generates a starter file. The recommended content is build, lint, test commands, repo layout, and project conventions. Plain markdown.

External references can be pulled in via the instructions config key:

{
"instructions": [
"docs/lab_conventions.md",
"packages/*/AGENTS.md"
]
}

Locations, in increasing precedence:

  1. Remote .well-known/opencode (org defaults)
  2. Global ~/.config/opencode/opencode.json
  3. Custom path via OPENCODE_CONFIG
  4. Project ./opencode.json (walks up to git root)
  5. Inline OPENCODE_CONFIG_CONTENT env var
  6. Managed system files

Schema URL for editor JSON-schema integration: https://opencode.ai/config.json. Variable substitution uses {env:VAR_NAME} and {file:path}.

A representative opencode.json:

{
"$schema": "https://opencode.ai/config.json",
"model": "anthropic/claude-sonnet-4-5",
"small_model": "anthropic/claude-haiku-4-5",
"autoupdate": true,
"permission": {
"*": "ask",
"read": "allow",
"edit": "ask",
"bash": {
"git status*": "allow",
"git diff*": "allow",
"uv *": "allow",
"rm -rf *": "deny"
},
"webfetch": "deny"
},
"instructions": ["docs/lab_conventions.md"],
"watcher": {
"ignore": ["data/**", "results/**", ".venv/**"]
}
}

Common keys: model, small_model, provider, permission, agent, command, mcp, tools, instructions, formatter, lsp, share, snapshot, watcher, disabled_providers, enabled_providers, plugin.

Three states: allow, ask, deny. Tool keys include read, edit, bash, glob, grep, task, webfetch, websearch, external_directory, lsp, skill.

read defaults to allow except for .env files. Wildcards (*) set defaults. Object-form values give last-match-wins pattern rules:

{
"permission": {
"bash": {
"git *": "allow",
"rm -rf *": "deny"
}
}
}

When prompted interactively, the user picks once, always (session-scoped), or reject. The CLI flag --dangerously-skip-permissions exists for opencode run in headless settings; use sparingly.

Two primary agents ship by default; switch between them with Tab in the TUI:

  • build: full tool access (default).
  • plan: read-only or restricted; edit and bash default to ask.

Two subagents ship by default:

  • general: full tools, multi-step.
  • explore: read-only, codebase exploration.

Custom agents live as markdown in .opencode/agents/ (project) or ~/.config/opencode/agents/ (global).

---
description: SQL review subagent
mode: subagent
model: anthropic/claude-sonnet-4-5
permission:
edit: deny
bash: deny
---
You only review SQL queries. Look for missing indexes, full-table scans,
and N+1 patterns. Suggest fixes but do not edit files.

CLI helper: opencode agent create walks you through generation.

Custom commands are markdown files in .opencode/commands/ (project) or the user-level equivalent. Filename becomes command name (test.md/test).

---
description: Run tests with coverage
agent: build
---
Run `pytest --cov=src` and summarise failures.
Latest git status:
!`git status -s`
Coverage config:
@pyproject.toml

Inside the prompt, three placeholders are useful:

  • $ARGUMENTS, $1, $2: arguments passed to the command
  • !`cmd`: runs a shell command and injects stdout
  • @path: includes the contents of a file or directory listing

Configured under "mcp" in opencode.json. Both local (stdio subprocess) and remote (HTTP) transports.

{
"mcp": {
"filesystem": {
"type": "local",
"command": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/data"],
"enabled": true
},
"internal-api": {
"type": "remote",
"url": "https://mcp.example.org",
"enabled": true,
"headers": { "Authorization": "Bearer {env:MCP_TOKEN}" }
}
}
}

OAuth is handled automatically. CLI helper: opencode mcp auth <server>.

Default opencode launches the TUI. Other entry points:

  • opencode run <prompt>: one-shot, non-interactive.
  • opencode serve: headless API server.
  • opencode web: headless server with a web UI.
  • opencode acp: Agent Client Protocol server for IDE integrations.
  • opencode session: list and delete sessions.
  • opencode models: list provider/model IDs.

You can connect a CLI to a running server with --attach http://localhost:4096 to skip cold-boot.

Terminal window
opencode run "summarise the diff and write a release note" \
--model anthropic/claude-sonnet-4-5 \
--agent build \
--format json \
-f CHANGELOG.md
opencode run -c "follow up: also list affected modules" # continue last session
opencode run -s <session-id> "follow up to that session"

--format json emits raw JSON events good for CI parsing. GitHub Actions integration: opencode github install scaffolds .github/workflows/opencode.yml. Triggers from /opencode or /oc in a PR or issue comment, with provider keys in repo secrets.

The standout feature is first-class local model support. For lab data that cannot leave the machine, point OpenCode at Ollama or llama.cpp:

{
"provider": {
"ollama": {
"npm": "@ai-sdk/openai-compatible",
"name": "Ollama (local)",
"options": { "baseURL": "http://localhost:11434/v1" },
"models": {
"qwen2.5-coder:32b": { "name": "Qwen 2.5 Coder 32B" }
}
}
},
"model": "ollama/qwen2.5-coder:32b"
}

Tool calling needs num_ctx raised to 16k or 32k in Ollama; otherwise the agent’s tool-use prompts get truncated.

For HPC and air-gapped setups, no official guidance exists, but the architecture is friendly: point baseURL at a cluster-internal inference endpoint, ship the npm install, and drop an opencode.json next to the project. Treat this as a community pattern rather than a blessed config.

  • The anomalyco namespace in install URLs (Homebrew tap, Docker image, mise source) is SST-controlled. Not separately documented but legitimate.
  • opencode run stdin piping is not in the official docs. Verify on your install before relying on it.
  • webfetch is the network gate: there is no separate “network” permission. Disable webfetch, websearch, and remote mcp servers to keep traffic local.
  • Local model context windows: Ollama defaults are too small for tool use. Override per-model.