# Introducing opencode-aipass

> A dynamic opencode plugin for aipass-proxy that discovers AIPass models from GET /v1/models at startup — no more hand-maintained models in opencode.json.

I built [aipass-proxy](/projects/aipass-proxy) to expose [AIPass](https://de.aipass.net) through the OpenAI `GET /v1/models` and `POST /v1/chat/completions` endpoints. The first guide — [Using aipass-proxy with opencode](/writings/using-aipass-proxy-with-opencode) — showed how to wire it to [opencode](https://opencode.ai) with a manual `provider.aipass.models` block in `opencode.json`.

That worked, but it had a flaw: you had to copy model IDs by hand, and they drifted. When AIPass added `gpt-5.6-sol` or renamed `gemini-3.1-flash-lite`, you had to edit the file again. [opencode-aipass](https://github.com/pyyupsk/aipass-proxy/tree/main/plugin) fixes that. It fetches the list from your local proxy and registers the provider for you.

## Important Warning

Same warning as before. AIPass terms prohibit use of the platform API outside the official interface ([section 3.4](https://aipass.go.th/term-and-cond-th)). This proxy — and the plugin that talks to it — uses the API outside that interface. AIPass can suspend your account. Not legal advice — read the terms before you use either project.

## The problem with the old way

The original setup looked like this in `opencode.json`:

```json
{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "aipass": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "AIPass",
      "options": {
        "baseURL": "http://localhost:47871/v1",
        "apiKey": "unused"
      },
      "models": {
        "gemini-3.1-flash-lite": { "name": "Gemini 3.1 Flash Lite (Unlimited)" },
        "claude-opus-5@azure": { "name": "Claude Opus 5" },
        "gpt-5.6-terra": { "name": "GPT-5.6 Terra" }
      }
    }
  }
}
```

Every key under `models` had to match an ID from `GET /v1/models` exactly. The proxy already knew the real list — you were just copying it. The plugin removes that duplication.

## What the plugin does

`opencode-aipass` `v0.1.1` is a provider plugin for opencode v2. On startup it calls `GET /v1/models` on your proxy, turns the response into `Model.Info` entries with `tools: true` (the proxy emulates tool calls via `<tool_call>`), and registers them with `ctx.provider.transform`. opencode then shows them in the picker as `aipass/<model-id>`.

It then keeps the list in sync:

- Polls `GET /v1/models` every 60 seconds. If the id set changed, it calls `ctx.provider.reload`.
- Persists the last good list in `ctx.storage`. If the proxy is offline at next startup, it restores that cached list and logs a warning instead of showing nothing.
- Exposes a manual refresh as command `aipass:refresh` (TUI) and tool `aipass_refresh` (for agents).

You no longer edit `opencode.json` when AIPass ships a model.

## Prerequisites

1. [aipass-proxy](/projects/aipass-proxy) `v0.2.1` installed and running at `http://localhost:47871` (or your custom port). See the project page for `curl -sL https://fasu.dev/aipass-proxy | bash`, `aipass-proxy setup`, and `aipass-proxy start`.
2. opencode v2 and `@opencode/plugin` `^2.0.8` (peer `effect` `^4.0.0-rc.112`, `zod` `^4.1.8`).

Verify the proxy first:

```bash
curl http://localhost:47871/v1/models | head -c 500
```

If that returns `{"data": [...]}` you are ready for the plugin.

## Install

### Option A — Project-local (fastest, no publish)

This is how the [aipass-proxy repo](https://github.com/pyyupsk/aipass-proxy) itself uses the plugin. Point opencode at the source file:

```jsonc
{
  "$schema": "https://opencode.ai/config.json",
  "plugins": ["./plugin/src/index.ts"],
  "model": "aipass/gpt-5.6-sol"
}
```

Use this when you clone `pyyupsk/aipass-proxy` and want the plugin without publishing. The provider id is `aipass` and the model id is whatever the proxy returns — e.g. `aipass/gpt-5.6-sol`.

### Option B — Published package

If you want the plugin in your own project without the proxy repo:

```bash
# one-time publish from the proxy repo
cd plugin && npm publish
# then in your project
opencode plugin add opencode-aipass
```

```jsonc
{
  "$schema": "https://opencode.ai/config.json",
  "plugins": ["opencode-aipass"],
  "model": "aipass/gpt-5.6-sol"
}
```

Both options behave the same. Pick A for local dev, B for sharing across projects.

## Options

You can override the defaults:

```jsonc
{
  "plugins": [{
    "package": "./plugin/src/index.ts",
    "options": {
      "baseURL": "http://localhost:47871/v1",
      "name": "AIPass",
      "refreshInterval": 60000,
      "timeoutMs": 5000
    }
  }]
}
```

- `baseURL` — proxy base URL. Default `http://localhost:47871/v1`.
- `name` — provider display name in opencode. Default `AIPass`.
- `refreshInterval` — ms between `GET /v1/models` polls. Default `60000`.
- `timeoutMs` — fetch timeout in ms. Default `5000`.

Change `baseURL` if you run the proxy on a different port or expose it on your LAN.

## How it works (in 6 steps)

1. Calls `GET {baseURL}/models` with `AbortSignal.timeout(timeoutMs)`. On failure, keeps the previous list and warns to console.
2. Builds a provider via `@opencode/ai/providers/openai-compatible` with `baseURL` and `apiKey: "unused"`, advertising `capabilities: { tools: true, input: ["text"], output: ["text"] }`.
3. Registers with `ctx.provider.transform` — this is what populates the model picker.
4. Persists `models.map(m => m.id)` to `ctx.storage`. On next cold start with proxy offline, restores from storage.
5. Every `refreshInterval` re-fetches and diffs id sets. Only calls `ctx.provider.reload` when the set actually changed (avoids noisy events).
6. Adds `aipass:refresh` and `aipass_refresh` for on-demand reloads (`aipass: 23 models`).

Source is ~130 lines in [`plugin/src/index.ts`](https://github.com/pyyupsk/aipass-proxy/blob/main/plugin/src/index.ts) — easy to audit.

## Try the refresh

In the opencode TUI, open the command palette and run `aipass:refresh`. From an agent, call the tool:

```json
{ "tool": "aipass_refresh", "input": {} }
```

Response:

```json
{ "content": "aipass: 23 models" }
```

Add a model in AIPass, run the command, and it appears without restarting opencode.

## Migrate from the manual config

If you followed the first guide:

1. Delete the entire `provider.aipass` block from `opencode.json` (including `models`).
2. Add the `plugins` entry from above.
3. Set `"model": "aipass/<id>"` to any id from `curl http://localhost:47871/v1/models`.
4. Restart opencode. Run `aipass:refresh` once to prime the cache.

You can keep both configs side-by-side to compare, but the plugin will overwrite a manual `aipass` provider with the same id via `editor.remove(providerID)` before `editor.add`.

## When not to use the plugin

- Proxy not at `http://localhost:47871` and you do not want to set `baseURL`.
- You want a curated subset of models, not the full AIPass list. The plugin registers everything the proxy returns; manual `models` lets you hide entries.
- Offline-first setups where `GET /v1/models` is never reachable and you prefer an explicit list over a cached one.

## Ideas once it is running

Same ideas from the first post, now with less friction:

- Pin `aipass/gemini-3.1-flash-lite` as your default for quick edits; switch to `aipass/claude-opus-5@azure` or `aipass/gpt-5.6-sol` for planning.
- Test Thai-specific models without editing config — they just appear when AIPass makes them available.
- Run `aipass-proxy install-service` on a home server and point every machine's `baseURL` at that host. One plugin, one proxy, every device in sync.

## Where to find it

- Proxy: [pyyupsk/aipass-proxy](https://github.com/pyyupsk/aipass-proxy) — see also [/projects/aipass-proxy](/projects/aipass-proxy)
- Plugin: [pyyupsk/aipass-proxy/tree/main/plugin](https://github.com/pyyupsk/aipass-proxy/tree/main/plugin) (`opencode-aipass` `v0.1.1` on npm after `cd plugin && npm publish`)
- Previous guide: [Using aipass-proxy with opencode](/writings/using-aipass-proxy-with-opencode)
- Plugin package: [`plugin/package.json`](https://github.com/pyyupsk/aipass-proxy/blob/main/plugin/package.json)

https://github.com/pyyupsk/aipass-proxy
