---
title: OpenCode harness
description: >-
  The OpenCode harness runs OpenCode in the sandbox on the key of the provider
  its model id names and records its events.
---
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reeval.ai/llms.txt
> Use this file to discover all available pages before exploring further.

`opencode()` runs OpenCode in the sandbox on the provider the model id names, with that provider's key. For more information about the sandbox, see [Choose a sandbox](/configuration/sandboxes).

## `provider/model`

The part of the model id before the first `/` picks the provider, and the provider picks the key. For more information about each provider's model id prefix, key variable, header, and hosts, see [OpenCode providers](/reference/options#opencode-providers).

`opencode()` reads the provider's key from the environment or the `.env.local` file. A run exits with code 2 when the variable is unset, or when its value contains whitespace or a line break. reeval swaps the key into the provider's header on each request to the provider's hosts, and refuses it anywhere else. A restricted egress policy allows the provider's hosts and `mcp.exa.ai`.

When the API rejects the key, the attempt error begins with `The API rejected <Key>: set a valid key in the environment or .env.local`, with the provider's key variable.

For more information about keeping API keys on the host, see [Keep API keys on the host](/configuration/environments/secrets#keep-api-keys-on-the-host).

For more information about every provider variable, see [Environment variables](/reference/environment-variables).

## `opencode()`

`opencode()` is exported from `{{ pkg }}/harness`. The following configuration passes it as the `harness` option:

```ts title="reeval.config.ts"
import { defineConfig } from '{{ pkg }}'
import { opencode } from '{{ pkg }}/harness'

export default defineConfig({
  harness: opencode({
    model: 'google/gemini-3.8-flash',
    effort: 'high',
  }),
})
```

`model` is required. For what each field takes, see [Harness factory options](/reference/options#harness-factory-options).

The cell id is `opencode:` followed by the part of `model` after its last `/`.

In the sandbox, OpenCode runs with its `question` and browser tools off, self-update, share links, and the model-catalog fetch off, session titles on the run's model, and its model calls over HTTP. That configuration overrides the workspace's own `opencode.json` file where both set a key.

For more information about model ids and effort values, see [Set the agent's model](/configuration/agents/model). For rules, skills, MCP servers, usage, served models, and web events, see [Harness behavior](/reference/options#harness-behavior).

## `plugins`

reeval adds each plugin's skills to the home skills directory and unpacks subagents and commands into `.opencode/agents` and `.opencode/commands`. OpenCode skips a file whose frontmatter it refuses, so reeval keeps only `description`, and `mode: subagent` for a subagent. OpenCode's own plugins are code modules, and reeval never loads them from an environment's plugin.

[//]: # (generated:harness-plugins:opencode)

- Takes `skills`, `agents`, `commands` and `mcp`, and refuses a plugin that keeps `hooks` and `rules`: narrow it with `only`, or leave it out of the cell.

[//]: # (/generated:harness-plugins:opencode)

For more information about plugins, see [Environment helpers reference](/reference/environment-helpers#pluginlocal).
