# Free IDE Proxy OpenAI/Anthropic-compatible proxy that aggregates **free** models from [OpenCode Zen](https://opencode.ai) and [Kilo Code](https://kilo.ai) under a single endpoint. Use DeepSeek V4 Flash, StepFun, Nemotron, OpenRouter free, and more — for free — in any OpenAI-compatible tool (Cursor, Claude Code, Continue, Cline, etc.). ## How it works ``` Your tool → free-ide-proxy (localhost:6446) → { opencode.ai/zen/v1 | api.kilo.ai/api/gateway } ``` The proxy routes by model name to the matching backend, injecting the required headers. OpenCode Zen expects `x-opencode-*` headers with `Bearer public`; Kilo's gateway needs no auth for free models. Your tools talk standard OpenAI protocol to the proxy; the proxy handles the rest. ### Auto rate-limit jailing When an upstream starts returning HTTP 429 (rate limit) for a model, the proxy automatically **cages** it — the model disappears from `/v1/models` immediately. A background checker re-probes caged models every 30 minutes; if they recover, they reappear. This means your client just needs to query `/v1/models` before each request and pick an available model. No hardcoded model names, no manual retries. ## Quick Start ```bash # Build go build -o free-ide-proxy . # Run (no auth) ./free-ide-proxy # Run with API key protection ./free-ide-proxy -api-key "your-secret-key" # Or via env var export OPENCODE_PROXY_KEY="your-secret-key" ./free-ide-proxy ``` The server starts on `http://127.0.0.1:6446`. ## CLI Flags | Flag | Default | Description | |------|---------|-------------| | `-port` | `6446` | Server port | | `-host` | `127.0.0.1` | Server host | | `-api-key` | (none) | API key to protect the proxy | | `-version` | — | Show version and exit | Also reads `OPENCODE_PROXY_KEY` environment variable if `-api-key` is not set. ## Endpoints | Method | Path | Description | |--------|------|-------------| | `GET` | `/health` | Health check (version, active model count, auth status) | | `GET` | `/v1/models` | List currently **active** (not rate-limited) free models | | `GET` | `/v1/models/{id}` | Single model detail (404 if rate-limited) | | `POST` | `/v1/chat/completions` | OpenAI Chat Completions (streaming + non-streaming) | | `POST` | `/v1/messages` | Anthropic Messages API | | `POST` | `/v1/v1/messages` | Workaround for Claude Code double-path bug | ### Authentication If `-api-key` is set, all requests require one of: - `Authorization: Bearer ` - `x-api-key: ` ## Available Models ### OpenCode Zen (5 models) — `opencode.ai/zen/v1` | Model ID | Aliases | Context | Max Output | |----------|---------|---------|------------| | `deepseek-v4-flash-free` | `deepseek`, `deepseek-v4`, `ds` | 1M | 384K | | `big-pickle` | `pickle` | 200K | 32K | | `mimo-v2.5-free` | `mimo`, `mimo-v2.5`, `xiaomi` | 1M | 32K | | `north-mini-code-free` | `north`, `north-mini`, `cohere` | 256K | 64K | | `nemotron-3-ultra-free` | `nemotron`, `nemotron-3`, `nvidia` | 1M | 16K | **API auth:** `Bearer public` (no real token needed). ### Kilo gateway (4 models) — `api.kilo.ai/api/gateway` | Model ID | Aliases | Context | Max Output | |----------|---------|---------|------------| | `stepfun/step-3.7-flash:free` | `stepfun`, `stepfun-free` | 256K | 32K | | `poolside/laguna-m.1:free` | `poolside`, `poolside-free`, `laguna` | 256K | 32K | | `nvidia/nemotron-3-ultra-550b-a55b:free` | — | 1M | 16K | | `openrouter/free` | `openrouter` | 256K | 32K | **API auth:** None needed for free models. All models support streaming, tool calls, and system messages. Reasoning models (DeepSeek, Nemotron, StepFun) need `max_tokens` ≥ 500 or they return empty content (first tokens go to reasoning). ## Claude Code Claude Code appends `/v1/messages` to `ANTHROPIC_BASE_URL` automatically. Set: ```bash export ANTHROPIC_BASE_URL=http://127.0.0.1:6446 export ANTHROPIC_MODEL=claude-sonnet-4-6 # maps to deepseek-v4-flash-free ``` The proxy also handles `/v1/v1/messages` as a fallback for the double-path issue. Claude model name aliases (Claude Code validates model names client-side): | Claude Model | Maps to | |-------------|---------| | `claude-sonnet-4-6`, `claude-sonnet-4-5`, `claude-sonnet-4` | `deepseek-v4-flash-free` | | `claude-opus-4-8`, `claude-opus-4-5`, `claude-opus-4` | `deepseek-v4-flash-free` | | `claude-haiku-4-5`, `claude-haiku-4` | `north-mini-code-free` | | `claude-3.5-sonnet` | `north-mini-code-free` | | `claude-3.5-haiku` | `big-pickle` | ## Tool Configuration ### Cursor / Continue / Cline - **Base URL**: `http://127.0.0.1:6446/v1` - **API Key**: your proxy key (or empty if no auth) - **Model**: `deepseek-v4-flash-free` (or any alias) ### Any OpenAI SDK ```python from openai import OpenAI client = OpenAI( base_url="http://127.0.0.1:6446/v1", api_key="your-proxy-key" ) response = client.chat.completions.create( model="deepseek-v4-flash-free", messages=[{"role": "user", "content": "Hello!"}] ) ``` ## Deploy on VPS ```bash # Build for Linux GOOS=linux GOARCH=amd64 go build -o free-ide-proxy . # Copy and run scp free-ide-proxy user@vps:/home/user/ ssh user@vps './free-ide-proxy -api-key "secure-key" -host 0.0.0.0' ``` ### systemd service ```ini [Unit] Description=Free IDE Proxy After=network.target [Service] ExecStart=/home/user/free-ide-proxy -api-key "${PROXY_KEY}" -host 0.0.0.0 Restart=always User=user EnvironmentFile=/etc/free-ide-proxy.env [Install] WantedBy=multi-user.target ``` ### Local SSH tunnel ```bash ssh -L 6446:127.0.0.1:6446 user@your-vps ``` Then point your tools at `http://127.0.0.1:6446/v1`. ## Quirks & Gotchas - **No tests** exist yet. All manual testing. - **In-memory only** — session and health state dies on restart. Health map auto-rebuilds via initial scan. - **Health check logs** show rate-limit activity: `sudo journalctl -u free-ide-proxy | grep health` - **Unknown models** are forwarded as-is via the default backend (opencode) — catch-all for new models. - **Reasoning model caveat:** DeepSeek, Nemotron and StepFun need `max_tokens` ≥ 500; with very low values they return empty content. This is model behaviour, not a proxy bug. ## Architecture ``` Client → internal/server/ (HTTP, auth, routing) → internal/proxy/ (model resolve, backend router, session mgmt, forwarding, Anthropic↔OpenAI conversion) → Backend → upstream ``` - **Pure stdlib Go 1.22** — no router, no dependencies beyond stdlib. - **Multi-backend** via `Backend` interface (`internal/proxy/backend.go`). Add a new backend by implementing the interface and registering it in `NewProxy` (`models.go`). - **Model aliases** live in each backend (`opencode.go`, `kilo.go`). - **Auto rate-limit jailing** built into `Models()` — models returning 429 are hidden until they recover. ## License MIT