What you need
- A Runloop API key (
RUNLOOP_API_KEY)
- One of:
- Python 3.11+ and
uv
- Node.js 18+ and
npm
- Optional model provider keys:
ANTHROPIC_API_KEY
OPENAI_API_KEY
Environment variables
Set your Runloop API key before running any command:
export RUNLOOP_API_KEY="your-runloop-api-key"
You can also set provider keys if your OpenCode workflow needs them:
export ANTHROPIC_API_KEY="..."
export OPENAI_API_KEY="..."
Instead of exporting provider keys directly, you can store them as Runloop
account secrets and map them into your devbox at runtime. See Account
Secrets.
Setup
Clone the reference implementation:
git clone https://github.com/runloopai/opencode-starter.git
cd opencode-starter
Create a blueprint with OpenCode
cd python
uv sync
uv run opencode-runloop create-blueprint
This creates a reusable opencode blueprint with OpenCode preinstalled.
Create a devbox with OpenCode
cd python
uv run opencode-runloop run
Each command creates a devbox, starts opencode web, enables a tunnel, and prints the OpenCode URL.
Optional: create devbox without blueprint (manual install)
Use this when you want zero upfront setup:
cd python
uv sync
uv run opencode-runloop run --manual
Manual mode is slower because OpenCode is installed in a fresh devbox each
run.
How the integration works internally
Each run follows this flow:
- Create a devbox (from blueprint or fresh)
- Install OpenCode (manual mode only)
- Write OpenCode config in the devbox
- Start OpenCode on
0.0.0.0:3000
- Create a Runloop tunnel and print the URL
This makes local setup simple while keeping execution remote and sandboxed.
OpenCode Dockerfile
Use this Dockerfile when creating the blueprint:
# Runloop starter image containing Node.js and npm
FROM runloop:runloop/starter-x86_64
# Install OpenCode globally
RUN npm install -g opencode-ai
# Create config directory
RUN mkdir -p /home/user/.config/opencode
WORKDIR /home/user
OpenCode config
Use this OpenCode config payload:
{
"$schema": "https://opencode.ai/config.json",
"default_agent": "runloop",
"server": {
"hostname": "0.0.0.0",
"port": 3000
},
"agent": {
"runloop": {
"description": "Runloop sandbox-aware coding agent",
"mode": "primary",
"prompt": "You are running in a Runloop devbox. Use /home/user as your working directory. When running services, bind to 0.0.0.0 so they are accessible via Runloop tunnels. File paths should be absolute or relative to /home/user."
}
}
}
Write config into the devbox filesystem
The starter writes config to /home/user/.config/opencode/opencode.json before starting OpenCode:
import json
opencode_config = {
"$schema": "https://opencode.ai/config.json",
"default_agent": "runloop",
"server": {
"hostname": "0.0.0.0",
"port": 3000,
},
"agent": {
"runloop": {
"description": "Runloop sandbox-aware coding agent",
"mode": "primary",
"prompt": "You are running in a Runloop devbox. Use /home/user as your working directory. When running services, bind to 0.0.0.0 so they are accessible via Runloop tunnels. File paths should be absolute or relative to /home/user.",
},
},
}
devbox.cmd.exec("mkdir -p ~/.config/opencode")
devbox.file.write(
file_path="/home/user/.config/opencode/opencode.json",
contents=json.dumps(opencode_config, indent=2),
)
Snippets
Creating a blueprint with OpenCode
from runloop_api_client import RunloopSDK
from runloop_api_client.types.shared_params.launch_parameters import (
LaunchParameters,
UserParameters,
)
runloop = RunloopSDK()
opencode_dockerfile = '''
# Runloop starter image containing Node.js and npm
FROM runloop:runloop/starter-x86_64
# Install OpenCode globally
RUN npm install -g opencode-ai
# Create config directory
RUN mkdir -p /home/user/.config/opencode
WORKDIR /home/user
'''
blueprint = runloop.blueprint.create(
name="my_opencode_blueprint",
dockerfile=opencode_dockerfile,
launch_parameters=LaunchParameters(
user_parameters=UserParameters(username="root", uid=0)
),
)
Creating a devbox with OpenCode
from runloop_api_client import RunloopSDK
from runloop_api_client.types.devbox_create_params import Tunnel
from runloop_api_client.types.shared_params.launch_parameters import (
LaunchParameters,
UserParameters,
)
runloop = RunloopSDK()
devbox = runloop.devbox.create_from_blueprint_name(
name="opencode",
blueprint_name="my_opencode_blueprint",
launch_parameters=LaunchParameters(
user_parameters=UserParameters(username="user", uid=1000),
),
tunnel=Tunnel(auth_mode="open"),
)
Common issues
- Missing API key errors
- Confirm
RUNLOOP_API_KEY is set in your shell before running commands.
- Provider/model errors
- Set
ANTHROPIC_API_KEY or OPENAI_API_KEY based on the model you are using.
- Slow startup
- Use blueprint mode (
create-blueprint once, then run) instead of --manual.
Next steps