25 OpenCode Setup
April 30, 2026 ยท View on GitHub
It reuses the opencode CLI that already works on your machine, injects DeepScientist MCP servers, and mirrors first-party skills into the OpenCode project tree.
The right order is:
- install OpenCode
- authenticate / configure providers directly in OpenCode
- validate
opencode rundirectly - run
ds doctor - only then switch DeepScientist to the
opencoderunner
Official docs to read first
Read the official OpenCode docs first:
- Intro / install:
https://opencode.ai/docs - Config:
https://opencode.ai/docs/config/ - Providers:
https://opencode.ai/docs/providers/ - MCP servers:
https://opencode.ai/docs/mcp-servers - Skills:
https://opencode.ai/docs/skills - Gemini OpenAI compatibility:
https://ai.google.dev/gemini-api/docs/openai - Ollama OpenAI compatibility:
https://docs.ollama.com/openai - Ollama + OpenCode:
https://docs.ollama.com/integrations/opencode
DeepScientist expects the same local OpenCode configuration described there.
What DeepScientist actually uses
DeepScientist currently runs OpenCode through a command shape close to:
opencode run \
--format json \
--pure \
--dir /absolute/workspace \
[--model provider/model] \
[--agent agent-name] \
[--variant high]
Then it injects:
memoryartifactbash_exec
as quest-local MCP servers.
It also mirrors DeepScientist skills into:
<quest_root>/.opencode/skills/
Step 1: install OpenCode
According to the current OpenCode docs, common install paths include:
Install script
curl -fsSL https://opencode.ai/install | bash
NPM
npm install -g opencode-ai
Bun
bun install -g opencode-ai
pnpm
pnpm install -g opencode-ai
Yarn
yarn global add opencode-ai
Homebrew
brew install anomalyco/tap/opencode
Then verify the actual binary:
which opencode
opencode --version
opencode run --help
If you need a custom binary, set an absolute path in runners.opencode.binary.
Step 2: authenticate providers in OpenCode
The official OpenCode docs describe provider setup through:
opencode auth loginopencode providersopencode auth list
OpenCode stores credentials in:
~/.local/share/opencode/auth.json
and global config in:
~/.config/opencode/opencode.json
If you are new to OpenCode providers, the docs recommend connecting a provider first and then setting the model in config.
Step 3: validate OpenCode directly
Before changing DeepScientist settings, validate OpenCode on its own.
Minimal smoke check
opencode run --format json --pure "Reply with exactly HELLO"
Model-specific smoke check
opencode run --format json --pure --model anthropic/claude-sonnet-4-5 "Reply with exactly HELLO"
Agent / variant smoke check
opencode run \
--format json \
--pure \
--agent plan \
--variant high \
"Reply with exactly HELLO"
If this does not work, stop there and fix OpenCode first.
OpenCode config concepts that matter most
From the current official docs and CLI help, the DeepScientist-relevant OpenCode concepts are:
- global config file:
~/.config/opencode/opencode.json - credentials file:
~/.local/share/opencode/auth.json - project config merge behavior
- model id format:
provider/model-id default_agentin OpenCode config--agentin CLI--variantin CLI--format jsonfor raw event output--thinkingin CLI if you want OpenCode itself to print thinking blocks in direct terminal usage
Config merge and project locations
OpenCode config files are merged, not replaced.
The official config docs also note that project-level OpenCode directories use plural names such as:
.opencode/agents/.opencode/skills/.opencode/plugins/.opencode/tools/
That aligns with how DeepScientist mirrors its own quest-local skills.
Provider configuration
OpenCode's provider docs describe two layers:
- credentials added through
opencode auth login - provider behavior customized in the
providersection ofopencode.json
A common provider example looks like:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"anthropic": {
"options": {
"baseURL": "https://api.anthropic.com/v1"
}
}
}
}
This matters for DeepScientist because the opencode runner does not bypass your OpenCode provider setup. It reuses it.
Gemini
OpenCode is the recommended DeepScientist runner for Gemini.
Why:
- Gemini has an official OpenAI-compatible endpoint
- OpenCode supports custom OpenAI-compatible providers
- the DeepScientist OpenCode runner reuses
~/.config/opencode/opencode.jsonand can passGEMINI_API_KEYthroughrunners.opencode.env
1. Prepare the key
export GEMINI_API_KEY="..."
printenv GEMINI_API_KEY
Gemini's OpenAI-compatible base URL is:
https://generativelanguage.googleapis.com/v1beta/openai/
2. Configure a custom provider
Edit:
${EDITOR:-vim} ~/.config/opencode/opencode.json
Merge in:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"gemini": {
"npm": "@ai-sdk/openai-compatible",
"name": "Gemini",
"options": {
"baseURL": "https://generativelanguage.googleapis.com/v1beta/openai/",
"apiKey": "{env:GEMINI_API_KEY}"
},
"models": {
"gemini-3-flash-preview": {
"name": "Gemini 3 Flash Preview"
}
}
}
}
}
If opencode.json already has providers, merge the gemini object instead of replacing the file.
3. Validate OpenCode directly
export GEMINI_API_KEY="..."
opencode run \
--format json \
--pure \
--model gemini/gemini-3-flash-preview \
"Reply with exactly HELLO."
If this fails, fix OpenCode provider setup first.
4. Map it into DeepScientist
Let OpenCode decide the model:
opencode:
enabled: true
binary: opencode
config_dir: ~/.config/opencode
model: inherit
env:
GEMINI_API_KEY: "..."
Force Gemini for every DeepScientist run:
opencode:
enabled: true
binary: opencode
config_dir: ~/.config/opencode
model: gemini/gemini-3-flash-preview
env:
GEMINI_API_KEY: "..."
Then:
ds doctor --runner opencode
ds --runner opencode
Ollama
OpenCode is also one of the simplest Ollama paths.
1. Make the model available
ollama --version
ollama serve
In another terminal:
ollama pull gpt-oss:20b
ollama run gpt-oss:20b "Reply with exactly HELLO."
2. Configure OpenCode
If OpenCode recognizes its built-in Ollama provider, prefer that:
opencode providers
opencode models ollama
If you need an explicit custom provider, treat Ollama as a local OpenAI-compatible endpoint:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"local_ollama": {
"npm": "@ai-sdk/openai-compatible",
"name": "Local Ollama",
"options": {
"baseURL": "http://localhost:11434/v1",
"apiKey": "ollama"
},
"models": {
"gpt-oss:20b": {
"name": "gpt-oss:20b"
}
}
}
}
}
3. Validate OpenCode directly
Built-in provider:
opencode run \
--format json \
--pure \
--model ollama/gpt-oss:20b \
"Reply with exactly HELLO."
Custom provider:
opencode run \
--format json \
--pure \
--model local_ollama/gpt-oss:20b \
"Reply with exactly HELLO."
Use the model string that works in your DeepScientist config:
opencode:
enabled: true
binary: opencode
config_dir: ~/.config/opencode
model: ollama/gpt-oss:20b
or:
opencode:
enabled: true
binary: opencode
config_dir: ~/.config/opencode
model: local_ollama/gpt-oss:20b
Then run:
ds doctor --runner opencode
ds --runner opencode
Agents and skills
The official OpenCode docs support:
- custom agents in
opencode.json - file-based agents in
~/.config/opencode/agents/or.opencode/agents/ - skills in
.opencode/skills/<name>/SKILL.md
DeepScientist currently maps its own first-party skill bundles into:
<quest_root>/.opencode/skills/deepscientist-*/
So from the user's point of view:
- your own global OpenCode agents stay global
- DeepScientist's quest skills are mirrored per quest
- DeepScientist can still pass
--agent <name>throughrunners.opencode.default_agent
Step 4: map OpenCode into DeepScientist settings
Global default runner
# ~/DeepScientist/config/config.yaml
default_runner: opencode
Runner config
# ~/DeepScientist/config/runners.yaml
opencode:
enabled: true
binary: opencode
config_dir: ~/.config/opencode
model: inherit
default_agent: ""
variant: ""
mcp_timeout_ms: 172800000
retry_on_failure: true
retry_max_attempts: 4
retry_initial_backoff_sec: 10.0
retry_backoff_multiplier: 4.0
retry_max_backoff_sec: 600.0
env: {}
Settings-first path after launch
If DeepScientist is already running, use the visual Models page first:
- route:
/settings/runners
Use it to:
- switch the global default runner to
OpenCode - enable the OpenCode runner
- fill
binary,config_dir,model,default_agent,variant, andmcp_timeout_ms

Settings page mapping
In the web Settings page:
Config -> Default runner- choose
OpenCode
- choose
Runners -> opencode.enabled- enable the runner
Runners -> opencode.binary- set
opencodeor an absolute path
- set
Runners -> opencode.config_dir- usually
~/.config/opencode
- usually
Runners -> opencode.model- use
inheritunless you want DeepScientist to force a specificprovider/model
- use
Runners -> opencode.default_agent- optional
--agent
- optional
Runners -> opencode.variant- optional provider-specific
--variant
- optional provider-specific
Runners -> opencode.mcp_timeout_ms- timeout for fetching tools from each MCP server during OpenCode startup; this is not tool execution timeout
Step 5: validate DeepScientist
After direct OpenCode validation works, run:
ds doctor
You want the OpenCode checks to confirm:
- the binary is found
- the startup hello probe succeeds
- the configured
config_diris readable
Then start DeepScientist:
ds
and confirm that a quest actually runs on opencode.
Model selection and other providers
OpenCode is the most flexible runner in DeepScientist today for users who want to connect other model providers.
The official docs describe:
provider/model-idmodel naming- provider-specific
baseURL - local models
- many third-party providers through the OpenCode provider system
In practice that means:
- if OpenCode already works with your provider, DeepScientist can reuse it
- you usually do not need DeepScientist-specific provider code
- keep
runners.opencode.model: inheritwhen OpenCode itself should decide the default model - only set
runners.opencode.modelwhen you want DeepScientist to override the OpenCode default for every quest turn
Project-level switching
DeepScientist now supports both levels of switching:
New quests follow the global default
default_runner: opencode
Existing quests can override it
Inside project settings, change:
Project settings -> Default runner
This means you can:
- keep one quest on Codex
- move another quest to OpenCode
- switch a Claude quest over to OpenCode later if the provider fit is better
DeepScientist-specific OpenCode behavior
For each run, DeepScientist creates a quest-local OpenCode home overlay under:
<quest_root>/.ds/opencode-home/
and writes quest-specific config there, including MCP injection.
It also mirrors first-party skills into:
<quest_root>/.opencode/skills/
So users do not need to hand-maintain DeepScientist's MCP or first-party skills inside the quest.
Common failure cases
opencode is missing
Check:
which opencode
opencode --version
Then either:
- fix PATH
- or set
runners.opencode.binaryto an absolute path
opencode run works interactively, but DeepScientist doctor fails
Usually one of these is wrong:
runners.opencode.config_dir- OpenCode credentials were saved under a different user home than the daemon actually sees
- the configured
modeloverride is invalid for the current provider variantis set even though the current provider does not support it
You use a provider-specific reasoning tier
Put it in:
runners:
opencode:
variant: high
only if your provider actually documents that variant flag.
Otherwise leave variant empty.
You want a custom OpenCode agent
Set:
runners:
opencode:
default_agent: plan
only after confirming the same agent name works in direct OpenCode CLI usage.
Skills do not appear
Check that the quest contains:
<quest_root>/.opencode/skills/
DeepScientist syncs first-party skill bundles there during quest creation and prompt refresh.
Recommended defaults
For most users, the safest OpenCode setup is:
# config.yaml
default_runner: opencode
# runners.yaml
opencode:
enabled: true
binary: opencode
config_dir: ~/.config/opencode
model: inherit
default_agent: ""
variant: ""
env: {}
Then do all provider-specific auth and model tuning inside OpenCode first, validate with opencode run, and only then switch DeepScientist over.