Skip to main content
Glama
README.md
# mcp-vision-image-fadhli

MCP server untuk analisis gambar lewat **[9router](https://github.com/decolua/9router)** — dengan **penemuan otomatis model vision yang benar-benar bekerja di mesin Anda**.

Tidak perlu daftar model hardcoded. Tidak perlu API key Google. Tidak ada quota free tier.

---

## Kenapa perlu penemuan otomatis?

9router mengekspos ratusan model, dan katalognya punya flag `capabilities.vision`. **Flag itu tidak bisa dipercaya.**

Diukur pada satu mesin (24 Sep 2026):

| | |
|---|---|
| Model di katalog | 824 |
| Mengklaim `vision: true` | 468 |
| **Benar-benar bisa memproses gambar** | **segelintir** |

Sampel 50 model yang mengklaim vision: hanya 4 yang menjawab benar. Sisanya gagal karena:

- `401/403` — API key provider mati
- `402` — kredit habis
- `5xx` — error upstream (dibungkus 9router jadi 503)
- **`200` dengan `content` kosong** — paling menyesatkan: HTTP sukses, tapi tidak ada jawaban
- timeout

**Yang penting:** penyebabnya hampir selalu **provider**, bukan model. Dan karena setiap instalasi 9router punya provider & akun yang berbeda, daftar model yang bekerja **tidak bisa di-hardcode** — harus ditemukan di mesin tempat server berjalan.

---

## Cara kerja

```
analyze_image
   │
   ├─ 1. Coba model eksplisit / env ROUTER9_MODEL / cache / default
   │     └─ berhasil? selesai. (kasus umum, cepat)
   │
   └─ 2. Semua gagal → pindai mesin ini
         ├─ sapu SATU model per provider (gelombang 1)
         ├─ provider hidup? perdalam di gelombang berikutnya
         ├─ uji pakai gambar 3 kotak, nilai jawabannya
         └─ simpan hasil → pakai model tercepat
```

**Mengapa menyapu provider dulu:** kegagalan itu soal provider. Menguji 5 model dari provider yang sama itu sia-sia — kalau providernya mati, kelimanya mati. Gelombang 1 mengambil satu model per provider, jadi berapa pun jumlah providernya, sekali jalan langsung ketahuan mana yang hidup.

**Model dinilai secara objektif.** Gambar uji berisi 3 kotak (merah, hijau, biru). Model yang benar-benar bisa melihat akan menyebut ketiga warna; model yang mengarang tidak akan cocok.

---

## Instalasi

```bash
npm install -g mcp-vision-image-fadhli
```

Butuh **9router berjalan** di mesin yang sama (default `http://127.0.0.1:20128`).

### Konfigurasi MCP

Tambahkan ke `~/.claude.json` (atau config MCP klien Anda):

```json
{
  "mcpServers": {
    "mcp-vision-image": {
      "type": "stdio",
      "command": "node",
      "args": ["C:\\path\\ke\\mcp-vision-image\\src\\server.js"],
      "env": {
        "ROUTER9_API_KEY": "sk-xxxxxxxxxxxx"
      }
    }
  }
}
```

API key diambil dari dashboard 9router → **Endpoint & Key**.

> **Cuma satu key yang dibutuhkan.** Key 9router membuka seluruh pool model Anda — tidak perlu key Antigravity, B.AI, atau provider lain satu per satu.

### Variabel lingkungan

| Variabel | Default | Keterangan |
|---|---|---|
| `ROUTER9_API_KEY` | — | **Wajib.** API key 9router. |
| `VISION_PROVIDERS` | `ag,oc` | Provider yang dipakai, dipisah koma. Isi `*` untuk semua. |
| `ROUTER9_BASE_URL` | `http://127.0.0.1:20128` | Alamat 9router. |
| `ROUTER9_MODEL` | — | Paksa satu model, lewati pemilihan otomatis. |
| `ROUTER9_MAX_TOKENS` | `2000` | Batas token jawaban. |
| `ROUTER9_TIMEOUT_MS` | `120000` | Timeout per model. |

### Provider yang dipakai

Default **`ag,oc`** — Antigravity dan OpenCode Free. Keduanya dipakai karena
terukur, bukan dipilih sembarangan:

| Provider | Model | Verifikasi |
|---|---|---|
| `ag` (Antigravity) | `gemini-3.8-flash-medium`, `-high`, `3.7-flash-high` | ✅ 4,1 dtk |
| `oc` (OpenCode Free) | `mimo-v2.5-free`, `muse-spark-1.3-contributor-free`, `1.2-contributor-free` | ✅ 3,8–10 dtk |

Semua diuji 25 Sep 2026 lewat endpoint Anthropic 9router memakai gambar uji
(3 kotak merah/hijau/biru) — keempatnya menjawab dengan benar.

Kenapa dibatasi: memindai **semua** provider menemukan 4 model bekerja dari 30
diuji; dibatasi ke `ag,oc` menemukan **8 dari 8**. Provider lain menghabiskan
waktu dan kuota untuk model yang kreditnya kosong atau key-nya mati.

Ganti lewat env kalau instalasi Anda berbeda:

```json
"env": {
  "ROUTER9_API_KEY": "sk-xxxxxxxxxxxx",
  "VISION_PROVIDERS": "ag"          // Antigravity saja
}
```

Provider yang diminta tapi **tidak ada** di katalog dilaporkan sebagai
peringatan — tidak diabaikan diam-diam.

### Catatan: kenapa endpoint Anthropic

Modul ini memanggil `/v1/messages`, bukan `/v1/chat/completions`. Dua alasan,
keduanya terukur:

1. **Input gambar di endpoint OpenAI mengembalikan `content` kosong** —
   HTTP-nya 200, tapi jawabannya tidak ada, untuk semua model yang diuji.
2. **Provider `oc` kena gate tambahan di endpoint OpenAI.** OpenCode Free
   hanya menjawab kalau tool quartet `{bash, glob, grep, read}` ikut dikirim;
   tanpanya, HTTP 200 dengan `content` kosong. Endpoint Anthropic tidak
   menerapkan gate itu, jadi `oc` bekerja tanpa trik tambahan.

Bentuk responsnya juga tidak seragam — Antigravity menjawab **SSE**, `oc`
menjawab **JSON**. Parser menangani keduanya.

---

## Tools

### `analyze_image`

Menganalisis gambar dari file lokal atau URL.

| Parameter | Keterangan |
|---|---|
| `image_path` | Path file lokal |
| `image_url` | URL gambar (diunduh otomatis) |
| `prompt` | Instruksi spesifik (opsional) |
| `model` | Paksa model tertentu (opsional) |

Jawabannya menyertakan model mana yang dipakai dan berapa lama.

### `discover_vision_models`

Memindai 9router untuk menemukan model yang benar-benar bisa memproses gambar di mesin ini. Hasilnya di-cache dan dipakai otomatis oleh `analyze_image`.

Jalankan ulang kalau daftar terasa basi (provider berganti, kredit berubah).

| Parameter | Default | Keterangan |
|---|---|---|
| `target` | 5 | Berhenti setelah sekian model bekerja |
| `max_probe` | 48 | Batas atas model diuji (pengaman kuota) |
| `include_non_vision` | false | Ikut uji yang tidak mengklaim vision — untuk memeriksa akurasi metadata |

**Batas selalu dilaporkan.** Kalau ada model yang tidak diuji karena kena batas, jumlahnya disebutkan — supaya hasilnya tidak terbaca "menyeluruh" padahal tidak.

### `get_usage_stats`

Statistik pemakaian per model, riwayat harian, status backend, dan ringkasan hasil pemindaian terakhir.

---

## Catatan teknis

### Kenapa endpoint Anthropic, bukan OpenAI?

Untuk input **gambar**, `/v1/chat/completions` di 9router mengembalikan **HTTP 200 dengan `content` kosong** — untuk semua model yang diuji. `/v1/messages` dengan model yang sama menjawab benar. Jadi ini soal jalur translasi gambar di 9router, bukan soal model.

| Endpoint | Hasil untuk input gambar |
|---|---|
| `/v1/chat/completions` | HTTP 200, `content` **kosong** |
| `/v1/messages` | jawaban benar |

### Blok thinking dibuang

Model thinking mengirim rantai penalaran di `thinking_delta` (sering dalam bahasa Mandarin). Parser hanya mengambil `text_delta`, dan `max_tokens` dijaga cukup tinggi supaya jatah tidak habis di thinking lalu menyisakan `content` kosong.

---

## Test

```bash
ROUTER9_API_KEY=xxx npm test
```

13 pemeriksaan, termasuk memanggil tool lewat protokol MCP sungguhan (stdio) dan memverifikasi jawaban terhadap gambar uji secara objektif.

Untuk memindai lebih luas di luar test:

```bash
node test/probe-vision.js --per-provider 2    # sampel stratifikasi
node test/probe-vision.js --all               # sapu bersih
node test/probe-vision.js --only ag/gemini-3.8-flash-high
node test/probe-vision.js --control           # uji akurasi metadata katalog
```

---

## Lisensi

MIT

TDQS

A4/5.0

Scored across 2 tools

Disambiguation5/5

The two tools have clearly distinct purposes: analyze_image handles image analysis, while get_usage_stats reports API usage metrics. No overlap or ambiguity exists.

Naming Consistency5/5

Both tools follow a consistent verb_noun pattern: analyze_image and get_usage_stats. The naming is uniform and predictable.

Tool Count3/5

With only 2 tools, the server feels thin but is reasonable for a focused single-purpose image analysis service. It sits at the borderline of being too minimal.

Completeness5/5

For its stated purpose of image analysis via Gemini Vision, the server covers the core operation (analyze_image) and adds useful monitoring (get_usage_stats). No obvious missing operations within this narrow domain.

Maintenance

ActivityMaintained
ResponsivenessNo issues