# aipass-proxy

> An OpenAI-compatible chat-completions proxy in front of AIPass, so tools like opencode can use it as a custom provider.

A local proxy that presents [AIPass](https://de.aipass.net) through the standard OpenAI API format. Point any OpenAI-compatible client at the proxy and it forwards requests to AIPass. Implements `GET /v1/models` and `POST /v1/chat/completions`.

## Warning

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 uses the API outside that interface. If you use it, AIPass can suspend your account. Not legal advice — read the terms before you use this project.

## Features

- OpenAI-compatible `GET /v1/models` (real model list from AIPass) and `POST /v1/chat/completions`.
- Tool calling via `<tool_call>` emulation, parallel tool calls, and re-injected tool prompt every turn.
- Structured output with JSON Schema and tool-call retry.
- Streaming with error surfacing, plus Zod validation for request bodies.
- One AIPass conversation per opencode session (keyed on `x-session-id`), oldest evicted when full.
- Detects AIPass session expiry and returns a clear `401`.
- Binds to `localhost` only and evades WAF traversal blocks on tool-result round-trips.
- [opencode plugin](https://github.com/pyyupsk/aipass-proxy/tree/main/plugin) that fetches the model list from the proxy and registers the provider — no manual model list, auto-refresh every 60s, `aipass:refresh` command and `aipass_refresh` tool.

## Install

```sh
curl -sL https://fasu.dev/aipass-proxy | bash
```

Detects OS and architecture and installs the latest binary to `~/.local/bin`. No Bun, Node.js, or clone required.

Set `INSTALL_DIR` to change the install directory, or `VERSION` to pin a tag (e.g. `v0.2.1`):

```sh
INSTALL_DIR=~/.local/bin VERSION=v0.2.1 curl -sL https://fasu.dev/aipass-proxy | bash
```

Prebuilt binaries are also on the [Releases](https://github.com/pyyupsk/aipass-proxy/releases) page (`aipass-proxy-linux-x64`, `linux-arm64`, `darwin-x64`, `darwin-arm64`) with SHA-256 verification.

## Setup

```sh
aipass-proxy setup
```

Asks for your AIPass session token and a port. The token is the `__Secure-ai_passport_auth.session_token` cookie from an authenticated session at [de.aipass.net](https://de.aipass.net) (DevTools → Application/Storage → Cookies). Input is masked. Port defaults to `47871`. Values are written to `~/.config/aipass-proxy/.env` with `600` permissions.

## Run

```sh
aipass-proxy start
```

Listens at `http://localhost:47871` (or your custom port).

For a background service that starts at login:

```sh
aipass-proxy install-service
# then run the command it prints:
systemctl --user enable --now aipass-proxy   # Linux
launchctl load ~/Library/LaunchAgents/com.aipass-proxy.plist   # macOS
```

## Use

```sh
curl http://localhost:47871/v1/models

curl http://localhost:47871/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"gemini-3.1-flash-lite","messages":[{"role":"user","content":"hello"}]}'
```

Point any OpenAI client at `http://localhost:47871/v1`. Detailed guide: [Using aipass-proxy with opencode](/writings/using-aipass-proxy-with-opencode).

## opencode Plugin

[`plugin/`](https://github.com/pyyupsk/aipass-proxy/tree/main/plugin) holds [`opencode-aipass`](https://www.npmjs.com/package/opencode-aipass), published on npm as `v0.1.1` — a dynamic provider for opencode v2 that discovers models from `GET /v1/models` and registers `aipass` without hand-maintaining `models` in `opencode.json`. Keeps the list in sync, restores the last cached list when the proxy is offline at startup, and exposes a refresh command and tool.

### When to use

Use the plugin when the proxy runs at `http://localhost:47871`. New models appear after the next refresh; if the proxy is offline at startup, the plugin shows the last stored ids from `ctx.storage`. If you prefer not to use a plugin, list models by hand in `opencode.json` instead — see the history of [`opencode.json`](https://github.com/pyyupsk/aipass-proxy/blob/main/opencode.json) for an example.

### Install

**Project-local (no publish):**

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

Provider id is `aipass`; model id is whatever `GET /v1/models` returns.

**From npm:**

```sh
opencode plugin add opencode-aipass
```

```jsonc
{
  "plugins": ["opencode-aipass"]
}
```

### Options

```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 (default `AIPass`).
- `refreshInterval` — ms between `GET /v1/models` polls (default `60000`).
- `timeoutMs` — request timeout in ms (default `5000`).

### How it works

1. On startup calls `GET /v1/models` at `baseURL`; on failure logs a warning and keeps the previous list.
2. Creates provider via `@opencode/ai/providers/openai-compatible` with `baseURL` + `apiKey: "unused"` and advertises `tools: true` (proxy emulates tool calls with `<tool_call>`).
3. Registers models via `ctx.provider.transform` — opencode shows them in the picker.
4. Polls `GET /v1/models` every `refreshInterval`; if the id set changed, calls `ctx.provider.reload`.
5. Stores last good ids in `ctx.storage` for offline startup restores.
6. Manual refresh via command `aipass:refresh` (TUI) or tool `aipass_refresh` (agent, returns e.g. `aipass: 23 models`).

### Commands and tools

- `aipass:refresh` — refresh model list from proxy.
- `aipass_refresh` — same for agents.

### Requirements

opencode v2, `@opencode/plugin` `^2.0.8`, `effect` `^4.0.0-rc.112`, and a running proxy that responds to `GET /v1/models`.

## Update

```sh
curl -sL https://fasu.dev/aipass-proxy | bash -s update
```

## Uninstall

```sh
systemctl --user disable --now aipass-proxy   # Linux, if service installed
launchctl unload ~/Library/LaunchAgents/com.aipass-proxy.plist   # macOS, if service installed

curl -sL https://fasu.dev/aipass-proxy | bash -s uninstall
```
