Skip to main content
Use the reference starter repo for complete source code: runloopai/opencode-starter.

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:
  1. Create a devbox (from blueprint or fresh)
  2. Install OpenCode (manual mode only)
  3. Write OpenCode config in the devbox
  4. Start OpenCode on 0.0.0.0:3000
  5. 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