# OpenCode Guide: Open-Source Alternative to Claude Code

> What OpenCode is, how to install it, connect cloud and local models via Ollama, and set up agents, permissions, and MCP. How it compares to Claude Code.
> Author: Roman Belov · Published: 2026-10-30 · Source: https://futurecraft.pro/blog/opencode-guide/

OpenCode is an open-source coding agent under the MIT license. It runs in the terminal, as a desktop app, or as an IDE extension. It reads your project, edits files, and runs commands. The main difference from Claude Code is the models: OpenCode connects to 75+ providers through the [AI SDK](https://opencode.ai/docs/providers), including local models in Ollama, LM Studio, and llama.cpp.

Vendor independence has a price. You write the config for a local model by hand, default permissions are broad, and the quality of the work depends entirely on the model you pick. On top of that, as of November 2026 the project has two parallel versions, OpenCode 1 and OpenCode 2, with different install commands.

This guide covers installing OpenCode, connecting cloud and local models, and setting up agents, permissions, and MCP, plus how it differs from Claude Code. At the end is a test of local models through Ollama on OpenCode 1.15.11: what worked and what broke. Everything else is based on the documentation as of November 6, 2026.

## What is OpenCode

The project lives on GitHub at [anomalyco/opencode](https://github.com/anomalyco/opencode) under the MIT license. The old address `github.com/sst/opencode` returns a 301 redirect to the new one. As of November 6, 2026, the repository has about 225K stars and 30K forks.

There are three interfaces: a terminal TUI, a desktop app (marked beta in the README), and an IDE extension. There's also a non-interactive mode: `opencode run "task"` runs a single task and exits, which is how OpenCode fits into scripts and CI. Provider keys added through `/connect` are stored in `~/.local/share/opencode/auth.json`.

### OpenCode 1 and OpenCode 2

Two lines are in active development. The GitHub API marks v1.19.5 from October 28, 2026 as the latest release, while the v2 line ships in parallel: v2.2.5 came out on October 30. Both versions install the `opencode` command and can't coexist under that name. The V2 installer replaces the V1 binary.

The [migration guide](https://opencode.ai/v2/docs/migrate-v1/) lists three intentional breaking changes in V2: a new plugin API, new server API contracts, and terminal client settings moved from `tui.json` into a single global `cli.json`. V2 reads the old config from the same locations and converts it to the new format in memory without rewriting the file. The native V2 format is optional, and its keys are renamed: `agent` becomes `agents`, `permission` becomes a `permissions` array, and MCP servers move to `mcp.servers`.

This guide describes OpenCode 1 and its config format. Per the migration guide, that format also works in V2. One behavioral difference in V2 affects security: by default, V2 doesn't ask before accessing paths outside the project.

## Installing OpenCode

### macOS and Linux

The commands differ between the two versions. For OpenCode 1, the [documentation](https://opencode.ai/docs) lists these options:

```bash
# OpenCode 1
curl -fsSL https://opencode.ai/install | bash
npm install -g opencode-ai
brew install anomalyco/tap/opencode
```

For OpenCode 2, the commands come from the [README](https://github.com/anomalyco/opencode) and the [v2 docs](https://opencode.ai/v2/docs):

```bash
# OpenCode 2
curl -fsSL https://opencode.ai/v2/install | bash
npm install -g @opencode/cli
brew install anomalyco/tap/opencode-v2
```

The formula in core Homebrew, `brew install opencode`, is called official in the README but is updated less often. The V1 docs add that it currently installs V2, so V1 needs the `anomalyco/tap` tap. On Arch, the `opencode` package from the official repository also installs V2. The install script puts the binary in `$HOME/.opencode/bin`, and you need to add that directory to your `PATH`.

Homebrew had one more surprise in the test environment. `brew upgrade opencode` refused to load the formula from a third-party tap with the message `Refusing to load formula anomalyco/tap/opencode from untrusted tap` and suggested marking the tap as trusted. That changes Homebrew's trust settings, so make that call deliberately.

### Windows

For OpenCode 1, the docs recommend WSL. Native options are Chocolatey (`choco install opencode`), Scoop (`scoop install opencode`), npm (`npm install -g opencode-ai`), and Docker (`docker run -it --rm ghcr.io/anomalyco/opencode`). OpenCode 2 doesn't support Windows package managers. The v2 docs link to standalone binaries for x64 and ARM64.

### Verifying the install

```bash
opencode --version
```

If the command isn't found after a script install, check that `$HOME/.opencode/bin` is in your `PATH` and open a new terminal.

## First run

Start OpenCode in your project directory:

```bash
cd ~/projects/my-app
opencode
```

First, connect a provider with `/connect` (more on that in the next section). Then run `/init`: OpenCode analyzes the project and creates `AGENTS.md` in the root. The docs recommend committing this file. The agent keeps the description of the project's structure and conventions in it. How that format works and how it fits with CLAUDE.md is covered in the [AGENTS.md guide](https://futurecraft.pro/blog/agents-md-guide/).

A few things you'll need right away:

- `@` in the prompt opens fuzzy search over project files. The selected file goes into context.
- Tab switches the primary agent between Build and Plan. Plan doesn't edit code and is meant for discussing a plan.
- `/undo` reverts the latest changes and restores your original message, and you can repeat it several times. `/redo` brings the reverted changes back.
- `/models` lists the models of connected providers.

## Connecting models

In the config, a model is written as `provider/model`, for example `anthropic/claude-sonnet-5-5`. A separate `small_model` key handles lightweight tasks such as generating session titles. If it isn't set, OpenCode tries a cheaper model from the same provider and otherwise falls back to the main one.

### Cloud providers

Cloud providers need almost no config. `/connect` in the TUI shows the provider list, asks for a key, and saves it. The [provider list](https://opencode.ai/docs/providers) includes Anthropic, OpenAI, Amazon Bedrock, Google Vertex AI, Azure OpenAI, OpenRouter, GitHub Copilot, Groq, DeepSeek, xAI, Together AI, Ollama Cloud, and dozens more. For how OpenRouter routes requests and what it charges, see the [OpenRouter guide](https://futurecraft.pro/blog/openrouter-guide/).

Some providers support subscriptions. Per the OpenCode docs, ChatGPT Plus/Pro (browser sign-in), GitHub Copilot, and GitLab Duo work with no extra setup. The OpenCode team also sells model access through its own OpenCode Models and OpenCode Go providers (per the v2 docs, Go is a $10/month subscription). Both are optional.

Claude models are a different story. The OpenCode docs state plainly that plugins exist for using a Claude Pro/Max subscription, that Anthropic explicitly prohibits this, and that OpenCode stopped shipping them as of version 1.3.0. The [Claude Code documentation](https://code.claude.com/docs/en/legal-and-compliance), for its part, says subscription OAuth sign-in is meant for Claude Code and Anthropic's other native apps. For Claude in OpenCode, that leaves an API key from the Claude Console:

```json
{
  "$schema": "https://opencode.ai/config.json",
  "model": "anthropic/claude-sonnet-5-5",
  "small_model": "anthropic/claude-haiku-5-5"
}
```

### Local models through Ollama

Ollama connects as an OpenAI-compatible provider. Here's the project `opencode.json` used for the test in this guide:

```json
{
  "$schema": "https://opencode.ai/config.json",
  "model": "ollama/qwen3:8b",
  "provider": {
    "ollama": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Ollama (local)",
      "options": { "baseURL": "http://localhost:11434/v1" },
      "models": {
        "qwen3:8b": { "name": "Qwen3 8B" },
        "gemma4:e4b": { "name": "Gemma 4 E4B" }
      }
    }
  }
}
```

The key in `models` must match the model name in Ollama. To check that the config was picked up, run `opencode models ollama`. It lists the provider's models as `ollama/<model>`.

Context is the main setting here. The [Ollama docs](https://docs.ollama.com/integrations/opencode) say OpenCode needs a context of 64k tokens or more. By default, Ollama picks the context based on VRAM: 4k below 24 GiB, 32k at 24-48 GiB, and 256k at 48 GiB or more ([context length](https://docs.ollama.com/context-length)). On the 36 GiB test machine, `ollama ps` showed 32,768. When tool calls don't work, the OpenCode docs suggest raising `num_ctx` to 16-32k, which is below Ollama's recommendation.

You set the context when starting the server, and the actual value shows in the `CONTEXT` column:

```bash
OLLAMA_CONTEXT_LENGTH=64000 ollama serve
ollama ps
```

More context runs into memory limits and the model's own ceiling. For qwen3:8b that ceiling is 40,960 tokens, so 64k is out of reach. Model choice, quantization, and memory are covered in detail in the [Ollama guide](https://futurecraft.pro/blog/ollama-guide/).

There's also a shortcut: `ollama launch opencode`. Per the Ollama docs, it starts OpenCode with an inline config for the selected model and doesn't overwrite `~/.config/opencode/opencode.json`. `ollama launch opencode --config` only sets up the integration without starting a session. Models defined only in `opencode.json` won't appear in the `ollama launch` picker. This path wasn't tested.

If you need a local model in Claude Code specifically, that also works through Ollama's Anthropic-compatible API. The setup is covered in the [Ollama guide](https://futurecraft.pro/blog/ollama-guide/).

### Custom OpenAI-compatible provider

Any service with an OpenAI-compatible API is added the same way. In `/connect`, choose Other, set a provider ID and key, then describe the provider in `opencode.json`:

```json
{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "myprovider": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "My provider",
      "options": {
        "baseURL": "https://api.myprovider.com/v1",
        "apiKey": "{env:MYPROVIDER_API_KEY}"
      },
      "models": { "my-model": { "name": "My model" } }
    }
  }
}
```

The `@ai-sdk/openai-compatible` package works with `/v1/chat/completions`. If the provider uses `/v1/responses`, the docs recommend `@ai-sdk/openai`. You can pass extra headers in `options.headers`.

## Modes and agents

### Build and Plan

OpenCode has two primary agents, and Tab switches between them. Build is the default agent with all tools. Plan is meant for analysis and planning, but it [restricts less](https://opencode.ai/docs/agents) than the name suggests:

- file edits, writes, and patches are denied, except markdown plans in `.opencode/plans/` and in the OpenCode data directory;
- bash isn't restricted, and commands follow the general `permission` config;
- Plan's rules are applied before your config, and the last matching rule wins. A global `"edit": "allow"` applies to Plan as well.

To make sure Plan changes nothing and asks before running commands, set its permissions explicitly:

```json
{
  "agent": {
    "plan": {
      "permission": { "edit": "deny", "bash": "ask" }
    }
  }
}
```

### Subagents

There are two built-in subagents. General handles multi-step tasks, has every tool except `todowrite`, and can change files; several General tasks can run in parallel. Explore is read-only and searches code. The primary agent calls subagents on its own based on their descriptions, and you can call one manually with a mention: `@general find where authentication is handled`. Three more system agents (compaction, title, summary) are hidden and run automatically.

### Custom agents

You can define your own agent under the `agent` key in the config or as a markdown file in `~/.config/opencode/agents/` (global) or `.opencode/agents/` (project). The file name becomes the agent name:

```markdown
---
description: Reviews code for quality and security without editing files
mode: subagent
temperature: 0.1
permission:
  edit: deny
  bash: deny
---
You are a code reviewer. Focus on bugs, edge cases,
security and missing tests. Do not change files.
```

Only `description` is required. The other fields are `mode` (`primary`, `subagent`, or `all`), `model`, `prompt`, `temperature`, `steps` (an iteration limit after which the agent has to answer in text), `permission`, `hidden`, and `disable`. `opencode agent create` creates an agent interactively, and `opencode agent list` shows the loaded ones. The equivalent mechanism in Claude Code is covered in the article on [subagents](https://futurecraft.pro/blog/claude-code-subagents/).

### Permissions: the permission key

Each tool has three modes: `allow`, `ask`, and `deny`. Per the [documentation](https://opencode.ai/docs/permissions), the defaults are permissive. Most permissions are `allow`, and only `doom_loop` (the same call three times in a row) and `external_directory` (access to paths outside the project) are set to `ask`. Reading `.env` files requires confirmation by default.

Rules use patterns. In this example git commands are allowed, push is denied, and everything else requires confirmation:

```json
{
  "permission": {
    "bash": {
      "*": "ask",
      "git *": "allow",
      "git push *": "deny"
    }
  }
}
```

For an `ask` request, the UI offers three choices: allow once, allow similar requests for the rest of the session, or reject.

## Configuring OpenCode

OpenCode reads JSON and JSONC. Configs are [merged](https://opencode.ai/docs/config): a later source overrides only the conflicting keys and keeps the rest. Load order, from lowest to highest priority:

1. Remote organization config from `.well-known/opencode`.
2. Global `~/.config/opencode/opencode.json`.
3. The file from the `OPENCODE_CONFIG` variable.
4. Project `opencode.json`. OpenCode looks for it in the current directory and up to the nearest git directory.
5. `.opencode` directories (agents, commands, plugins).
6. Inline config from the `OPENCODE_CONFIG_CONTENT` variable.
7. Admin-managed files: `/Library/Application Support/opencode/` on macOS, `/etc/opencode/` on Linux.
8. macOS MDM profiles, which users can't override.

Two more variables: `OPENCODE_CONFIG_DIR` sets a custom directory for agents and commands, and `OPENCODE_TUI_CONFIG` points to the UI settings. The config schema lives at `https://opencode.ai/config.json`, and the TUI schema at `https://opencode.ai/tui.json`. A schema link in `$schema` turns on autocomplete in your editor.

Values support substitutions. `{env:VAR}` reads an environment variable (you get an empty string if it's missing), and `{file:path}` reads a file's contents. That keeps keys out of a config you commit to git:

```json
{
  "$schema": "https://opencode.ai/config.json",
  "instructions": ["CONTRIBUTING.md", "docs/guidelines.md"],
  "provider": {
    "openai": { "options": { "apiKey": "{file:~/.secrets/openai-key}" } }
  }
}
```

The `instructions` key takes paths and glob patterns for additional instruction files. To limit the set of providers, use `enabled_providers` (an allowlist) and `disabled_providers`. The latter takes priority.

## MCP servers

MCP servers go under the `mcp` key. Per the [documentation](https://opencode.ai/docs/mcp-servers), both local and remote servers are supported. What MCP is and how it works is covered in the article on [MCP servers](https://futurecraft.pro/blog/mcp-servers-explained/).

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "everything": {
      "type": "local",
      "command": ["npx", "-y", "@modelcontextprotocol/server-everything"],
      "enabled": true
    },
    "remote-api": {
      "type": "remote",
      "url": "https://mcp.example.com/mcp",
      "headers": { "Authorization": "Bearer {env:REMOTE_API_TOKEN}" }
    }
  }
}
```

For remote servers with OAuth, OpenCode offers to authorize on first access. You can start the flow manually with `opencode mcp auth <server-name>`. `opencode mcp list` shows the status of all servers, and `opencode mcp logout <server-name>` deletes stored credentials.

The docs also warn about context. Each MCP server adds its tool descriptions to the prompt, and some, such as GitHub MCP, add so many tokens that you can easily hit the limit. For local models with 32-64k of context, that's a real problem. If you have many servers, disable them globally and enable them only for the agent that needs them:

```json
{
  "tools": { "my-mcp*": false },
  "agent": {
    "my-agent": { "tools": { "my-mcp*": true } }
  }
}
```

MCP tools are registered with the server name as a prefix, so the `my-mcp*` pattern disables every tool from the `my-mcp` server. In the native V2 format, servers live in `mcp.servers`, and `enabled` is replaced by its inverse, `disabled`.

## OpenCode vs Claude Code

This comparison is based on both products' documentation as of November 6, 2026. Plan prices and limits are left out of the table.

| | OpenCode | Claude Code |
|---|---|---|
| License | MIT ([LICENSE](https://github.com/anomalyco/opencode)) | Proprietary, on Anthropic's terms ([LICENSE.md](https://github.com/anthropics/claude-code)) |
| Where it runs | TUI, desktop, IDE extension, `opencode run`, `serve`/`web` | Terminal, VS Code, JetBrains, desktop, web, `claude -p` |
| Models | 75+ providers through the AI SDK, local (Ollama, LM Studio, llama.cpp), any OpenAI-compatible API | Claude models through a subscription, the Anthropic API, Amazon Bedrock, Google Cloud, Microsoft Foundry |
| Who you pay | The model provider at its rates; ChatGPT Plus/Pro, Copilot, GitLab Duo subscriptions; free locally | A Claude subscription or API billing with Anthropic or a cloud provider |
| Modes | Build and Plan primary agents, switched with Tab | Permission modes (Manual, acceptEdits, plan, auto, and others), switched with Shift+Tab |
| Default permissions | Most actions `allow`; `ask` for paths outside the project, repeated calls, and `.env` | Manual: only reads run without confirmation; edits, commands, and network access ask first |
| Built-in subagents | General, Explore | Explore, Plan, general-purpose, and internal ones |
| Custom agents | Markdown in `.opencode/agents/` and `~/.config/opencode/agents/` or JSON in the config | Markdown with YAML frontmatter in `.claude/agents/` and `~/.claude/agents/` |
| Project instructions | `AGENTS.md` (created by `/init`), `instructions` key | `CLAUDE.md`; `AGENTS.md` is read if there's no CLAUDE.md |
| Skills | `SKILL.md` in `.opencode/skills/`, plus `.claude/skills/` and `.agents/skills/` | `SKILL.md` in `.claude/skills/` and `~/.claude/skills/` |
| MCP | `mcp` key in `opencode.json`, local and remote, OAuth | `claude mcp add`, local/project/user scopes, `.mcp.json` |
| Config | `opencode.json`, 8-level merge from remote to MDM | `settings.json`: managed > command line > local > project > user |

OpenCode sources: [providers](https://opencode.ai/docs/providers), [agents](https://opencode.ai/docs/agents), [permissions](https://opencode.ai/docs/permissions), [skills](https://opencode.ai/docs/skills), [config](https://opencode.ai/docs/config). Claude Code sources: [overview](https://code.claude.com/docs/en/overview), [permission modes](https://code.claude.com/docs/en/permission-modes), [sub-agents](https://code.claude.com/docs/en/sub-agents), [settings](https://code.claude.com/docs/en/settings), [MCP](https://code.claude.com/docs/en/mcp).

Architecturally, the two tools are close: a terminal agent, a planning mode, subagents, markdown agents, MCP, an instructions file in the project root. OpenCode even looks for skills in Claude Code's directories. The main differences are the model and the defaults. Claude Code works only with Claude models and is cautious by default. OpenCode isn't tied to a vendor and is permissive by default, so the quality of the work comes down to the model you connect.

Subscriptions work differently too. A Claude subscription covers Claude Code but not OpenCode: Claude models in OpenCode need an API key (see the cloud providers section). ChatGPT Plus/Pro and GitHub Copilot, on the other hand, are officially supported in OpenCode. There's more on Claude Code in the [complete guide](https://futurecraft.pro/blog/claude-code-complete-guide/), a comparison with another closed agent in [Claude Code vs Codex](https://futurecraft.pro/blog/claude-code-vs-codex/), and a market overview in [the best AI coding tools](https://futurecraft.pro/blog/best-ai-coding-tools/).

## Test: local models in OpenCode 1.15.11

**Environment.** macOS 27.2, Apple M4 Max, 36 GiB of memory. OpenCode 1.15.11 (1.19.5, the current release at test time, wasn't installed), Ollama 0.24.0, then 0.40.14. The provider config is the one shown above. No global config was used: `HOME` and `XDG_*` pointed to empty temporary directories.

**Task.** A project with `calc.py` containing `add` and `subtract` functions and two `unittest` tests. The prompt: add a `multiply(a, b)` function to `calc.py`, add a test for it, and run `python3 -m unittest discover -s tests -t .`. Command: `opencode run -m ollama/<model> "<task>"`, one attempt per configuration.

| Model | Ollama | Context | Time | Result |
|---|---|---|---|---|
| qwen2.5-coder:7b | 0.24.0 | 32,768 | 15 s | Tool call printed as JSON text, files unchanged |
| qwen2.5-coder:7b | 0.40.14 | 32,768 | 21 s | Same: calls as text, files unchanged |
| qwen3:8b | 0.24.0 | 32,768 | 70 s | Glob → Read → Edit → bash; the first test run failed, the agent fixed the import, 3 tests OK. An unreachable line was left in `calc.py` after `return a * b` |
| qwen3:8b | 0.40.14 | 32,768 | 280 s | Timeout, files unchanged |
| qwen3:8b | 0.40.14 | 32,768 | 170 s | Timeout; `subtract` replaced with `multiply`, the test fails |
| qwen3:8b | 0.40.14 | 32,768 | 212 s | 3 tests OK, but the code has duplicate `return` lines, repeated asserts, and broken function order |
| qwen3:8b | 0.40.14 | 40,960 | 86 s | Only ran the tests, files unchanged |
| gemma4:e4b | 0.40.14 | 65,536 | 79 s | multiply and its test added, 2 tests OK, but `subtract` and its test deleted |

Takeaways:

1. **The `tools` tag in the Ollama library doesn't guarantee working tool calls in OpenCode.** qwen2.5-coder:7b has the tag, but in every run in the table it wrote calls as text, and OpenCode didn't execute them. The test doesn't show where exactly the chain breaks (the model's format, the Ollama template, or the OpenCode version).
2. **Results on local 8B models are unstable.** In five runs, qwen3:8b completed the task once without touching existing code and got the tests green once more at the cost of junk in the code. The other three runs ended with nothing done or with damage. gemma4:e4b with 64k context was the fastest, but it deleted a function it wasn't asked to touch.
3. **Green tests don't mean a correct edit.** In two of the three runs with green tests, existing code was broken or deleted. In the third, an extra line was left behind.
4. **One attempt per configuration isn't enough to rank models.** The table shows how widely results vary. It doesn't tell you which model is better.

The practical takeaway: with a local model, OpenCode can get the task done, but work only in a git repository, check `git diff` after every step, and verify the result with tests and by reading the code. Behavior on OpenCode 1.19.5 and V2 wasn't tested.

## Limitations and gotchas

**Two versions.** V1 and V2 have different install commands, and `brew install opencode` from core Homebrew already installs V2. Decide which version you want before installing, and read the documentation for that version: V2 has a different plugin format and server API.

**V2 doesn't ask about paths outside the project.** The migration guide warns that V1 asks before accessing paths outside the project, while V2 allows it by default. To restore the V1 behavior in V2, add the rule `{ "action": "external_directory", "resource": "*", "effect": "ask" }` to the `permissions` array.

**Broad default permissions.** Even in V1, most tools, including bash and file edits, run without confirmation. For an unfamiliar repository or a weak model, set `"bash": {"*": "ask"}` and review what the agent wants to run.

**Prompt size and skills from other agents.** Per the [documentation](https://opencode.ai/docs/skills), OpenCode looks for skills in its own directories and also in `~/.claude/skills/` and `~/.agents/skills/` (in a project, `.claude/skills/` and `.agents/skills/`). It lists the names and descriptions of every skill it finds in the `skill` tool description. In test runs with the real home directory, the Ollama log showed `truncating input prompt limit=32768 prompt=52988`: a 52,988-token prompt was cut down to 32,768. The OpenCode log at the same time had `service=skill` warnings with paths to those directories. The link between skills and prompt size isn't directly proven, but in runs with an empty `HOME` requests were about 8k tokens. Per the docs, `"permission": {"skill": {"*": "deny"}}` hides skills, and `"tools": {"skill": false}` on an agent removes the whole `<available_skills>` block. These settings weren't tested.

Here's how the same effect shows up: the local model behaves oddly, and the Ollama log has a `truncating input prompt` line. A truncated system prompt can lose tool descriptions, and then the model doesn't know how to call the tools.

**Local model context.** Ollama recommends 64k or more, but by default the server allocates 4k or 32k depending on VRAM, and some models top out below 64k. Check the actual value in `ollama ps`, not in the config.

**Plan isn't read-only.** File edits are denied in Plan, but bash follows the general config. If `"bash": "allow"` is set globally, Plan can run any command.

**MCP eats context.** Every server adds tool descriptions to the prompt. With a local model, attach MCP servers selectively, to a specific agent.

**Not tested for this guide:** OpenCode 1.19.5 and V2, `ollama launch opencode`, Plan mode, MCP, cloud providers. Those sections are based on the documentation.

## Where to start

1. Pick a version and install it: for V1, `curl -fsSL https://opencode.ai/install | bash` or the `anomalyco/tap/opencode` tap; for V2, the commands from the README. Check `opencode --version`.
2. Run `opencode` in a project under git, connect a cloud provider with `/connect`, and run `/init`.
3. Restrict permissions right away: `"bash": {"*": "ask"}` in `opencode.json` and explicit `permission` settings for the Plan agent.
4. For a local model, raise the Ollama context (`OLLAMA_CONTEXT_LENGTH`), check it in `ollama ps`, and describe the provider in `opencode.json`.
5. Give the model a small task with tests, review `git diff`, and only then move on to real work.
6. If the prompt balloons (`truncating input prompt` in the Ollama log), remove extra skills and MCP servers or enable them only for the agents that need them.
