Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OpenCode → LiteLLM → Open WebUI

Self-hosted gateway that exposes the models served by the OpenCode Zen API (https://opencode.ai/zen/go/v1) through a LiteLLM proxy, so they can be consumed by Open WebUI (or any OpenAI-compatible client) with a single, unified API key.

LiteLLM translates the OpenCode endpoints into the standard OpenAI API schema, adds an authentication layer (a virtual key), and persists usage/state in PostgreSQL. Open WebUI then points to LiteLLM as if it were a normal OpenAI endpoint and instantly gets the full model catalog.

This repo runs LiteLLM + PostgreSQL via Docker Compose. Open WebUI runs as your own separate instance and connects to the LiteLLM proxy — see Connecting Open WebUI.


Architecture / Flow

flowchart LR
    subgraph Client["🖥️ Client"]
        UI["Open WebUI<br/>(github.com/open-webui/open-webui)"]
    end

    subgraph Docker["🐳 Docker Compose stack (this repo)"]
        LL["LiteLLM Proxy<br/>:4000"]
        DB[("PostgreSQL 16<br/>litellm_db")]
    end

    subgraph Upstream["☁️ Upstream provider"]
        OC["OpenCode Zen API<br/>opencode.ai/zen/go/v1"]
    end

    UI -->|"OpenAI-compatible request<br/>Bearer LITELLM_MASTER_KEY"| LL
    LL -->|"reads config &amp; routes model"| OC
    OC -->|"authenticated with<br/>OPENCODE_API_KEY"| LL
    LL <-->|"keys, spend, state"| DB
    LL -->|"streamed response"| UI
Loading

In one sentence: Open WebUI talks to LiteLLM with the master key; LiteLLM forwards each request to OpenCode using the real provider key, normalizes the response, and streams it back.


Prerequisites


Get an OpenCode Go subscription

The models exposed by this gateway come from OpenCode Go, a low-cost coding plan. Subscribe at https://opencode.ai/ (Go section).

The same subscription powers both use cases this project targets: your self-hosted chat (Open WebUI) and coding inside OpenCode/VSCode — one plan, no separate API provider needed.

Once subscribed, open your OpenCode dashboard. The Go tab shows your usage (rolling / weekly / monthly), and the API Keys tab is where you get the key:

OpenCode Go dashboard — usage and API Keys

In API Keys you can either use the default key or generate a new one. Copy it — this is the value you put in OPENCODE_API_KEY in your .env.


Quick start

1. Clone and configure environment

git clone https://github.com/Baronco/opencode-openwebui-gateway.git
cd opencode-openwebui-gateway
cp .env.example .env

Edit .env and fill in your real values:

# Your OpenCode Zen API key (the upstream provider key)
OPENCODE_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# The "virtual" master key clients use to talk to LiteLLM.
# Choose any strong secret — this is what you paste into Open WebUI.
LITELLM_MASTER_KEY=sk-my-strong-master-key

2. Start the stack

docker compose up -d

This launches two services:

ServiceImagePortPurpose
litellmdocker.litellm.ai/berriai/litellm:main-latest4000OpenAI-compatible proxy over OpenCode
dbpostgres:16Stores keys, spend tracking and state

Check it is up:

docker compose ps
docker compose logs -f litellm

3. Verify the proxy

List the models LiteLLM is exposing (use your LITELLM_MASTER_KEY):

curl http://localhost:4000/v1/models \
  -H "Authorization: Bearer $LITELLM_MASTER_KEY"

Send a test completion:

curl http://localhost:4000/v1/chat/completions \
  -H "Authorization: Bearer $LITELLM_MASTER_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"glm-5.2","messages":[{"role":"user","content":"hi"}],"max_tokens":5}'

4. Log into the LiteLLM Admin UI and create a virtual key

Open WebUI should not authenticate with the master key directly. Instead, you create a scoped virtual key in LiteLLM and use that. Open the LiteLLM admin panel at http://localhost:4000/ui and log in with:

  • Username: admin
  • Password: your LITELLM_MASTER_KEY (the value you set in .env)

LiteLLM Admin UI login

Then, following the official LiteLLM × Open WebUI tutorial:

  1. (Optional) Create a Team to group access.
  2. Go to Virtual Keys and click + Create New Key. Give it an alias (e.g. OWUI) and choose which models the key may use — these are exactly the models Open WebUI will see.
  3. Copy the generated key (starts with sk-…). This is the key you paste into Open WebUI in the next section.

LiteLLM — Virtual Keys / Create New Key


Connecting Open WebUI

Install Open WebUI by following the official repository — https://github.com/open-webui/open-webui. It offers several installation methods (Docker, pip, Kubernetes, etc.) across different versions; pick the one that suits your environment. This repo only provides the LiteLLM gateway that Open WebUI connects to.

Once Open WebUI is running, go to Settings → Admin Settings → Connections → OpenAI API and click the + to add a new connection:

Open WebUI — Connections settings

Fill in the connection details:

FieldValue
URLhttp://host.docker.internal:4000
AuthBearer → the virtual key you created in step 4
Model IDsleave empty to auto-import all models the key has access to

Open WebUI — Edit Connection dialog

Use the virtual key here, not LITELLM_MASTER_KEY. The master key is only for the Admin UI / key management; the virtual key is what scopes which models this Open WebUI connection can use.

Use http://host.docker.internal:4000 when Open WebUI runs in its own container and needs to reach LiteLLM on the host. If both run in the same Docker network, use the service name instead: http://litellm:4000. If Open WebUI runs directly on the host, use http://localhost:4000.

After saving, the OpenCode model catalog appears in the model picker.

Reference: https://docs.litellm.ai/docs/tutorials/openweb_ui


Available models

The model catalog is defined in litellm_config.yaml. Each entry maps a friendly model_name to the upstream OpenCode model. Current families:

FamilyModels
MiniMaxminimax-m3, minimax-m2.7, minimax-m2.5
Kimikimi-k2.7-code, kimi-k2.6, kimi-k2.5
GLMglm-5.2, glm-5.1, glm-5
DeepSeekdeepseek-v4-pro, deepseek-v4-flash
Qwenqwen3.7-plus, qwen3.6-plus, qwen3.5-plus
MiMomimo-v2.5-pro, mimo-v2.5, mimo-v2-pro, mimo-v2-omni
Hunyuanhy3-preview

📄 Full model catalog: opencode_go_models.pdf — a reference table (as of June 26, 2026) characterizing every model available on OpenCode Go. The descriptions were AI-generated as a reference, so verify against the live catalog before relying on them.

Adding / updating models

Query the upstream catalog directly from OpenCode:

curl https://opencode.ai/zen/go/v1/models \
  -H "Authorization: Bearer $OPENCODE_API_KEY"

Probe which models are actually reachable (returns HTTP status per model):

for model in minimax-m3 minimax-m2.7 minimax-m2.5 kimi-k2.7-code kimi-k2.6 \
  kimi-k2.5 glm-5.2 glm-5.1 glm-5 deepseek-v4-pro deepseek-v4-flash \
  qwen3.7-max qwen3.7-plus qwen3.6-plus qwen3.5-plus mimo-v2.5-pro mimo-v2.5 \
  mimo-v2-pro mimo-v2-omni hy3-preview; do
  echo -n "Testing $model... "
  curl -s -o /dev/null -w "%{http_code}\n" \
    https://opencode.ai/zen/go/v1/chat/completions \
    -H "Authorization: Bearer $OPENCODE_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"model\":\"$model\",\"messages\":[{\"role\":\"user\",\"content\":\"hi\"}],\"max_tokens\":5}"
done

To expose a new model, add a block to litellm_config.yaml:

  - model_name: <friendly-name>
    litellm_params:
      model: openai/<upstream-model-id>
      api_base: https://opencode.ai/zen/go/v1
      api_key: os.environ/OPENCODE_API_KEY
      additional_drop_params: ["reasoningSummary"]

Then reload the proxy:

docker compose restart litellm

Configuration reference

.env

VariableDescription
OPENCODE_API_KEYUpstream OpenCode Zen provider key. Used by LiteLLM to call the API.
LITELLM_MASTER_KEYAdmin/master key for LiteLLM. Used to log into the Admin UI (/ui) and to mint virtual keys. Open WebUI should use a virtual key, not this one.

docker-compose.yml

Defines the litellm proxy (port 4000) and the db (PostgreSQL 16) service. The DATABASE_URL and Postgres credentials are wired between the two services; the LiteLLM config file is mounted read-only at /app/config.yaml.

litellm_config.yaml

Holds the model_list (model routing) and general_settings.master_key (bound to LITELLM_MASTER_KEY). additional_drop_params: ["reasoningSummary"] strips a non-standard field that the upstream models would otherwise reject.


Operations

docker compose up -d          # start in background
docker compose ps             # status
docker compose logs -f litellm# follow proxy logs
docker compose restart litellm# reload after editing litellm_config.yaml
docker compose down           # stop (keeps the DB volume)
docker compose down -v        # stop and DELETE the Postgres volume

Troubleshooting

  • 401 Unauthorized from LiteLLM — the client key doesn't match LITELLM_MASTER_KEY. Confirm the value in .env and that you restarted the stack after changing it.
  • 401/403 from upstreamOPENCODE_API_KEY is missing or invalid.
  • Open WebUI can't reach LiteLLM — using localhost from inside a container points to the container itself. Use host.docker.internal:4000 (or the service name on a shared network).
  • A model returns errors — confirm it still exists upstream with the probe loop above; the catalog changes over time.

About

LiteLLM gateway that exposes your OpenCode Zen models to Open WebUI

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors