Skip to content

About

Use OpenCode models (incl. free tier) in any harness — OpenAI/Anthropic-compatible Cloudflare Worker

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

5 Commits

Folders and files

Repository files navigation

opencode-gateway

Cloudflare Worker or Python Flask server that lets any harness (Claude Code, Codex CLI, Aider, OpenHands, LangChain, curl, ...) use OpenCode models through one OpenAI/Anthropic-compatible endpoint — no OpenCode account or API key needed for the free models.

Deploy to Cloudflare Workers

Two runtimes, same API

Cloudflare Worker Python (Flask)
Files worker.js + bridge.js server.py + bridge.py
Runtime edge, no server local machine, VPS, Docker, systemd…
Install npx wrangler deploy pip install -r requirements.txt
Secrets dashboard secrets env vars (ZEN_API_KEY, GATEWAY_KEY, OC_UA_VERSION)

Both expose identical endpoints and the identical free-tier fingerprint. The Python bridge is cross-validated against the Worker's bridge.js (Anthropic/Responses ↔ chat conversion, SSE aggregation and re-emission).

Free models

Verified live against the upstream catalog. GET /v1/models returns the current list with free: true flags (additions/removals upstream are picked up automatically).

Model Status (2026-10-18)
big-pickle ✅ verified
beam-free ✅ verified
deepseek-v4.1-flash-free ✅ verified
glm-5.3-flash-free ✅ verified
longcat-2.5-preview-free ✅ verified
mimo-v2.6-flash-free ✅ verified
nemotron-3.5-lightning-free ✅ verified
nemotron-3.5-super-vl-free ✅ verified
space-bunny-free ✅ verified
jev-1.13-free ✅ works — but it is a TypeSafe decision model, not chat; use POST /v1/systemone (below)

Free-tier catalog is limited-time promos upstream — models can rotate; the gateway's /v1/models always reflects what is currently available, and any model ending in -free (plus big-pickle) is routed through the free fingerprint automatically.

Endpoints

GET  /v1/models            catalog
POST /v1/chat/completions  OpenAI Chat wire (stream + non-stream)
POST /v1/messages          Anthropic Messages wire (Claude Code compatible)
POST /v1/responses         OpenAI Responses wire
POST /v1/systemone         Jev/SystemOne decision wire (free tier)
GET  /health

Jev / SystemOne (decision models)

jev-1.13 / jev-1.13-free are not chat models — they are TypeSafe decision models (classify state into answers with probabilities/confidence). They speak their own wire format on a dedicated endpoint, which the gateway passes through:

POST /v1/systemone
{
  "model": "jev-1.13-free",
  "state": "My Stripe integration keeps failing for 3 days.",
  "questions": {
    "department": {"type": "choice", "instructions": "Which team should handle this",
                   "criteria": {"billing": "Payment issues", "technical": "Bugs"}},
    "is_urgent": {"type": "noul", "instructions": "The customer explicitly requests a refund"}
  }
}

Response: {"answers": {"department": {"choice": "billing", "confidence": 0.44, ...}, ...}} Question types: choice (≤255 options), score (2–10 ordered levels), noul (true/false). Free tier verified working — see the Jev guide and the API reference for the full schema.

How the free tier works

OpenCode's free tier is not account-gated — it is client-shape gated. Both runtimes reproduce the official opencode CLI fingerprint on every free request (reverse-engineered by the opencode2api project, documented in their UPSTREAM-COMPAT.md):

  1. Upstream path /inference/openai/v1/chat/completions — all free models accept the OpenAI chat wire; Anthropic/Responses client requests are bridged locally (bridge.js / bridge.py, same architecture as zen-proxy)
  2. User-Agent: opencode/latest/<ver>/cli — version pinned (2.0.29); the gate rejects too-old AND too-new versions
  3. x-opencode-session: ses_ + descending 48-bit timestamp hex + 14 base62 chars (exact ID encoding from packages/opencode/src/id/id.ts)
  4. Four session headers; x-opencode-request must NOT be sent (403)
  5. stream: true forced upstream — non-stream clients get local SSE→JSON aggregation
  6. tools must include bash, glob, grep, read with non-empty parameters.properties — stubs are injected automatically, and tool_choice: none is set when the client brought no tools

⚠️ Fragility: this is an adversarial compat layer, not a stable API. OpenCode has tightened the gate five times between 2026-09-17 and 2026-10-15. If free models start returning 403 FreeTierError, check the compat doc above and re-pin the version via the OC_UA_VERSION secret / env var.

Deploy to Cloudflare Workers

Option A — button above (Deploys to Cloudflare from this repo).

Option B — CLI:

git clone https://github.com/nullstacks/opencode-gateway
cd opencode-gateway
npx wrangler login
npx wrangler deploy

Secrets (optional)

Secret Purpose
ZEN_API_KEY fallback Zen key — unlocks all 85 paid models for keyless callers
GATEWAY_KEY require callers to present this key (lock public deployments)
OC_UA_VERSION override the pinned opencode CLI version
npx wrangler secret put ZEN_API_KEY

Run the Python server

pip install -r requirements.txt          # flask + httpx
python3 server.py                        # serves on 0.0.0.0:8080 (PORT/HOST to override)

Production options:

gunicorn -w 4 -b 0.0.0.0:8080 server:app
flask --app server run --host 0.0.0.0 --port 8080

A Dockerfile is included: docker build -t opencode-gateway . && docker run -p 8080:8080 opencode-gateway.

Environment variables (Python, optional)

Variable Purpose
ZEN_API_KEY fallback Zen key — unlocks paid models for keyless callers
GATEWAY_KEY require callers to present this key (lock public deployments)
OC_UA_VERSION override the pinned opencode CLI version
PORT / HOST bind address (default 0.0.0.0:8080)

Usage

# OpenAI client — free model, no key
curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"glm-5.3-flash-free","messages":[{"role":"user","content":"hi"}]}'

# Paid model — pass your Zen key from https://opencode.ai/auth
curl http://localhost:8080/v1/chat/completions \
  -H "Authorization: Bearer <zen-key>" \
  -d '{"model":"gpt-5.5","messages":[{"role":"user","content":"hi"}]}'

# Claude Code
export ANTHROPIC_BASE_URL=http://localhost:8080
export ANTHROPIC_API_KEY=free
export ANTHROPIC_MODEL=glm-5.3-flash-free

Key resolution order: X-Zen-Key header → ?key= → Authorization: Bearer → x-api-key → ZEN_API_KEY env. public / empty = free tier.

License

MIT

About

Use OpenCode models (incl. free tier) in any harness — OpenAI/Anthropic-compatible Cloudflare Worker

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages