docs: expand OpenCode 2 beta guides

This commit is contained in:
Dax Raad 2026-07-09 18:00:30 -04:00
parent a7746379d5
commit 1004fbb2f5
24 changed files with 889 additions and 359 deletions

View file

@ -20,7 +20,7 @@ export const OpencodeContent = opencodeContent
export const ReportContent = reportContent
export const OpencodeDescription =
"Use this skill for any question about OpenCode itself, including how OpenCode works, using or configuring it, troubleshooting it, developing plugins or integrations, using the OpenCode SDK, clients, server, or API, and contributing to the OpenCode codebase. Also use it for OpenCode agents, commands, skills, tools, permissions, MCP servers, providers, models, themes, keybinds, formatters, the CLI, TUI, desktop app, and web app."
"Use this skill for any question about OpenCode itself, including how OpenCode works, using or configuring it, migrating from V1 to V2, troubleshooting it, developing plugins or integrations, using the OpenCode SDK, clients, server, or API, and contributing to the OpenCode codebase. Also use it for OpenCode agents, commands, skills, tools, permissions, MCP servers, providers, models, themes, keybinds, formatters, the CLI, TUI, desktop app, and web app."
const REPORT_DESCRIPTION =
"Use when the user wants to report an opencode issue or bug. Collect standard diagnostics, add user-specific reproduction context, and publish the issue with GitHub CLI."

View file

@ -37,6 +37,23 @@ settings when editing an existing file.
See the [full configuration guide](https://opencode.mintlify.site/config) for
every field, examples, config locations, and links to dedicated feature guides.
## V1 to V2 migration
For any request to migrate OpenCode configuration, agents, commands, skills,
plugins, integrations, or other behavior from V1 to V2, read the full
[migration guide](https://opencode.mintlify.site/migrate-v1) before acting. In
the repository, its source is `packages/docs/migrate-v1.mdx`.
V1 config files and `.opencode/` definitions are intended to remain compatible.
The only intentional breaking changes are the server API and plugin API. Native
V2 config uses more ergonomic shapes, but conversion is optional. When the user
requests conversion, inspect the complete configuration, preserve behavior and
unrelated settings, and apply only the relevant migrations from the guide. If
the request includes a V1 plugin, explain that its API is not finalized and do
not attempt migration yet. Once the V2 plugin API is finalized, OpenCode should
be able to migrate most plugins. If non-API V1 functionality fails in V2, use
the `report` skill to file it as a compatibility bug.
## Service
OpenCode uses a client-server architecture. Interfaces such as the TUI connect

View file

@ -1,6 +1,6 @@
---
title: "Agents"
description: "Configure and use primary agents and subagents in OpenCode."
description: ""
---
Agents combine a system prompt, model preference, tool permissions, and display
@ -8,32 +8,6 @@ metadata into a reusable assistant profile. OpenCode includes agents for common
workflows, and you can override them or add your own in configuration or
Markdown files.
## Modes
An agent's `mode` controls where it can run:
| Mode | Behavior |
| --- | --- |
| `primary` | Can be selected as the main agent for a session. It cannot be launched as a subagent. |
| `subagent` | Can run in a child session through the `subagent` tool, but cannot be selected as the main agent. |
| `all` | Can be used either way. This is the default for a custom agent when `mode` is omitted. |
In the TUI, press <kbd>Tab</kbd> and <kbd>Shift</kbd>+<kbd>Tab</kbd> to cycle
through visible primary and `all` agents, or use `/agents` to choose one.
Subagents run in child sessions with fresh context. A primary agent can invoke
one with the `subagent` tool, either in the foreground or in the background.
You can also `@` mention a visible subagent to ask the current agent to delegate
work to it:
```text
@explore find where authentication errors are handled
```
The parent agent's `subagent` permission controls which agents it may launch.
The child currently uses its own configured permissions, not a restricted copy
of the parent's permissions.
## Built-in agents
| Agent | Mode | Purpose |
@ -66,42 +40,33 @@ be hidden. If it is unavailable, OpenCode falls back to `build`, then to the
first visible agent that can run as a primary agent. This selection does not
rewrite the agent already stored on an existing session.
## Configure agents
## Modes
### JSON or JSONC
An agent's `mode` controls where it can run:
Use the plural `agents` field in any [OpenCode configuration file](/config):
| Mode | Behavior |
| --- | --- |
| `primary` | Can be selected as the main agent for a session. It cannot be launched as a subagent. |
| `subagent` | Can run in a child session through the `subagent` tool, but cannot be selected as the main agent. |
| `all` | Can be used either way. This is the default for a custom agent when `mode` is omitted. |
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"default_agent": "reviewer",
"agents": {
"reviewer": {
"description": "Reviews changes for correctness, security, and missing tests",
"mode": "all",
"model": "anthropic/claude-sonnet-4-5#high",
"system": "Review the current changes. Report findings before any summary.",
"color": "warning",
"steps": 8,
"permissions": [
{ "action": "edit", "resource": "*", "effect": "deny" },
{ "action": "shell", "resource": "*", "effect": "deny" }
]
},
"build": {
"permissions": [
{ "action": "shell", "resource": "git push *", "effect": "ask" }
]
}
}
}
In the TUI, press <kbd>Tab</kbd> and <kbd>Shift</kbd>+<kbd>Tab</kbd> to cycle
through visible primary and `all` agents, or use `/agents` to choose one.
Subagents run in child sessions with fresh context. A primary agent can invoke
one with the `subagent` tool, either in the foreground or in the background.
You can also `@` mention a visible subagent to ask the current agent to delegate
work to it:
```text
@explore find where authentication errors are handled
```
Agent definitions merge in configuration order. Later scalar fields replace
earlier values, request maps merge by key, and permission rules are appended.
Global `permissions` are applied to every agent before its agent-specific rules,
so a later agent rule can refine a global rule.
The parent agent's `subagent` permission controls which agents it may launch.
The child currently uses its own configured permissions, not a restricted copy
of the parent's permissions.
## Configure agents
### Markdown files
@ -139,9 +104,40 @@ Review for correctness, security, regressions, and missing tests.
List findings in severity order with file and line references.
```
For compatibility with older layouts, V2 also discovers Markdown under
`agent/`, and treats files under `mode/` or `modes/` as primary agents. Prefer
`agents/` for new files.
### JSON or JSONC
Use the `agents` field in any [OpenCode configuration file](/config):
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"default_agent": "reviewer",
"agents": {
"reviewer": {
"description": "Reviews changes for correctness, security, and missing tests",
"mode": "all",
"model": "anthropic/claude-sonnet-4-5#high",
"system": "Review the current changes. Report findings before any summary.",
"color": "warning",
"steps": 8,
"permissions": [
{ "action": "edit", "resource": "*", "effect": "deny" },
{ "action": "shell", "resource": "*", "effect": "deny" }
]
},
"build": {
"permissions": [
{ "action": "shell", "resource": "git push *", "effect": "ask" }
]
}
}
}
```
Agent definitions merge in configuration order. Later scalar fields replace
earlier values, request maps merge by key, and permission rules are appended.
Global `permissions` are applied to every agent before its agent-specific rules,
so a later agent rule can refine a global rule.
## Options

View file

@ -1,6 +1,6 @@
---
title: "Attachments"
description: "Attach supported files and images to V2 prompts and configure image processing."
description: ""
---
OpenCode can add local context to a prompt as text or image media. Current V2

91
packages/docs/client.mdx Normal file
View file

@ -0,0 +1,91 @@
---
title: "Client"
description: "Connect an application to the OpenCode HTTP API."
---
`@opencode-ai/client` is the generated TypeScript client for the OpenCode HTTP
API. Use it when your application connects to an OpenCode server over the
network. Its types and methods are generated from the same contract as the
[API reference](/api).
<Warning>
The V2 API and client are beta. Method names, inputs, and outputs may change
before the stable release.
</Warning>
## Install
```sh
bun add @opencode-ai/client
```
The package has two entrypoints:
- `@opencode-ai/client/promise` uses `fetch` and returns Promises or async
iterables. It has no Effect runtime dependency.
- `@opencode-ai/client/effect` returns Effects and Streams, decodes values into
the V2 schema types, and requires an `HttpClient` service from Effect.
## Promise client
Create a client with the server URL, then call methods grouped by API resource:
```ts
import { OpenCode } from "@opencode-ai/client/promise"
const client = OpenCode.make({
baseUrl: "http://localhost:4096",
})
const session = await client.session.create({
location: { directory: "/workspace" },
})
await client.session.prompt({
sessionID: session.id,
text: "Review the current changes",
})
```
Pass default authentication or application headers to `OpenCode.make` with
`headers`. You can also supply a custom `fetch` implementation. Each operation
accepts request options as its final argument for an `AbortSignal` or
per-request headers.
Streaming endpoints return async iterables:
```ts
for await (const event of client.event.subscribe()) {
console.log(event.type)
}
```
## Effect client
Install the `effect` peer dependency when using the Effect entrypoint. The
client uses canonical V2 values such as `Location.Ref` and `Session.ID`, and
returns typed failures in the Effect error channel.
```ts
import { AbsolutePath, Location, OpenCode } from "@opencode-ai/client/effect"
import { Effect } from "effect"
import { FetchHttpClient } from "effect/unstable/http"
const program = Effect.gen(function* () {
const client = yield* OpenCode.make({ baseUrl: "http://localhost:4096" })
const session = yield* client.session.create({
location: Location.Ref.make({
directory: AbsolutePath.make("/workspace"),
}),
})
return yield* client.session.get({ sessionID: session.id })
})
const session = await Effect.runPromise(
program.pipe(Effect.provide(FetchHttpClient.layer)),
)
```
Streaming operations, including `client.event.subscribe()` and
`client.session.log(...)`, return Effect `Stream` values.

View file

@ -1,6 +1,6 @@
---
title: "Commands"
description: "Create reusable slash commands from configuration or Markdown files."
description: ""
---
Custom commands turn a named prompt template into a slash command. Type the
@ -10,45 +10,18 @@ command in the TUI, followed by any arguments:
/review src/auth
```
## Configure with JSON
Add commands under the plural `commands` key in any OpenCode JSON or JSONC
[configuration file](/config). Each entry's key is the command name and
`template` is required.
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"commands": {
"review": {
"description": "Review code for correctness and missing tests",
"template": "Review $ARGUMENTS. Report bugs first, then missing tests.",
"agent": "plan",
"model": "anthropic/claude-sonnet-4-5#high"
}
}
}
```
Run it with:
```text
/review src/auth
```
## Configure with Markdown
OpenCode discovers `.md` command files in both the singular `command/` and
plural `commands/` directories:
OpenCode discovers `.md` command files in `commands/` directories:
```text
~/.config/opencode/commands/ # Global
.opencode/commands/ # Project
```
The equivalent `command/` paths also work. Files may be nested; for example,
`.opencode/commands/team/review.md` defines `/team/review`. Files with other
extensions, including `.mdx`, are not discovered.
Files may be nested; for example, `.opencode/commands/team/review.md` defines
`/team/review`. Files with other extensions, including `.mdx`, are not
discovered.
```md title=".opencode/commands/review.md"
---
@ -66,6 +39,32 @@ precedence over global definitions, and a later definition can override a
built-in or earlier command with the same name. Changes are reloaded
automatically.
Run it with:
```text
/review src/auth
```
## Configure with JSON
Add commands under the `commands` key in any OpenCode JSON or JSONC
[configuration file](/config). Each entry's key is the command name and
`template` is required.
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"commands": {
"review": {
"description": "Review code for correctness and missing tests",
"template": "Review $ARGUMENTS. Report bugs first, then missing tests.",
"agent": "plan",
"model": "anthropic/claude-sonnet-4-5#high"
}
}
}
```
## Fields
| Field | Required | Behavior |

View file

@ -1,6 +1,6 @@
---
title: "Context compaction"
description: "Configure and run context compaction in OpenCode V2."
title: "Compaction"
description: ""
---
Compaction replaces the active model context from an older part of a session

View file

@ -1,6 +1,6 @@
---
title: "Config"
description: "Configure OpenCode."
description: ""
---
<Tip>

View file

@ -20,17 +20,13 @@
"groups": [
{
"group": "Get started",
"pages": ["index", "config", "troubleshooting"]
},
{
"group": "Migrate from V1",
"pages": ["migrate-v1"]
"pages": ["index", "migrate-v1", "config", "troubleshooting"]
},
{
"group": "Configure",
"pages": [
"models",
"providers",
"models",
"agents",
"permissions",
"sharing",
@ -43,15 +39,19 @@
"compaction",
"formatters",
"lsp",
"references",
"plugins"
"references"
]
}
]
},
{
"tab": "SDK",
"pages": ["sdk/index"]
"tab": "Build",
"groups": [
{
"group": "Build with OpenCode",
"pages": ["plugins", "client", "sdk/index"]
}
]
},
{
"tab": "API",

View file

@ -1,6 +1,6 @@
---
title: "Formatters"
description: "Configure formatter settings and understand formatter support in OpenCode V2."
description: ""
---
OpenCode V2 accepts formatter configuration, but it does not yet include a

View file

@ -156,7 +156,7 @@ Use `/undo` when a change isn't what you wanted.
OpenCode stages a conversation revert and restores your original message so you can revise it. In a Git repository, it
also restores file changes when snapshots were captured successfully. Run `/undo` multiple times to move the conversation
boundary back, or use `/redo` to restore the staged conversation and files. See [Snapshots and undo](/snapshots) for
boundary back, or use `/redo` to restore the staged conversation and files. See [Undo](/snapshots) for
limitations and safety details.
```text

View file

@ -1,6 +1,6 @@
---
title: "Instructions"
description: "Give OpenCode global, project, and directory-specific guidance."
description: ""
---
Instructions are privileged context that guide an agent throughout a session.

View file

@ -1,6 +1,6 @@
---
title: "LSP"
description: "Configure language servers and understand LSP support in OpenCode V2."
description: ""
---
Language Server Protocol (LSP) integrations can provide code diagnostics,

View file

@ -1,6 +1,6 @@
---
title: "MCP servers"
description: "Connect local and remote Model Context Protocol servers to OpenCode."
description: ""
---
OpenCode can connect to [Model Context Protocol](https://modelcontextprotocol.io/) servers and make their tools, prompts, and instructions available to agents. MCP tools consume model context, so enable only the servers you need.
@ -132,13 +132,21 @@ For a server that supports dynamic client registration, only the remote server i
}
```
When the server reports `needs authentication`, start the browser authorization flow:
When the server reports that it needs authentication, run `/connect` in the TUI:
```text
/connect
```
Select the MCP server under **Services**, then complete the browser authorization flow.
You can also authenticate from the command line:
```bash
opencode2 mcp auth sentry
```
The command prints the authorization URL and waits for the redirect to OpenCode's loopback callback server.
The CLI command prints the authorization URL and waits for the redirect to OpenCode's loopback callback server.
If the provider issued client credentials, configure them using V2's snake_case field names:

View file

@ -1,11 +1,25 @@
---
title: "Overview"
title: "Migrate from V1"
description: "Move from OpenCode V1 to the OpenCode 2.0 beta."
---
<Note>
The only intentional breaking changes in V2 are the server API and the plugin API. All other functionality is intended
to remain compatible with V1.
</Note>
Existing config files, agent definitions, command definitions, skills, and other files in `.opencode/` should continue to
work without changes. If one of these stops working in V2, treat it as a beta compatibility bug rather than an expected
migration requirement.
<Tip>
Run `/report` if existing V1 functionality does not work in V2. The report skill collects diagnostics and helps you file
a compatibility issue.
</Tip>
<Warning>
OpenCode 2.0 is in beta. Back up important configuration and data before migrating. Beta data may be wiped, features may
break, and configuration and plugin APIs may change.
OpenCode 2.0 is in beta. Beta data may be wiped, features may break unintentionally, and the server and plugin APIs may
continue to change.
</Warning>
During the beta, OpenCode V1 and V2 use different executable names. You can keep using `opencode` for V1 while trying V2
@ -25,9 +39,13 @@ Start it in your project with:
opencode2
```
## Back up your configuration
## Configuration
Before making changes, back up your global and project configuration files:
This section covers both JSON/JSONC configuration and file-based definitions under `.opencode/`.
### Use your existing configuration
V2 reads existing global and project configuration from the same locations as V1:
```text
~/.config/opencode/opencode.json(c)
@ -35,55 +53,467 @@ Before making changes, back up your global and project configuration files:
<project>/.opencode/opencode.json(c)
```
V2 reads these same locations. It detects V1-shaped configuration and translates supported fields in memory without
rewriting the source file. Keep shared files in their V1 shape while evaluating both versions; V1 does not understand the
native plural V2 fields and may silently ignore them.
V2 reads these same locations. It detects V1-shaped configuration and translates it in memory without rewriting the
source file. Existing V1 configuration is intended to keep working, so you do not need to convert it to try or adopt V2.
## Update configuration
### Ask OpenCode to migrate
Automatic translation is a compatibility aid, not a guarantee that every V1 setting behaves identically. Convert your
configuration to the native V2 shape only when you no longer need V1 to read those same files.
The V1 config format remains supported. The native V2 format is optional and makes several settings more explicit and
ergonomic.
<Note>
Do not mix V1 and V2 field names in one file. Back up the V1 file, update the complete working file to the V2 shape, and
validate it against the current schema. Restore the V1 copy before using V1 again.
</Note>
The recommended migration path is to ask OpenCode to update the configuration for you:
The main field changes are:
```text
Migrate my OpenCode configuration, including file-based definitions, from the V1 format to the native V2 format.
Preserve its behavior and all unrelated settings.
```
| V1 | V2 |
| --- | --- |
| `permission` | `permissions` |
| `agent` and `mode` | `agents` |
| `snapshot` | `snapshots` |
| `attachment` | `attachments` |
| `command` | `commands` |
| `reference` | `references` |
| `plugin` | `plugins` |
| `provider` | `providers` |
| Servers directly under `mcp` | Servers under `mcp.servers` |
| `skills.paths` and `skills.urls` | A single `skills` array |
OpenCode can inspect the complete file, apply the relevant changes below, and avoid rewriting settings that do not need to
change. Do not mix V1 and V2 field names manually in one file.
### Sharing
The deprecated V1 `autoshare` boolean becomes the explicit `share` policy:
```jsonc
// V1
{ "autoshare": true }
// V2
{ "share": "auto" }
```
Use `"manual"`, `"auto"`, or `"disabled"`. If the V1 file already uses `share`, no change is needed.
### Permissions and tools
V1 groups permission effects by tool. V2 uses one ordered `permissions` array, making precedence and exceptions explicit:
```jsonc
// V1
{
"permission": {
"bash": {
"git push *": "ask"
},
"edit": "allow"
},
"tools": {
"websearch": false
}
}
// V2
{
"permissions": [
{ "action": "shell", "resource": "git push *", "effect": "ask" },
{ "action": "edit", "resource": "*", "effect": "allow" },
{ "action": "websearch", "resource": "*", "effect": "deny" }
]
}
```
Permission actions also changed: `bash` is now `shell`, `task` is now `subagent`, and `write` and `patch` are now `edit`.
See [Permissions](/permissions) for the ordered V2 rule format.
V1-only fields including `logLevel`, `server`, `layout`, `disabled_providers`, `enabled_providers`, and `small_model` are
not carried into the native V2 configuration. Remove them and use the current [Config](/config) and
[Providers](/providers) guides to configure their replacements where applicable.
### Agents and modes
## Review extensions
The singular `agent` and deprecated `mode` maps become `agents`. Agent fields become more consistent with the rest of the
V2 config:
V2 continues to discover file-based agents, commands, and skills from OpenCode configuration directories. Their schemas
have changed, so review each extension against the current [Agents](/agents), [Commands](/commands), and
[Skills](/skills) guides.
```jsonc
// V1
{
"agent": {
"reviewer": {
"prompt": "Review for correctness and missing tests.",
"model": "anthropic/claude-sonnet-4-5",
"variant": "high",
"disable": false,
"permission": {
"edit": "deny"
}
}
}
}
<Warning>
V1 plugins are not guaranteed to work with V2. The plugin API is changing during beta; review and port each plugin using
the [V2 plugin guide](/plugins).
</Warning>
// V2
{
"agents": {
"reviewer": {
"system": "Review for correctness and missing tests.",
"model": "anthropic/claude-sonnet-4-5#high",
"disabled": false,
"permissions": [
{ "action": "edit", "resource": "*", "effect": "deny" }
]
}
}
}
```
`prompt` becomes `system`, `disable` becomes `disabled`, and a separate `variant` joins the model reference after `#`.
`temperature`, `top_p`, and provider-specific `options` move under `request.body`. `maxSteps` becomes `steps`. Entries from
the old `mode` map become primary agents.
### Snapshots
Rename the singular `snapshot` field to `snapshots`. Its boolean value does not change:
```jsonc
// V1
{ "snapshot": false }
// V2
{ "snapshots": false }
```
### Attachments
Rename the singular `attachment` object to `attachments`. Nested image settings keep the same names:
```jsonc
// V1
{ "attachment": { "image": { "auto_resize": true } } }
// V2
{ "attachments": { "image": { "auto_resize": true } } }
```
### MCP servers
V2 groups servers under `mcp.servers`, replaces `enabled` with the inverse `disabled`, and separates timeout purposes:
```jsonc
// V1
{
"mcp": {
"playwright": {
"type": "local",
"command": ["npx", "@playwright/mcp"],
"enabled": true,
"timeout": 30000
}
}
}
// V2
{
"mcp": {
"servers": {
"playwright": {
"type": "local",
"command": ["npx", "@playwright/mcp"],
"disabled": false,
"timeout": {
"catalog": 30000,
"execution": 30000
}
}
}
}
}
```
Remote OAuth fields use snake case: `clientId` becomes `client_id`, `clientSecret` becomes `client_secret`,
`callbackPort` becomes `callback_port`, and `redirectUri` becomes `redirect_uri`. The V1 `experimental.mcp_timeout` value
also becomes the default `mcp.timeout.catalog` and `mcp.timeout.execution` values. See [MCP servers](/mcp).
### Compaction
V2 groups the retained-context token budget under `keep` and gives the reserve a clearer name:
```jsonc
// V1
{
"compaction": {
"preserve_recent_tokens": 8000,
"reserved": 20000
}
}
// V2
{
"compaction": {
"keep": {
"tokens": 8000
},
"buffer": 20000
}
}
```
`auto` and `prune` keep their names. V2 has no native `tail_turns` field; recent context is retained by token budget instead.
See [Compaction](/compaction).
### Skills
V1 separates extra skill paths and URLs. V2 combines both into one ordered array:
```jsonc
// V1
{
"skills": {
"paths": ["./team-skills"],
"urls": ["https://example.com/skills/"]
}
}
// V2
{
"skills": ["./team-skills", "https://example.com/skills/"]
}
```
Existing skill files and automatic `.opencode/skills/` discovery do not change. See [Skills](/skills).
### Commands
Rename the singular `command` map to `commands`. Join a separate model `variant` to the model reference:
```jsonc
// V1
{
"command": {
"review": {
"template": "Review the current changes.",
"model": "anthropic/claude-sonnet-4-5",
"variant": "high"
}
}
}
// V2
{
"commands": {
"review": {
"template": "Review the current changes.",
"model": "anthropic/claude-sonnet-4-5#high"
}
}
}
```
`template`, `description`, `agent`, and `subtask` keep their names. Existing Markdown command definitions remain supported.
See [Commands](/commands).
### References
Rename the deprecated singular `reference` map to `references`:
```jsonc
// V1
{ "reference": { "docs": "../docs" } }
// V2
{ "references": { "docs": "../docs" } }
```
V1 already accepts `references`, so no change is needed when the file uses it. Reference entries keep the
same shapes. See [References](/references).
### Providers
Rename the singular `provider` map to `providers`. V2 separates the runtime package, endpoint, and request settings:
```jsonc
// V1
{
"provider": {
"acme": {
"npm": "@ai-sdk/openai-compatible",
"api": "https://llm.example.com/v1",
"options": {
"apiKey": "{env:ACME_API_KEY}"
}
}
}
}
// V2
{
"providers": {
"acme": {
"package": "aisdk:@ai-sdk/openai-compatible",
"settings": {
"baseURL": "https://llm.example.com/v1",
"apiKey": "{env:ACME_API_KEY}"
}
}
}
}
```
V1 `npm` becomes `package`, and AI SDK packages receive the `aisdk:` prefix. `api` becomes `settings.baseURL`. Provider
`options` are separated into `settings`, `headers`, and `body` according to their request role. See [Providers](/providers).
### Models and variants
Models remain nested under their provider, but several model fields become more explicit:
- `id` becomes `modelID`.
- `tool_call` and `modalities` become `capabilities.tools`, `capabilities.input`, and `capabilities.output`.
- A `status` of `"deprecated"` becomes `disabled: true`.
- Cache costs move from `cache_read` and `cache_write` to `cache.read` and `cache.write`.
- Provider-specific `options` become `settings`.
- A V1 variants object becomes a V2 array with an `id` on each entry.
```jsonc
// V1
{
"variants": {
"high": {
"reasoningEffort": "high"
}
}
}
// V2
{
"variants": [
{
"id": "high",
"settings": {
"reasoningEffort": "high"
}
}
]
}
```
See [Models](/models) for the complete native model shape.
### Fields without native equivalents
Most fields that keep the same shape, including `shell`, `model`, `default_agent`, `autoupdate`, `watcher`, `formatter`,
`lsp`, `instructions`, `enterprise`, and `tool_output`, require no migration.
These V1 fields do not have one-to-one native V2 config fields:
- `logLevel`: use `OPENCODE_LOG_LEVEL` when starting OpenCode.
- `server`: use the V2 service and explicit server options; the server API is an intentional breaking change.
- `layout`: remove it; V1 already treated it as deprecated and always used stretch layout.
- `enabled_providers` and `disabled_providers`: there is no native provider allowlist or denylist field yet.
- `small_model`: V2 selects models for internal maintenance agents without a separate top-level field.
- `compaction.tail_turns`: V2 uses `compaction.keep.tokens` instead.
If your V1 configuration relies on a field without a native equivalent, keep using the supported V1 format rather than
forcing a manual conversion. Run `/report` if V2 does not preserve the behavior you rely on.
### Agent files
V1 agent files may use `agent/`, `agents/`, `mode/`, or `modes/`. V2 still discovers all four directories. The preferred
V2 location is:
```text
.opencode/agents/<name>.md
```
Files under a V1 `mode/` or `modes/` directory represent primary agents. When moving one into `agents/`, add
`mode: primary` to its frontmatter. Files under `agent/` can move to `agents/` without changing their path-derived ID.
When converting the frontmatter to native V2 fields:
- Keep the Markdown body as the agent's system instructions.
- Rename `prompt` to `system` when it appears in JSON configuration; file bodies do not need a `system` field.
- Rename `disable` to `disabled` and `permission` to `permissions`.
- Join `model` and `variant` as `provider/model#variant`.
- Move `temperature`, `top_p`, and provider-specific options under `request.body`.
V2 translates legacy agent frontmatter automatically, so these edits are optional. See [Agents](/agents).
### Command files
V1 command files may use `command/` or `commands/`. V2 discovers both. The preferred location is:
```text
.opencode/commands/<name>.md
```
Move files from `command/` to the same relative path under `commands/` to preserve command names. The Markdown body remains
the command template, and `description`, `agent`, and `subtask` frontmatter keep the same names. If frontmatter has separate
`model` and `variant` fields, append the variant to the model and remove `variant`:
```yaml
# V1
model: anthropic/claude-sonnet-4-5
variant: high
# V2
model: anthropic/claude-sonnet-4-5#high
```
See [Commands](/commands).
### Skill files
V2 discovers skills from both `.opencode/skill/` and `.opencode/skills/`. The preferred layout is:
```text
.opencode/skills/<skill-id>/SKILL.md
```
Move the complete skill directory, not only `SKILL.md`, so relative scripts, references, and other supporting files remain
available. Keep the directory name stable to preserve the skill ID. Existing skill frontmatter and Markdown bodies do not
require a V2 rewrite. See [Skills](/skills).
### Instruction files
Existing `AGENTS.md` files stay in place. V2 discovers the global `~/.config/opencode/AGENTS.md` and project `AGENTS.md`
files from the current directory up to the project root.
If a V1 setup relied on a `CLAUDE.md` fallback, move that guidance into the applicable `AGENTS.md`. V2 currently only
discovers `AGENTS.md`; because non-API V1 behavior is intended to remain compatible, also run `/report` with the affected
project details. See [Instructions](/instructions).
## Plugins
Rename `plugin` to `plugins`. Replace a package-and-options tuple with an object:
```jsonc
// V1
{
"plugin": [
"opencode-example-plugin",
["./plugin/local.ts", { "enabled": true }]
]
}
// V2
{
"plugins": [
"opencode-example-plugin",
{
"package": "./plugin/local.ts",
"options": { "enabled": true }
}
]
}
```
V2 discovers local plugins from both `.opencode/plugin/` and `.opencode/plugins/`; use `.opencode/plugins/` for V2 files.
Moving a file between these directories does not migrate its implementation.
<Warning>V1 plugins will not work in V2.</Warning>
The config entry can be translated automatically, but plugin implementation code must be ported to the new API. The V2
plugin API is still being finalized during beta, and detailed plugin migration guidance will be published when it is
ready.
Once the V2 plugin API is finalized, OpenCode should be able to migrate the majority of V1 plugins while keeping related
local modules and dependencies together. See the current beta [Plugins guide](/plugins).
## Server API and clients
OpenCode 2 has a revised, more ergonomic server API and a new set of clients. Integrations that call the V1 server API
must migrate to the V2 API.
Use the `@opencode-ai/client` package to access the new clients. The server API and clients are still being finalized
during beta, so their contracts may continue to change. See the generated [API reference](/api) for the current endpoints,
request types, and responses.
## Verify your setup
Start `opencode2` in a project and verify your model, provider credentials, agents, permissions, MCP servers, and plugins
before relying on the beta for regular work. Keep your V1 setup and backups until you have confirmed the V2 behavior you
need, and do not point V1 at configuration that you have converted to the native V2 shape.
before relying on the beta for regular work. Keep your V1 setup until you have confirmed the V2 behavior you need, and do
not point V1 at configuration that you have converted to the native V2 shape.

View file

@ -1,49 +1,43 @@
---
title: "Models"
description: "Select, configure, and customize models in OpenCode 2.0."
description: ""
---
OpenCode builds its model catalog from [Models.dev](https://models.dev), provider integrations, and your configuration.
Only enabled models whose provider is available for the current project appear in the model picker.
Connect a provider with `/connect` in the TUI, or configure a provider and its credentials in `opencode.json`.
Connect a provider with `/connect` in the TUI, or configure it in [Providers](/providers).
## Select a model
## Choose a model
Open the model picker with `/models` or the default `<leader>m` keybind. Use `/variants` to choose a variant for the
current model, or press `ctrl+t` to cycle through its variants.
Open the model picker with `/models` or the default `<leader>m` keybind. The picker shows the models available from
providers connected to the current project.
A model reference has this form:
Select a model to use it in the current session. Switching models updates that session without changing your config. Use
the catalog entries shown in the picker rather than guessing a provider or model name.
```text
provider/model#variant
```
## Per-run model
The variant is optional. OpenCode splits at the first `/`, so model IDs may contain additional slashes:
```text
openai/gpt-5.2
openai/gpt-5.2#high
openrouter/anthropic/claude-sonnet-4.5#high
```
Use the catalog IDs shown by `/models`, not a provider's display name. Omit `#variant` to use the model's base settings.
### Command line
Select a model for a non-interactive run with `--model` or `-m`:
Select a model for one non-interactive run with `--model` or `-m`:
```bash
opencode2 run --model openai/gpt-5.2 "Explain this repository"
opencode2 run -m openai/gpt-5.2#high "Review the current changes"
```
<Note>
`opencode2 run` accepts `provider/model#variant`. The current `opencode2 mini --model` option accepts only
`provider/model`; choose its variant from the interactive interface.
</Note>
Agents and commands can also select their own model. See [Agents](/agents) and [Commands](/commands).
## Set the default
## Variants
Variants are named request overlays for one model, commonly used for reasoning effort or token budgets. Available names
are model-specific and are derived from current catalog metadata. Do not assume that names such as `low`, `high`, or
`max` exist for every model; `/variants` shows the valid choices.
Use `/variants` to choose one for the current model, or press `ctrl+t` to cycle through available variants.
## Configure
### Default model
Set `model` in `opencode.json` or `opencode.jsonc`:
@ -54,81 +48,13 @@ Set `model` in `opencode.json` or `opencode.jsonc`:
}
```
The explicit object form is equivalent:
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"model": {
"providerID": "openrouter",
"model": "anthropic/claude-sonnet-4.5"
}
}
```
Root, agent, and command `model` fields accept these same selection forms. See [Config](/config) for configuration
locations and precedence.
The configured model becomes the catalog default when its provider is available and the model is enabled. Otherwise,
session execution falls back to the newest available supported model. An explicit model already selected on a session
takes precedence over the default; switching models changes that session and does not rewrite your config.
## Variants
See [Config](/config) for configuration locations and precedence.
Variants are named request overlays for one model, commonly used for reasoning effort or token budgets. Available names
are model-specific and are derived from current catalog metadata. Do not assume that names such as `low`, `high`, or
`max` exist for every model; `/variants` shows the valid choices.
Add a variant, or override a catalog variant with the same ID, under the model's `variants` array:
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"providers": {
"openai": {
"models": {
"gpt-5.2": {
"settings": {
"reasoningEffort": "medium"
},
"variants": [
{
"id": "fast",
"settings": {
"reasoningEffort": "low"
}
},
{
"id": "deep",
"settings": {
"reasoningEffort": "high",
"reasoningSummary": "auto"
}
}
]
}
}
}
},
"commands": {
"deep-review": {
"description": "Review with high reasoning effort",
"template": "Review the current changes for correctness and missing tests.",
"model": "openai/gpt-5.2#deep"
}
}
}
```
Variant entries support `settings`, `headers`, and `body`. Selecting one deeply overlays its values on the effective
provider and model configuration. An unknown variant fails model resolution instead of silently using the base model.
<Warning>
V2 uses `providers` (plural) and an array of `{ "id": "..." }` variant entries. The V1 `provider` key and
object-shaped `variants` configuration are not the V2 format.
</Warning>
## Configure a model
### Model settings
Provider and model entries can supply three kinds of request configuration:
@ -172,7 +98,46 @@ Here `openai/coding-default` is the selectable catalog reference, while `gpt-5.2
model that is not already in the catalog, set accurate `capabilities` and `limit` values so OpenCode can expose tools and
enforce the correct context limits. Set `disabled: true` on a model entry to hide it from the available catalog.
## Local and compatible models
### Custom variants
Add a variant, or override a catalog variant with the same ID, under the model's `variants` array:
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"providers": {
"openai": {
"models": {
"gpt-5.2": {
"settings": {
"reasoningEffort": "medium"
},
"variants": [
{
"id": "fast",
"settings": {
"reasoningEffort": "low"
}
},
{
"id": "deep",
"settings": {
"reasoningEffort": "high",
"reasoningSummary": "auto"
}
}
]
}
}
}
}
}
```
Variant entries support `settings`, `headers`, and `body`. Selecting one deeply overlays its values on the effective
provider and model configuration. An unknown variant fails model resolution instead of silently using the base model.
### Local models
For an OpenAI-compatible server, define a provider package, endpoint, and at least one model:
@ -210,9 +175,34 @@ Use the server's real model name, limits, modalities, and tool support. OpenCode
manually. If the endpoint requires a key, add `apiKey` to provider `settings` using an environment substitution such as
`"apiKey": "{env:LOCAL_API_KEY}"`; do not commit secrets.
## Caveats
### Model references
Configuration and CLI options identify a model as `provider/model`, with an optional `#variant`:
```text
openai/gpt-5.2
openai/gpt-5.2#high
openrouter/anthropic/claude-sonnet-4.5#high
```
OpenCode splits the reference at the first `/`, so model IDs may contain additional slashes. Provider and model IDs are
case-sensitive. Provider IDs cannot contain `/` or `#`, and model IDs cannot contain `#`.
The expanded config form is equivalent when generated or programmatic configuration is more convenient:
```jsonc
{
"model": {
"providerID": "openrouter",
"model": "anthropic/claude-sonnet-4.5"
}
}
```
Root, agent, and command `model` fields accept both forms. Use the IDs shown by `/models`, not provider display names.
### Caveats
- Provider and model IDs are case-sensitive. Provider IDs cannot contain `/` or `#`; model IDs cannot contain `#`.
- The selector object uses `model`, while a provider catalog entry uses `modelID` for the upstream API identifier.
- The root `model` currently sets the default provider and model only. Although its selection shape accepts a variant,
the V2 catalog default does not retain it; select a variant in the TUI, with `opencode2 run`, or on an agent or command.

View file

@ -1,10 +1,10 @@
---
title: "Permissions"
description: "Configure ordered V2 rules for tool access, approvals, and agent overrides."
description: ""
---
Permissions control whether an agent may perform an action on a resource. V2
configuration uses the plural `permissions` field and an ordered array of rules.
configuration uses the `permissions` field and an ordered array of rules.
<Warning>
The V1 object syntax uses different field and action names. Do not use

View file

@ -22,7 +22,7 @@ function.
### Configuration
Add ordered entries to the plural `plugins` field in `opencode.json(c)`:
Add ordered entries to the `plugins` field in `opencode.json(c)`:
```jsonc title="opencode.jsonc"
{
@ -57,21 +57,19 @@ precedence rather than replacing the entire array.
### Local discovery
OpenCode automatically scans both of these directories in every discovered
OpenCode config directory:
OpenCode automatically scans this directory in every discovered OpenCode config
directory:
```text
.opencode/plugin/
.opencode/plugins/
```
The equivalent global directories are
`~/.config/opencode/plugin/` and `~/.config/opencode/plugins/`. Direct `.ts` and
`.js` children are loaded. An immediate child directory is also loaded as a
The equivalent global directory is `~/.config/opencode/plugins/`. Direct `.ts`
and `.js` children are loaded. An immediate child directory is also loaded as a
package when OpenCode can resolve a string `exports`, `module`, or `main`
entrypoint, or an `index.ts` or `index.js` file.
A `plugin/` directory beside a project-root `opencode.json` is not discovered
A `plugins/` directory beside a project-root `opencode.json` is not discovered
automatically. Put it under `.opencode/`, or add its file explicitly with a
relative config entry.
@ -86,7 +84,7 @@ applied in order:
"plugins": [
"-opencode.provider.*",
"opencode.provider.openai",
"-./plugin/old.ts",
"-./plugins/old.ts",
"-*",
"./plugins/only-this-one.ts"
]

View file

@ -1,6 +1,6 @@
---
title: "Providers"
description: "Connect LLM providers and configure endpoints, packages, models, and variants."
description: ""
---
OpenCode builds its provider and model catalog from [Models.dev](https://models.dev), then applies the `providers`
@ -57,7 +57,7 @@ When several credential sources exist, OpenCode uses the stored credential first
<Warning>Do not commit API keys or authorization headers to your repository.</Warning>
## Configure providers
## Configure
The `providers` object is keyed by provider ID. Each provider accepts these fields:
@ -75,7 +75,7 @@ Configuration files are applied from lowest to highest precedence. `settings` an
merged case-insensitively. At request time, provider values are inherited by the model, model values override them, and
the selected variant is applied last.
### Custom endpoint
### Endpoint
Override `settings.baseURL` to send an existing provider through a proxy or compatible endpoint. Its existing package,
models, and connection continue to apply:
@ -95,7 +95,7 @@ models, and connection continue to apply:
`settings` is package-specific. A field only has an effect when the selected package supports it.
### Custom headers and body
### Headers and body
Headers and body fields can be set at provider, model, or variant scope:
@ -127,7 +127,7 @@ Headers and body fields can be set at provider, model, or variant scope:
These are request overlays, not a generic authentication scheme. Prefer `/connect`, `env`, or `settings.apiKey` for
provider credentials unless the endpoint explicitly requires a custom header.
## Custom providers and packages
### Provider packages
For an OpenAI-compatible service, use the V2 native compatible package. The model map is explicit because a custom
provider has no Models.dev catalog entries:
@ -179,10 +179,10 @@ not validate package-specific keys.
`package` may also be set on one model to override the provider package for that model.
## Models
### Models
`models` adds a model or overlays an existing catalog model. The object key is the model ID used in OpenCode. Set
`modelID` when the upstream API expects a different ID:
Add a model under a provider's `models` map. The object key is the model ID used in OpenCode; `modelID` is the ID sent to
the provider:
```jsonc title="opencode.jsonc"
{
@ -193,13 +193,7 @@ not validate package-specific keys.
"models": {
"coding": {
"modelID": "gpt-5.2",
"name": "GPT-5.2 Coding",
"family": "gpt-5",
"limit": {
"context": 200000,
"input": 180000,
"output": 32000
}
"name": "GPT-5.2 Coding"
}
}
}
@ -207,66 +201,4 @@ not validate package-specific keys.
}
```
A model supports `modelID`, `family`, `name`, `package`, `settings`, `headers`, `body`, `capabilities`, `variants`,
`cost`, `disabled`, and `limit`. If supplied, `capabilities` requires `tools`, `input`, and `output`. `limit` may set
`context`, `input`, and `output`. Cost values are USD per million tokens:
```jsonc
{
"cost": {
"input": 3,
"output": 15,
"cache": {
"read": 0.3,
"write": 3.75
}
}
}
```
Set `disabled: true` on a model to remove it from the available model list. V2 does not define provider-level
whitelist or blacklist fields.
## Variants
Variants are named request overlays for one model. They can override `settings`, `headers`, and `body`; the selected
package determines which values are meaningful.
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"providers": {
"openai": {
"models": {
"gpt-5.2": {
"variants": [
{
"id": "fast",
"settings": {
"reasoningEffort": "low"
}
},
{
"id": "deep",
"settings": {
"reasoningEffort": "high",
"reasoningSummary": "auto"
}
}
]
}
}
}
}
}
```
Choose a variant with the TUI variant picker or `/variants`. Explicit CLI, agent, and command model references use
`provider/model#variant`; for example:
```bash
opencode2 run --model openai/gpt-5.2#deep "Review this project"
```
The current V2 top-level `model` default does not retain a `#variant` selection, so choose the variant separately.
Selecting an ID that is not defined for the model fails instead of silently using the default request settings.
See [Models](/models) for model selection, defaults, capabilities, limits, costs, and variants.

View file

@ -1,6 +1,6 @@
---
title: "References"
description: "Make local directories and Git repositories available as project context."
description: ""
---
References give OpenCode named access to directories outside the current

View file

@ -1,4 +1,75 @@
---
title: "SDK"
description: "Build with OpenCode."
description: "Embed an OpenCode host in an Effect application."
---
`@opencode-ai/sdk-next` is the Effect-native SDK for applications that need to
host OpenCode in-process. Unlike the [network client](/client), it assembles the
OpenCode server and routes API calls through its HTTP router in memory. It opens
no HTTP listener and adds no network hop between the client and server.
<Warning>
The V2 SDK is beta and currently private to the OpenCode workspace. It is not
published for external installation yet, and its package name and API may
change before release.
</Warning>
## Create a host
`OpenCode.create()` creates a scoped host. Closing its Effect Scope releases
the router, location services, fibers, and scoped plugin registrations.
```ts
import {
AbsolutePath,
Location,
OpenCode,
} from "@opencode-ai/sdk-next"
import { Effect } from "effect"
const program = Effect.scoped(
Effect.gen(function* () {
const opencode = yield* OpenCode.create()
const session = yield* opencode.sessions.create({
location: Location.Ref.make({
directory: AbsolutePath.make("/workspace"),
}),
})
return yield* opencode.sessions.get({ sessionID: session.id })
}),
)
const session = await Effect.runPromise(program)
```
The embedded host uses the same routes, middleware, codecs, errors, and schema
values as `@opencode-ai/client/effect`. It exposes the full generated client and
adds the convenience aliases `sessions` and `events` for the session and event
groups.
## Use as a service
Use `OpenCode.layer` when the host should be provided through Effect dependency
injection:
```ts
import { OpenCode } from "@opencode-ai/sdk-next"
import { Effect } from "effect"
const program = Effect.gen(function* () {
const opencode = yield* OpenCode.Service
return yield* opencode.sessions.active()
})
const active = await Effect.runPromise(
program.pipe(Effect.provide(OpenCode.layer)),
)
```
## Register plugins
Call `opencode.plugin(...)` to register an embedded V2 plugin. Embedded plugins
use the same discovery and location-scoped activation path as configured
plugins. The SDK also exports `Tool` for plugin-defined tools. See the
[Plugins guide](/plugins) for the plugin shape and available hooks.

View file

@ -1,6 +1,6 @@
---
title: "Session sharing"
description: "Understand the current beta status of session sharing in OpenCode V2."
description: ""
---
Session sharing is not yet available in OpenCode V2. V2 does not currently

View file

@ -1,6 +1,6 @@
---
title: "Skills"
description: "Add reusable, on-demand instructions to OpenCode."
description: ""
---
Skills are Markdown instructions that OpenCode can advertise to an agent and
@ -45,9 +45,9 @@ OpenCode automatically adds the following source directories:
| Scope | Sources |
| --- | --- |
| Global | `~/.config/opencode/skill`, `~/.config/opencode/skills` |
| Global | `~/.config/opencode/skills` |
| Global compatibility | `~/.claude/skills`, `~/.agents/skills` |
| Project | `.opencode/skill`, `.opencode/skills` |
| Project | `.opencode/skills` |
| Project compatibility | `.claude/skills`, `.agents/skills` |
For project sources, OpenCode searches from the current directory upward to
@ -166,12 +166,11 @@ wins. Sources are registered in this order, from lower to higher precedence:
1. Built-in skills
2. `.claude/skills` sources, global first and then from the current directory upward
3. `.agents/skills` sources, global first and then from the current directory upward
4. `~/.config/opencode/skill` and `~/.config/opencode/skills`
5. Project `.opencode/skill` and `.opencode/skills`, from the project root toward the current directory
4. `~/.config/opencode/skills`
5. Project `.opencode/skills`, from the project root toward the current directory
6. Explicit `skills` config entries, in config priority and array order
Within one `.opencode` directory, `skills` has precedence over `skill`. Avoid
duplicate IDs unless an override is intentional.
Avoid duplicate IDs unless an override is intentional.
## Runtime loading

View file

@ -1,6 +1,6 @@
---
title: "Snapshots and undo"
description: "Understand filesystem snapshots, undo, redo, and message reverts in OpenCode V2."
title: "Undo"
description: ""
---
OpenCode snapshots let the default interactive TUI roll back conversation history and related file changes. They are a
@ -104,6 +104,5 @@ Review the staged file summary and your Git diff before continuing. Commit or ba
using undo on a dirty worktree.
<Note>
`/undo` and `/redo` are interactive commands in the default V2 TUI. The non-interactive `run` command and the minimal
interactive interface do not provide these slash commands.
`/undo` and `/redo` are interactive TUI commands. The non-interactive `run` command does not provide them.
</Note>