Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
node_modules/
api-keys.json
*.log
.env
__pycache__/
*.pyc
*.bak
114 changes: 95 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,74 @@ Free AI models from [OpenCode](https://opencode.ai) exposed as standard OpenAI a

One server — works with any tool that speaks OpenAI or Anthropic format: Cursor, Continue, Cline, Claude Code, aider, opencode CLI, raw `curl`, whatever.

## Related projects

All three projects share the same CLI interface (`--port`, `--host`, `--proxy`, `--api-key`) and work together through [llama-swap](https://github.com/mmkeeper/llama-swap):

| Project | Port | Prefix | What |
|---------|------|--------|------|
| [opencode-free-proxy](https://github.com/mmkeeper/opencode-free-proxy) | 6446 | `ocf-` | OpenCode free models (this) |
| [deepseek-free-api](https://github.com/mmkeeper/deepseek-free-api) | 18632 | `dsf-` | DeepSeek free API |
| [mimo-free-proxy](https://github.com/mmkeeper/mimo-free-proxy) | 8788 | `mcf-` | Xiaomi MiMo free API |

## 30-second setup

```bash
git clone https://github.com/bigdata2211it-web/opencode-free-proxy.git
git clone https://github.com/mmkeeper/opencode-free-proxy.git
cd opencode-free-proxy
npm install
node server.mjs
pip install -r requirements.txt
python server.py
```

Done. Server is at `http://localhost:6446`. API keys are in `api-keys.json` (auto-generated on first run).

## CLI arguments

All projects use the same CLI interface:

```bash
python server.py --port 6446 --host 127.0.0.1 --proxy socks5://127.0.0.1:9150 --api-key sk-my-key
```

| Argument | Default | Description |
|----------|---------|-------------|
| `--port` | `6446` | Listen port |
| `--host` | `127.0.0.1` | Listen host |
| `--proxy` | _(none)_ | SOCKS5 proxy (e.g. `socks5://127.0.0.1:9150`) |
| `--api-key` | _(from api-keys.json)_ | API key for client auth |

## Environment variables

| Variable | Default | What |
|----------|---------|------|
| `PROXY_PORT` | `6446` | Server port |
| `HOST` | `127.0.0.1` | Listen host |
| `KEYS_FILE` | `./api-keys.json` | API keys file path |
| `SOCKS5_PROXY` | _(none)_ | SOCKS5 proxy address for upstream requests |

## What you get

| Model | What it is | Reliability |
|-------|-----------|-------------|
| `deepseek-v4-flash-free` | DeepSeek V4 Flash | Solid |
| `big-pickle` | DeepSeek V4 Flash (alias) | Solid |
| `minimax-m2.5-free` | MiniMax M2.5 | Solid |
| `nemotron-3-super-free` | NVIDIA Nemotron 3 Super | Hit or miss |
| `qwen3.6-plus-free` | Qwen 3.6 Plus | Intermittent |
| Model | What it is | Reliability | Works with proxy | Works without proxy |
|-------|-----------|-------------|------------------|---------------------|
| `mimo-v2.5-free` | Xiaomi MiMo v2.5 | Solid | ✅ | ✅ |
| `deepseek-v4-flash-free` | DeepSeek V4 Flash | Solid | ✅ | ✅ |
| `north-mini-code-free` | North Mini Code | Solid | ✅ | ✅ |
| `nemotron-3-ultra-free` | NVIDIA Nemotron 3 Ultra | Solid | ✅ | ⚠️ sometimes fails |
| `big-pickle` | DeepSeek V4 Flash (alias) | Solid | ✅ | ✅ |

All models support streaming, tool calls, and system messages.

### Model name aliases (opencode CLI / Hermes)

When using the proxy with tools that support provider-prefixed model names (opencode CLI, Hermes), use the `ocf-` prefix:

| Tool format | Actual model sent to upstream |
|-------------|------------------------------|
| `ocf-mimo-v2.5-free` | `mimo-v2.5-free` |
| `ocf-deepseek-v4-flash-free` | `deepseek-v4-flash-free` |

The `ocf-` prefix is stripped before forwarding to opencode.ai, so multiple providers (mimo-free-proxy, opencode-free-proxy) can coexist without model name conflicts.

## API

### OpenAI format — `POST /v1/chat/completions`
Expand Down Expand Up @@ -113,10 +158,10 @@ Add to `~/.config/opencode/opencode.json`:
# On your VPS
git clone https://github.com/bigdata2211it-web/opencode-free-proxy.git
cd opencode-free-proxy
npm install
node server.mjs # foreground
pip install -r requirements.txt
python server.py # foreground
# or
nohup node server.mjs > proxy.log 2>&1 & # background
nohup python server.py > proxy.log 2>&1 & # background
```

If your VPS doesn't expose port 6446, use an SSH tunnel:
Expand All @@ -137,7 +182,7 @@ After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/opencode-proxy
ExecStart=/usr/bin/node server.mjs
ExecStart=/usr/bin/python3 server.py
Restart=always
RestartSec=5
Environment=PROXY_PORT=6446
Expand All @@ -150,12 +195,35 @@ WantedBy=multi-user.target
sudo systemctl enable --now opencode-proxy
```

## Environment variables
## SOCKS5 Proxy

| Variable | Default | What |
|----------|---------|------|
| `PROXY_PORT` | `6446` | Server port |
| `KEYS_FILE` | `./api-keys.json` | API keys file path |
Route all upstream requests to opencode.ai through a SOCKS5 proxy.

### CLI argument

```bash
python server.py --proxy 127.0.0.1:9150
python server.py --proxy socks5://user:pass@10.0.0.1:1080
```

### Environment variable

```bash
SOCKS5_PROXY=127.0.0.1:9150 python server.py
SOCKS5_PROXY=socks5://user:pass@10.0.0.1:1080 python server.py
```

CLI `--proxy` takes priority over `SOCKS5_PROXY`. If neither is set, requests go directly.

### systemd with proxy

```ini
Environment=SOCKS5_PROXY=127.0.0.1:9150
```

## llama-swap integration

This server works with [llama-swap](https://github.com/mmkeeper/llama-swap) as a peer. See `config.yaml` in the llama-swap repo for an example.

## How it works

Expand All @@ -169,6 +237,14 @@ Your tool (Cursor, CLI, curl, etc.)
opencode.ai/zen/v1/ ← free tier API
```

### Session persistence

The proxy maintains conversation sessions automatically. It uses a hash of the message prefix to identify which upstream session to reuse, so multi-turn conversations stay coherent without the client managing session IDs.

### Model prefix (`ocf-`)

All models are exposed with an `ocf-` prefix (e.g. `ocf-mimo-v2.5-free`) to avoid conflicts with other providers in tools like Hermes. The prefix is stripped before forwarding to opencode.ai.

The proxy adds `x-opencode-*` authentication headers that the Zen API requires. These were discovered by reverse engineering the opencode binary — without them, even `Authorization: Bearer public` gets rejected with `AuthError`.

### Zen API auth headers (for the curious)
Expand Down
12 changes: 2 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,9 @@
"name": "opencode-free-proxy",
"version": "0.9.0",
"description": "Proxy server for OpenCode free-tier AI models via Zen API",
"type": "module",
"main": "server.mjs",
"main": "server.py",
"scripts": {
"start": "node server.mjs",
"dev": "node --watch server.mjs"
},
"dependencies": {
"express": "^4.21.0"
},
"engines": {
"node": ">=18"
"start": "python server.py"
},
"license": "MIT"
}
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fastapi>=0.115.0
uvicorn>=0.32.0
httpx[socks]>=0.28.0
Loading