TUTORIAL T-002 · AI ROUTER · INFRA

Cara Memakai 9Router

9Router adalah local proxy yang sit between AI coding tools (Claude Code, Cursor, Codex) dan provider LLM. Dengan token saver, auto-fallback, multi-account round-robin. Tutorial ini cover full lifecycle dari install sampai production rotation.

PORT: 20128 VERSION: 0.4.71 STEPS: 07 LEVEL: Intermediate
— TL;DR

Install via npm → jalanin di server pakai 9router -p 20128 --no-browser -t -l → dashboard di localhost:20128/dashboard (password default 123456) → add provider (Kiro, Xiaomi, dll) → setup proxy if needed → connect AI tools ke localhost:20128/v1. Multi-account = sticky session + round-robin via dashboard.

STEP 01

Setup & Install di Server

9Router butuh Node.js 18+. Install via npm sebagai global package, jalanin sebagai background daemon biar tetap up.

# Prerequisite: Node.js 18+ $ node --version v20.10.0 # Install 9router globally $ npm install -g 9router # Verify install $ 9router --version 0.4.71

Jalankan sebagai daemon (headless mode wajib di server, biar gak exit langsung):

# Production: tray mode + log + no browser $ 9router -p 20128 --no-browser -t -l # Atau pake daemon mode $ 9router serve --port 20128 --no-open --daemon
— PITFALL

Tanpa flag -t (tray mode), proses 9router akan exit dalam beberapa detik dengan pesan "Exiting...". Di server headless WAJIB pake -t.

Verify running:

$ ss -tlnp | grep 20128 LISTEN 0 511 0.0.0.0:20128 *:* users:(("node",pid=12345)) $ curl http://localhost:20128/api/health {"status":"ok","version":"0.4.71"}

Buka dashboard: http://your-server:20128/dashboard (default password: 123456). Ganti password di Settings.

STEP 02

Setup Proxy di 9Router

Proxy dipake biar request ke provider LLM lewat IP residential (anti rate-limit, bypass geo-block). Pake hasil dari tutorial T-001.

  1. Dashboard → Settings → Proxy
  2. Enable "Use proxy for outbound requests"
  3. Pilih protocol: HTTP atau SOCKS5
  4. Paste proxy URL format: http://user:pass@gateway:port
  5. Test connection → Save
# Format yang accepted di 9router proxy field http://user:[email protected]:6060 http://user-session-abc123:[email protected]:6060 socks5://user:[email protected]:7777
— TIPS

Pake sticky session ID per provider biar IP konsisten — less ban risk. Untuk rotation aggressive, ganti session di setiap restart 9router.

STEP 03

Import API Key (Single Provider)

9Router support 40+ provider. Setiap provider butuh API key sendiri. Mulai dari satu dulu untuk test.

Add provider via dashboard:

  1. Dashboard → Providers+ Add Provider
  2. Pilih provider (e.g. Xiaomi MiMo, Kiro AI, OpenRouter, dll)
  3. Pilih connection type: API Key atau OAuth
  4. Paste API key, beri name (label), save
— PITFALL: Xiaomi MiMo

Kalau API key lo prefix tp- (token plan), pake provider type "Xiaomi MiMo (Token Plan)" — BUKAN regular "Xiaomi MiMo". Salah pilih = 401 Invalid API Key.

— PITFALL: Kiro AI

Kiro punya 2 auth: API Key (ksk_*) untuk CLI saja, dan OAuth Refresh Token untuk 9router. ksk_* TIDAK bisa dipake di 9router — pake AWS Builder ID OAuth flow.

STEP 04

Bikin Command Setup untuk AI Agent

Setelah 9router jalan, configure AI tool (Claude Code, Cursor, Codex, Hermes Agent) buat point ke 9router — BUKAN langsung ke provider.

Get auth token:

$ cat ~/.9router/auth/* | head -c 64 a3f2b1c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1

Hermes Agent (~/.hermes/config.yaml):

model: default: kr/claude-sonnet-4 provider: 9router providers: 9router: api_key: your-9router-auth-token # dari ~/.9router/auth/ api_mode: chat_completions base_url: http://localhost:20128/v1 default_model: kr/claude-sonnet-4

Claude Code / Cursor / Codex: set environment variable atau config file:

$ export ANTHROPIC_BASE_URL="http://localhost:20128/v1" $ export ANTHROPIC_API_KEY="your-9router-auth-token"
— MODEL PREFIX

Setiap provider pake prefix model: kr/ Kiro, xm/ Xiaomi, or/ OpenRouter. Misal kr/claude-opus-4.8, xm/mimo-v2.5-pro. Cek list lengkap di dashboard → Models.

STEP 05

Import Bulk Proxy

Untuk multi-account ops, lo butuh banyak proxy yang assigned ke setiap connection. Pake proxies.txt dari tutorial T-001.

9Router belum support bulk proxy import via UI native, tapi bisa di-inject via SQLite langsung:

# Backup DB dulu $ cp ~/.9router/db/data.sqlite ~/.9router/db/data.sqlite.bak # Inject bulk proxies via Python $ python3 inject_proxies.py
# inject_proxies.py import sqlite3, json from pathlib import Path db = sqlite3.connect(Path.home() / ".9router/db/data.sqlite") proxies = Path("proxies.txt").read_text().strip().split("\n") for i, proxy in enumerate(proxies): db.execute( "INSERT INTO proxies (id, url, label, active) VALUES (?, ?, ?, 1)", (f"proxy-{i}", proxy, f"residential-{i}") ) db.commit() print(f"Injected {len(proxies)} proxies")
— IMPORTANT

Restart 9router setelah modify SQLite (kill $(cat ~/.9router/runtime/.pid); 9router -p 20128 --no-browser -t -l). Schema bisa berubah antar versi — cek dulu via sqlite3 ~/.9router/db/data.sqlite ".schema".

STEP 06

Setup Combos (Provider + Proxy + Account)

Combo = pairing antara API key, proxy, dan account label. Per kombinasi punya quota tracking sendiri — 9router auto-skip combo yang udah hit limit.

Pattern combo yang umum:

Total: 300 req/hari dengan zero overlap = anti-rate-limit auto.

# Dashboard → Providers → [Provider] → Connections # Tambah connection per combo: Connection: "luke-account-1" API Key: ksk_xxx... Proxy: http://user-s1:pass@gateway:6060 Label: "Account A" Quota: 100 req/hari Connection: "luke-account-2" API Key: ksk_yyy... Proxy: http://user-s2:pass@gateway:6060 Label: "Account B" Quota: 100 req/hari
STEP 07

Rotate Proxy & Round-Robin Strategy

9Router punya 3 strategy buat distribute traffic antar combo:

# Settings → Routing Strategy 1. Round-Robin → Cycle equal antar combo (default) 2. Random → Pilih combo random tiap request 3. Sticky → User-A pake combo-A terus, anti-fingerprint 4. Quota-Aware → Pilih combo yang quota-nya paling banyak available 5. Cheapest-First → Free tier dulu, fallback ke cheap, fallback ke paid

Pattern recommended untuk production:

  1. Cheapest-First sebagai primary strategy
  2. Auto-fallback kalau hit rate-limit (subscription → cheap → free)
  3. Sticky per chat session (biar context konsisten dari satu provider)
— RTK TOKEN SAVER

Aktifin di Settings → RTK. 9router bakal auto-compress tool_result output (git diff, grep, ls) sebelum kirim ke provider. Saving 20-40% token — free win.

Monitoring rotation:

$ curl http://localhost:20128/api/stats { "total_requests": 1247, "by_combo": { "luke-account-1": 421, "luke-account-2": 418, "luke-account-3": 408 }, "tokens_saved": 28491, "avg_latency_ms": 612 }
— COMMON PITFALLS

Things That Break

Mostly aku belajar from production scars. Lo gak perlu repeat.

Process exit langsung

Tanpa -t flag, 9router exit dalam detik di headless server. Selalu pake: 9router -p 20128 --no-browser -t -l

Auth token salah

Auth token yang dipake AI tools BUKAN dashboard password (123456). Token hex ada di ~/.9router/auth/ — panjang ~64 chars.

OAuth provider lost on restart

Connection OAuth (Kiro, etc) GAK persisten di SQLite. Setelah restart, harus re-add via dashboard. API key providers (Xiaomi, OpenRouter) survive restart.

Port 20128 conflict dengan OmniRoute

Default port sama persis. Gak bisa run dua-duanya. Uninstall OmniRoute dulu atau pakai port berbeda: 9router -p 20129 ...

Kiro CLI refresh_token ≠ IDE refresh_token

Token dari ~/.local/share/kiro-cli/data.sqlite3 GAK akan work di 9router Import Token. CLI pake AWS SSO DeviceCode flow, 9router butuh desktop IDE refresh token. Solusi: pake AWS Builder ID OAuth flow di dashboard.

429 rate-limit dari upstream

Multi-account masih kena 429 dari Kiro/provider kalau ramean. Set delay antar request (Settings → Throttle) atau gunakan sticky session lebih lama biar kelihatan natural.