AI Coding Tools

opencode Setup Guide — Terminal AI Agent with Any Model

Configure opencode to use a custom OpenAI-compatible provider. Full JSON config, model selection, remote and container workflows, and troubleshooting.

6 min read Clean APIs Team
opencode Setup Guide — Terminal AI Agent with Any Model
Contents

opencode is an AI coding agent that lives in your terminal. No editor, no browser, no GUI — it works against your current directory from the shell. That makes it the right tool for SSH sessions, containers, and CI-adjacent work where an editor is not available.

This guide connects opencode to Clean APIs — 31 models, one key, starting free.

What you need#

  • opencode installed
  • A Clean APIs API key — free, 5M tokens/month, no card
  • Five minutes

Step 1: Get your API key#

Sign up at cleanapis.com, then Dashboard → API Keys → Create Key. Keep all scopes enabled — opencode enumerates models before its first message.

Step 2: Add the provider#

opencode is configured through JSON rather than a settings panel. Edit ~/.config/opencode/opencode.json:

{
  "provider": {
    "cleanapis": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Clean APIs",
      "options": {
        "baseURL": "https://cleanapis.com/v1",
        "apiKey": "{env:CLEANAPIS_API_KEY}"
      },
      "models": {
        "claude-opus-4.8": {
          "name": "claude-opus-4.8"
        }
      }
    }
  }
}

Then export the key rather than committing it:

export CLEANAPIS_API_KEY=cc_your_key_here

Add that to your ~/.bashrc, ~/.zshrc, or PowerShell profile to persist it.

Using {env:...} instead of a literal key means the config file is safe to commit or sync between machines.

Step 3: Select the model#

Inside opencode:

/models

Pick your Clean APIs model from the list, and start working.

Adding more models#

List every available ID:

curl https://cleanapis.com/v1/models \
  -H "Authorization: Bearer $CLEANAPIS_API_KEY"

Add the ones you want to the models block:

"models": {
  "claude-opus-4.8": { "name": "Reasoning (default)" },
  "another-model-id": { "name": "Fast + cheap" }
}

The name is only a display label, so use something that reminds you why you added it. Switching models inside opencode is then a /models away — useful when you want a cheap model for mechanical edits and a reasoning model for debugging.

Choosing a model for terminal work#

Tool calling is mandatory#

Without the tools capability, opencode cannot read or write files. Check the Tools badge on the models page or look for "tools" in the capabilities array from /v1/models.

Context window#

opencode sends file contents plus history plus tool schemas. Prefer 128K or more for real projects; 8K fails almost immediately.

Reasoning where it earns its cost#

Reasoning models generate their thinking as billed output tokens, so they cost meaningfully more. Worth it for debugging and architecture; wasteful for renames and formatting.

Configure both and switch per task — every Clean APIs plan reaches every model.

Why opencode suits remote work#

No GUI dependency. Works identically over SSH, in a Docker container, or on a VPS.

Scriptable. Terminal-native means it composes with the rest of your shell workflow.

Low overhead. No editor process, no language server, no indexing.

The trade-off is reviewing changes. Terminal diffs are harder to scan than an editor's side-by-side view, so for large refactors you may prefer Kilo Code or Cline.

Long sessions over SSH#

SSH connections and reverse proxies both like to drop idle channels. Two things keep long agent runs alive:

On our side. Streaming connections stay open up to an hour, with a keep-alive comment every 15 seconds.

On your side. If you are running through your own proxy, raise its timeout:

proxy_read_timeout 3700s;
proxy_buffering off;

proxy_buffering off matters — with buffering on, streamed chunks are withheld and opencode appears to hang.

For long SSH sessions, run opencode inside tmux or screen so a dropped connection does not kill an in-progress task.

Troubleshooting#

Provider not appearing in /models#

Malformed JSON. Validate it:

cat ~/.config/opencode/opencode.json | python -m json.tool

Also confirm the file is at the path opencode actually reads for your platform.

401 Unauthorized#

The environment variable is not set in the shell opencode is running in:

echo $CLEANAPIS_API_KEY

Empty output means the export did not persist. Add it to your shell profile.

403 insufficient_scope#

Enable models:read on the key — opencode calls the models endpoint on startup.

404 model_not_found#

The model ID in your config does not exist. Copy it exactly from /v1/models.

Empty response#

A reasoning model spent its budget on thinking. We floor max_tokens at 2048 and default to 8192; raise it to 16000+ for hard problems.

Stream hangs#

Buffering somewhere in the path. Check proxy_buffering off on nginx, and that X-Accel-Buffering: no is not stripped.

429 rate limited#

Per-minute limit hit. Retry-After gives the wait; Dashboard → Usage → Rate Limits shows live consumption.

Cost awareness#

Terminal agents are as token-hungry as editor ones — same loops, same file reads.

Task Tokens
Single file edit ~8,000
Multi-file refactor 30,000–80,000
Codebase question ~5,000

Dashboard → Usage shows real per-request numbers. Set a usage alert in Settings → Notifications to be warned before the allowance runs out.

→ Understanding token pricing

Working effectively in a terminal agent#

A few habits make opencode noticeably better, and they are not obvious from the docs.

Start in the right directory. opencode works against your current working directory. Starting it at your repository root gives it the whole project; starting it three levels deep limits what it can find. This sounds trivial and it is the most common cause of "it cannot find the file."

Be specific about paths. In an editor the agent can infer context from your open tabs. In a terminal it cannot. "Fix the bug in the auth middleware" is weaker than "fix the token expiry check in app/Http/Middleware/ApiKeyAuth.php."

Ask for diffs on large changes. Reviewing a full rewritten file in a terminal is painful. "Show me only the lines that change" produces output you can actually scan, and costs fewer output tokens.

Commit before a big task. Terminal agents edit files directly. A clean Git state means git diff shows exactly what the agent did, and git checkout . undoes all of it. This is your review tool and your undo button.

Use it for what terminals are good at. Log analysis, migration scripts, config changes, dependency upgrades — tasks where the output is text and the verification is a command. Reserve visual work for an editor agent.

When to reach for an editor agent instead#

opencode is the wrong tool when:

  • The change spans many files and you need to review each diff carefully
  • You are working through unfamiliar code and want to click between definitions
  • The task is visual — layout, styling, anything where you need to see the result

For those, Cline gives you approval-based diffs in VS Code, and Kilo Code gives you autonomous multi-file editing with visual review.

Since one Clean APIs key works in all of them, switching tools mid-project costs nothing.

Next steps#

Get a free API key — 5M tokens monthly, 31 models, no card.

Ready to build?

Everything in this article works on the free tier — 5M tokens every month, all 33 models, no card.

Related reading