OpenCode
OpenCode
Section titled “OpenCode”OpenCode is an MIT-licensed, open-source AI coding agent for the terminal built by SST (YC-backed). With 147k+ GitHub stars and releases shipping multiple times per week, it’s one of the fastest-moving projects in the agentic coding space. Its key differentiators over Claude Code and Mistral Vibe are built-in LSP integration (real-time type errors fed to the agent), a client/server architecture (attach multiple sessions to one server), and a rich headless JSON event stream for automation pipelines.
What is OpenCode?
Section titled “What is OpenCode?”OpenCode is a terminal-based AI coding agent that can:
- Read, write, and edit files with exact-string replacement
- Execute shell commands in a stateful bash session
- Search files by name (glob) and content (grep/regex)
- Fetch and parse web pages
- Receive real-time LSP diagnostics (type errors, missing imports) as it edits
- Connect to MCP servers for extended capabilities
- Run headless with structured JSON output for CI/CD pipelines
- Operate as a persistent server that multiple clients can attach to
Built-in Tools
Section titled “Built-in Tools”| Tool | Description | Claude Code Equivalent |
|---|---|---|
read | Read file contents (supports line ranges) | Read |
write | Create or overwrite files | Write |
edit | Exact-string replacement | Edit |
apply_patch | Apply unified diff patches | — |
bash | Execute shell commands | Bash |
glob | Find files by pattern | Glob |
grep | Regex content search | Grep |
webfetch | Fetch and parse web pages | WebFetch |
lsp | Code intelligence (definitions, references, hover) | — |
skill | Load SKILL.md instruction files | Skill |
question | Prompt user for clarification | AskUserQuestion |
Why OpenCode? (vs. Alternatives)
Section titled “Why OpenCode? (vs. Alternatives)”| Feature | Claude Code | Mistral Vibe | OpenCode |
|---|---|---|---|
| License | Proprietary | Apache 2.0 | MIT |
| Model support | Claude only | Any OpenAI-compat | Any (ai-sdk providers) |
| Self-hosted | No | Yes | Yes |
| LSP integration | No | No | Yes (20+ languages) |
| Client/server | No | No | Yes (opencode serve) |
| Headless mode | No | vibe -p | opencode run + JSON events |
| MCP support | Yes | Yes (stdio+HTTP) | Yes (stdio+SSE+OAuth) |
| Custom instructions | CLAUDE.md | AGENTS.md | AGENTS.md + CLAUDE.md fallback |
| GitHub stars | N/A | ~5k | ~147k |
| Cost | $20-200/mo subscription | Free (self-host) | Free (self-host) or provider tokens |
Verdict: OpenCode’s LSP integration and client/server architecture make it the best open-source shell for agentic coding. Claude Code has higher benchmark scores. Vibe has simpler setup for self-hosted Devstral. Use OpenCode when you want LSP diagnostics, session persistence, or the richest automation API.
Installation
Section titled “Installation”macOS / Linux (Recommended)
Section titled “macOS / Linux (Recommended)”curl -fsSL https://opencode.ai/install | bashPackage Managers
Section titled “Package Managers”# npm (package name is opencode-ai, NOT opencode)npm i -g opencode-ai
# Homebrew (use the tap for latest)brew install anomalyco/tap/opencode
# Bunbun add -g opencode-aiOther Platforms
Section titled “Other Platforms”# Windows (Scoop)scoop install opencode
# Arch Linuxsudo pacman -S opencode
# Nixnix run nixpkgs#opencodeDesktop App (Beta)
Section titled “Desktop App (Beta)”brew install --cask opencode-desktopAlso available for Windows (NSIS installer) and Linux (deb/rpm) at the OpenCode website.
Common Install Mistakes
- The npm package is
opencode-ai, notopencode— wrong name installs a different package - On Homebrew,
brew install anomalyco/tap/opencodeis more current thanbrew install opencode - On WSL: the curl script may install into WSL instead of native Windows. Use Git Bash (MinGW64) if targeting native Windows.
Configuration
Section titled “Configuration”OpenCode uses opencode.json (or opencode.jsonc) for configuration:
- Project-level:
./opencode.jsonin the repo root (highest priority) - Global:
~/.config/opencode/opencode.json - Auth:
~/.config/opencode/auth.json(API keys, separate from config)
Add the $schema key for IDE autocompletion of all config options:
{ "$schema": "https://opencode.ai/config.json", "model": "anthropic/claude-sonnet-4-5", "small_model": "anthropic/claude-haiku-4-5"}Provider Configuration
Section titled “Provider Configuration”{ "$schema": "https://opencode.ai/config.json", "model": "vllm/devstral-123b", "small_model": "vllm/devstral-123b",
"provider": { "vllm": { "npm": "@ai-sdk/openai-compatible", "name": "Local vLLM", "options": { "baseURL": "http://192.168.1.19:8000/v1" }, "models": { "devstral-123b": { "name": "Devstral 123B (Self-Hosted)" } } } }}The model ID (e.g., devstral-123b) must exactly match what vLLM exposes at /v1/models.
Auth (Separate File)
Section titled “Auth (Separate File)”API keys live in ~/.config/opencode/auth.json, not in the main config:
{ "anthropic": { "api_key": "sk-ant-..." }, "vllm": { "api_key": "your-vllm-key" }}Permissions
Section titled “Permissions”{ "permission": { "*": "ask", "bash": { "*": "ask", "git *": "allow", "npm *": "allow", "rm *": "deny" }, "edit": "allow", "read": "allow", "grep": "allow", "glob": "allow" }}Values: "allow" (auto-approve), "ask" (prompt user), "deny" (block). Wildcard patterns supported for bash commands.
Custom Instructions (AGENTS.md)
Section titled “Custom Instructions (AGENTS.md)”OpenCode searches for instruction files in this order:
AGENTS.mdin current directory (traverses upward to repo root)~/.config/opencode/AGENTS.md(global)CLAUDE.mdin current directory (legacy fallback)~/.claude/CLAUDE.md(Claude Code global fallback)
To include additional instruction files:
{ "instructions": [ "CONTRIBUTING.md", "docs/style-guide.md", ".cursor/rules/*.md" ]}Glob patterns and remote URLs are supported.
The /init slash command runs a guided setup to generate AGENTS.md from your project.
MCP Servers
Section titled “MCP Servers”Local (Subprocess)
Section titled “Local (Subprocess)”{ "mcp": { "filesystem": { "type": "local", "command": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/path/to/project"], "enabled": true, "timeout": 5000 }, "git": { "type": "local", "command": ["uvx", "mcp-server-git"], "enabled": true } }}Remote (HTTP/SSE)
Section titled “Remote (HTTP/SSE)”{ "mcp": { "my-api": { "type": "remote", "url": "https://mcp.example.com", "enabled": true, "headers": { "Authorization": "Bearer {env:MY_TOKEN}" } } }}OAuth (Auto-Registration)
Section titled “OAuth (Auto-Registration)”{ "mcp": { "notion": { "type": "remote", "url": "https://mcp.notion.com", "oauth": { "clientId": "{env:NOTION_CLIENT_ID}", "clientSecret": "{env:NOTION_SECRET}", "scope": "tools:read tools:execute" } } }}Management commands: opencode mcp list, opencode mcp debug <name>, opencode mcp auth <name>.
Environment variable substitution: {env:VAR_NAME} works in all config values.
LSP Integration
Section titled “LSP Integration”OpenCode’s standout feature. The agent receives real-time diagnostics from language servers as it edits — catching type errors, missing imports, and syntax issues in-loop without needing a separate compile step.
Auto-Detected Languages (20+)
Section titled “Auto-Detected Languages (20+)”| Language | Server | Required |
|---|---|---|
| TypeScript/JavaScript | typescript | typescript in project deps |
| Go | gopls | gopls binary |
| Rust | rust-analyzer | rust-analyzer binary |
| Python | pyright / pylsp | respective binary |
| Ruby | solargraph | solargraph gem |
| C/C++ | clangd | clangd binary |
| Java | jdtls | Eclipse JDT LS |
| Vue | @vue/language-server | npm package |
| Svelte | svelte-language-server | npm package |
| Astro | @astrojs/language-server | npm package |
OpenCode auto-downloads missing LSP servers unless OPENCODE_DISABLE_LSP_DOWNLOAD=true.
Custom LSP Configuration
Section titled “Custom LSP Configuration”{ "lsp": { "my-language": { "command": ["my-lsp-server", "--stdio"], "extensions": [".mylang"], "disabled": false } }}To disable all LSP: "lsp": false.
Built-in Tools
Section titled “Built-in Tools”All tools are enabled by default. Disable specific tools in config:
{ "tools": { "webfetch": false, "websearch": false }}Web Search (Exa AI)
Section titled “Web Search (Exa AI)”Web search requires OPENCODE_ENABLE_EXA=true in environment. Uses Exa AI for search results.
Headless Mode & Automation
Section titled “Headless Mode & Automation”The opencode run command executes a task non-interactively — critical for CI/CD and orchestration scripts.
Basic Usage
Section titled “Basic Usage”# Simple one-shot taskopencode run "Fix all TypeScript errors in src/"
# With model overrideopencode run "Refactor the auth module" --model anthropic/claude-sonnet-4-5
# Auto-approve all tool calls (for automated pipelines)opencode run "Run tests and fix failures" --dangerously-skip-permissions
# Attach file contextopencode run "Review this file" --file src/auth.tsJSON Event Stream
Section titled “JSON Event Stream”opencode run "Fix the bug" --format json --dangerously-skip-permissionsOutputs newline-delimited JSON (JSONL) with event types:
| Event | Key Fields |
|---|---|
step_start | sessionID, part.snapshot |
tool_use | part.tool, part.state.input, part.state.output |
text | part.text |
step_finish | part.cost, part.tokens, part.reason |
error | error.data.message |
Client/Server Architecture
Section titled “Client/Server Architecture”Start a persistent server and attach multiple headless jobs:
# Start server (once per project)opencode serve --port 4096 &
# Attach headless jobs (multiple can run concurrently)opencode run --attach http://localhost:4096 "Fix auth module" --format jsonopencode run --attach http://localhost:4096 "Write tests" --format jsonThis avoids MCP server cold-start overhead on every invocation — significantly faster than stateless CLI calls.
Session Management
Section titled “Session Management”# Continue last sessionopencode run "Continue the refactoring" --continue
# Resume specific sessionopencode run "Fix the remaining issues" --session ses_XXXXXXXXXXXXXXXXXXXX
# Fork a session (don't overwrite original)opencode run "Try a different approach" --fork --session ses_XXXXSession data stored at ~/.local/share/opencode/.
Self-Hosted Backend (vLLM)
Section titled “Self-Hosted Backend (vLLM)”Configuration
Section titled “Configuration”{ "$schema": "https://opencode.ai/config.json", "model": "vllm/devstral-123b", "provider": { "vllm": { "npm": "@ai-sdk/openai-compatible", "name": "Obelisk vLLM", "options": { "baseURL": "http://your-server:8000/v1" }, "models": { "devstral-123b": { "name": "Devstral 123B" } } } }}Verify the model is accessible: curl http://your-server:8000/v1/models.
Claude Code + OpenCode Orchestration (Best of Both Worlds)
Section titled “Claude Code + OpenCode Orchestration (Best of Both Worlds)”Like the Vibe Orchestration pattern, OpenCode can serve as a grunt-work executor dispatched by Claude Code. OpenCode’s advantages over Vibe for orchestration: LSP diagnostics catch type errors in-loop, session continuity via --continue/--attach, and JSONL events with token/cost tracking per step.
When to use OpenCode vs Vibe as the dispatch target:
| Task | Use OpenCode | Use Vibe |
|---|---|---|
| TypeScript / Go / Rust / Python edits | Best (LSP) | Good |
| Long multi-step sessions | Best (compaction + sessions) | Risky (no compaction) |
| CI/CD with cost tracking | Best (JSONL has tokens/cost) | Limited (internal only) |
| Quick one-shot tasks | Good | Best (faster cold start) |
| Scripted dispatch to arbitrary dirs | No --workdir flag | Best (--workdir) |
| Markdown / configs / docs | Good | Best (lighter, LSP irrelevant) |
How It Works
Section titled “How It Works”┌──────────────────────────────────────────────────────────────────┐│ Claude Code (Brain) ││ Plans → Dispatches → Reviews → Synthesizes → Commits ││ ││ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ ││ │ opencode run │ │ opencode run │ │ opencode run │ ││ │ --attach :4096 │ │ --attach :4096 │ │ --attach :4096 │ ││ │ TypeScript src │ │ Go backend │ │ Tests │ ││ │ (LSP catches │ │ (LSP catches │ │ (parallel) │ ││ │ type errors) │ │ type errors) │ │ │ ││ └────────────────┘ └────────────────┘ └────────────────┘ ││ ↓ ↓ ↓ ││ opencode run (synthesizer) → Claude Code (judgment only) │└──────────────────────────────────────────────────────────────────┘Persistent Server Pattern
Section titled “Persistent Server Pattern”Start one server per project — all headless jobs attach to it, avoiding MCP cold-start overhead:
# Start server (once per project, runs in background)cd /path/to/project && opencode serve --port 4096 &
# Dispatch parallel agents — all attach to the same serveropencode run --attach http://localhost:4096 \ --model vllm/devstral-123b \ --dangerously-skip-permissions \ "Create src/lib/auth.ts with login, logout, session functions" &
opencode run --attach http://localhost:4096 \ --model vllm/devstral-123b \ --dangerously-skip-permissions \ "Write tests for src/lib/utils.ts at src/tests/utils.test.ts" &
opencode run --attach http://localhost:4096 \ --model vllm/devstral-123b \ --dangerously-skip-permissions \ "Document all exports in src/lib/ to docs/api.md" &
wait # All three complete in parallelJSONL Event Stream for CI/CD
Section titled “JSONL Event Stream for CI/CD”OpenCode’s --format json outputs structured events that pipelines can parse:
opencode run "Fix all TypeScript errors" \ --model vllm/devstral-123b \ --format json \ --dangerously-skip-permissions \ | jq 'select(.type == "step_finish") | {cost: .part.cost, tokens: .part.tokens}'Each step_finish event includes cost and tokens (input/output/total) — useful for tracking spend in automated pipelines.
Serial Dispatch with Session Continuity
Section titled “Serial Dispatch with Session Continuity”OpenCode’s --continue flag resumes the last session, preserving context:
# Step 1: Researchopencode run "Read src/api/ and list all endpoints" \ --model vllm/devstral-123b --dangerously-skip-permissions
# Step 2: Build on the research (same context)opencode run "Add a new POST /api/reset-password endpoint following those patterns" \ --model vllm/devstral-123b --dangerously-skip-permissions --continueThis is something Vibe cannot do — each vibe -p invocation starts fresh with no memory.
Cost Comparison
Section titled “Cost Comparison”| Approach | Claude Tokens | Self-Hosted Tokens | Time |
|---|---|---|---|
| Claude Code solo | ~500K ($2-10) | 0 | 1 session |
| Claude + OpenCode dispatch | ~50K ($0.20-1) | Unlimited (free) | Faster (parallel) |
| Claude + Vibe dispatch | ~50K ($0.20-1) | Unlimited (free) | Faster (parallel) |
| OpenCode solo (self-hosted) | 0 | Unlimited | Slower (weaker planning) |
Custom Agents
Section titled “Custom Agents”Define specialized agents in opencode.json:
{ "agent": { "reviewer": { "description": "Code review without making changes", "mode": "primary", "model": "anthropic/claude-opus-4-5", "permission": { "edit": "deny", "write": "deny", "bash": "deny" } }, "fast": { "description": "Quick tasks with auto-approval", "model": "anthropic/claude-haiku-4-5", "permission": { "*": "allow" } } }, "default_agent": "reviewer"}Use with: opencode run "Review the PR" --agent reviewer.
Tips & Known Issues
Section titled “Tips & Known Issues”- LSP is the killer feature — use it on TypeScript, Go, Rust, and Python repos for significantly fewer hallucinated edits
opencode serveonce per project, then attach headless jobs — avoids cold starts/initgeneratesAGENTS.mdfrom your project — good starting point for custom rules$schemainopencode.jsonenables full IDE autocompletion for config- Session fork (
--fork --session) lets you try different approaches without losing the original session - OpenCode reads CLAUDE.md automatically — zero-effort migration from Claude Code
Known Issues
Section titled “Known Issues”| Issue | Workaround | Status |
|---|---|---|
npm package is opencode-ai not opencode | Use correct name | Permanent |
| Context compaction at hardcoded 75% threshold | Can cause issues on long sessions; no config override yet | Open (#11314) |
--format json may fail with --command flag | Use positional arg instead | Open (#2923) |
| WSL path breakage with Windows Desktop app | Clone repos into WSL filesystem, not /mnt/c/ | By design |
Linux clipboard requires xclip/wl-clipboard | Install: sudo apt install xclip | By design |
| Excessive token consumption on large repos | Fixed in recent versions; monitor usage | Resolved |
| Corrupt plugin cache causes startup hang | Delete plugin key from config, or remove ~/.cache/opencode | Workaround |
Related Resources
Section titled “Related Resources”- Claude Code - Anthropic’s proprietary agentic coding CLI (highest benchmark scores)
- Mistral Vibe - Open-source CLI with self-hosted Devstral backend
- OpenHands - Web-based autonomous coding agent with sandbox isolation
- Gemini Code - Google’s Gemini CLI for multi-model orchestration
- AI Agent Pricing - Cost comparison across all CLI agents
External Links
Section titled “External Links”- OpenCode Documentation
- OpenCode GitHub - Source code (MIT)
- OpenCode Desktop - Desktop app for macOS, Windows, Linux
- Vibe Coding Repository - Community rules, skills, and lessons learned