Iris
resmiServer evaluasi agen dan observabilitas native MCP dengan pencatatan jejak, evaluasi kualitas output, pelacakan biaya, 12 aturan evaluasi bawaan, dasbor real-time, dan deteksi PII
Apa yang bisa Anda lakukan dengan Iris MCP?
- Mencatat dan mengevaluasi jalannya agen — Minta asisten Anda untuk mencatat tugas ke Iris dan dapatkan skor kualitas, keamanan, dan biaya yang deterministik pada keluaran tersebut.
- Mencari riwayat jejak — Ambil eksekusi agen yang tersimpan dengan dukungan filter, pembagian halaman, dan rentang waktu untuk meninjau kinerja sebelumnya.
- Membandingkan jalannya proses dari waktu ke waktu — Analisis dua proses pada pertanyaan yang sama secara berdampingan untuk menemukan regresi atau peningkatan dalam perilaku agen.
- Menilai kualitas keluaran — Evaluasi teks apa pun terhadap 25 aturan bawaan yang mencakup kelengkapan, relevansi, keamanan, dan biaya, dengan deteksi PII dan injeksi prompt.
- Menjalankan dasbor demo — Luncurkan basis data demo yang telah diisi dengan kegagalan dan vonis contoh untuk menjelajahi mesin penilaian Iris secara lokal.
Dokumentasi
Iris — berhenti mengirim agen berdasarkan firasat
Iris menilai setiap eksekusi agen untuk kualitas, keamanan, dan biaya — di mesin Anda, tanpa SDK dan tanpa akun. Sebagian besar proyek agen memeriksa kualitas dengan menjalankan beberapa prompt yang diingat dan melihat sekilas keluarannya. Iris menggantinya dengan angka yang dapat Anda audit: eksekusi agen Anda tersimpan dalam database SQLite di disk Anda, 25 aturan bawaan menilainya secara deterministik — PII, injeksi prompt, penanda halusinasi, ambang biaya, dan panggilan alat agen itu sendiri — gratis, tanpa panggilan LLM, dan hakim LLM opsional dengan batas biaya keras per evaluasi menangani pertanyaan semantik. Setiap aturan dapat diperiksa dan diedit, karena hakim yang tidak dapat Anda audit hanyalah firasat dengan angka di atasnya. Lisensi MIT, tanpa telemetri. Tidak ada yang meninggalkan mesin Anda kecuali Anda mengaktifkan salah satu dari ini: endpoint OpenTelemetry (IRIS_OTEL_ENDPOINT), yang mengekspor jejak ke kolektor yang Anda sebutkan; hakim LLM dengan kunci Anda sendiri, yang mengirim teks yang dinilainya ke penyedia tersebut, dan pemeriksaan kutipannya mengambil halaman yang dikutip oleh keluaran; atau webhook, yang mengirim id, vonis, dan nama aturan, tidak pernah teksnya, ke alamat yang Anda tetapkan.
Membutuhkan Node.js 22.13 atau lebih baru. Periksa dengan node --version.

Database demo, direkam oleh scripts/demo-media.mts; sumbernya adalah demo.mp4. Gambar diam: dashboard-overview.png.
Kegagalan di layar dalam 60 detik
Tanpa pengkabelan agen, tanpa konfigurasi — satu perintah:
npx @iris-eval/mcp-server --demo
Ini mengisi database demo — lima agen kecil, dua minggu eksekusi, setiap vonis dari mesin itu sendiri — dan menyajikan dasbor terhadapnya di http://localhost:6920 (browser Anda terbuka otomatis pada eksekusi pertama). Dasbor mendarat di Kegagalan: apa yang gagal, terburuk dan terbaru lebih dulu, setiap kartu menyebutkan aturan dan buktinya. Layak diklik — kebocoran PII yang tertangkap oleh aturan keamanan, arahan tersembunyi di posting forum yang dipatuhi perangkum, angka yang tidak pernah disebutkan dokumen sumber, dua eksekusi pada dua belas pertanyaan yang sama dibandingkan dengan interval (Eksekusi), aturan kustom yang diterapkan dan yang dijeda dengan baris auditnya, dan skor hakim LLM yang gagal dengan alasannya.
Data demo hidup di database sendiri (demo.db di direktori rumah Iris Anda — ~/.iris di macOS/Linux, %USERPROFILE%\.iris di Windows) dan tidak pernah bercampur dengan jejak asli Anda. Hapus semuanya dengan satu perintah:
npx @iris-eval/mcp-server --demo-clear
Hubungkan agen Anda sendiri
Pertama, buktikan instalasi berfungsi di mesin ini — berjalan offline dan tidak membuka apa pun milik Anda:
npx @iris-eval/mcp-server --self-test # exit 0 = healthy
Lalu tambahkan Iris ke klien MCP Anda. Satu perintah menulis file konfigurasi klien itu sendiri, menjaga setiap server lain di dalamnya, dan mengunci versi yang Anda jalankan:
npx -y @iris-eval/mcp-server install claude-code
Kliennya: claude-code, claude-desktop, cursor, windsurf, continue, vscode, cline, zed, codex, gemini. install --list menampilkan yang ditemukan di mesin ini, Iris yang dijalankan masing-masing dan file yang dibacanya; install <client> --uninstall menghapus Iris lagi. Setiap klien berbagi satu database, jadi setelah peningkatan, pindahkan semuanya sekaligus dengan install --upgrade (Memperbarui). Mulai ulang klien untuk memuatnya.
Claude Desktop: satu klik. Setiap rilis dari 0.20.0 ke atas melampirkan iris-eval.mcpb, sebuah MCP Bundle: unduh yang terbaru, buka, dan Claude Desktop menampilkan dialog instalasi. Tidak ada yang wajib di dalamnya — kunci Anthropic atau OpenAI untuk hakim LLM bersifat opsional, dan dasbor adalah sakelar yang mulai mati. Bundel tersebut berisi paket npm dan dependensinya, jadi tidak ada yang perlu diinstal lagi: Claude Desktop menjalankannya di bawah Node yang disertakannya saat Node tersebut 22.13 atau lebih baru (Claude Desktop 1.1.6679 menyertakan 24.13), dan Iris menyimpan jejak dengan SQLite bawaan Node, di ~/.iris yang sama yang digunakan instalasi lain. Catatan rilis menunjukkan cara memverifikasi tanda tangan dan bukti pembangunannya.
Ini berjalan di klien MCP mana pun, dan setiap klien yang disebutnya memiliki baris dengan apa yang sebenarnya diperiksa. Terverifikasi di setiap eksekusi CI: Claude Code, Gemini CLI — klien asli memulai Iris dari konfigurasi yang ditulis penginstal dan melaporkan bahwa ia terhubung (claude mcp list, gemini mcp list), di Linux, macOS, dan Windows; plugin hook penangkap Claude Code juga digerakkan melalui skrip asli. Diklaim dari dokumentasi MCP masing-masing klien — penginstal menulis bentuk konfigurasi yang didokumentasikan klien, dan penulis itu diuji pada bentuknya; tidak ada seorang pun di sisi Iris yang melihatnya terhubung: Claude Desktop, Cursor, Devin Desktop (Windsurf), Continue, VS Code, Cline, Zed, OpenAI Codex CLI. Setiap baris dengan sumbernya dan tanggal dibacanya: https://iris-eval.com/clients. Secara manual sebagai gantinya, satu blok, termasuk dasbor:
{
"mcpServers": {
"iris-eval": {
"command": "npx",
"args": ["-y", "@iris-eval/mcp-server", "--dashboard"]
}
}
}
Klien Anda mencantumkan dua belas alat Iris saat terhubung, dan dasbor melayani di http://localhost:6920. Sekarang tempel ini ke agen Anda:
Catat tugas terakhir itu ke Iris dan evaluasi keluarannya.
Jejak mendarat di dasbor dengan skornya. Lebih suka server MCP tanpa kepala? Hapus --dashboard dari argumen — Anda dapat membuka dasbor yang sama kapan saja dengan npx @iris-eval/mcp-server --dashboard.
Satu hal yang perlu diketahui di awal: alat MCP dipanggil saat model memutuskan untuk memanggilnya. Iris tidak mencegat agen Anda, jadi jejak dicatat saat agen Anda memintanya untuk mencatatnya — baik karena Anda menyuruhnya, atau karena kode Anda memanggil alat secara langsung. Minta agen Anda untuk "catat ini ke Iris dan evaluasi" dan ia akan melakukannya. Jika Anda ingin penangkapan yang tidak bergantung pada pilihan model, POST /api/v1/traces melakukan persis itu — kode Anda mengirim jejak melalui HTTP biasa, tanpa model dalam loop (lihat docs/http-ingest.md). CLI dan hook host di peta jalan akan menjadi klien tipis di atas endpoint yang sama.
Penangkapan melalui HTTP (tanpa model dalam loop)
Endpoint ingest hidup di port dasbor — 6920 secara default, bukan port transport MCP — dan hanya ada saat dasbor berjalan. Berikan --dashboard (atau atur IRIS_DASHBOARD=true); --transport http saja tidak memulainya, dan permintaan ke port transport mengembalikan 404. Dengan dasbor aktif, apa pun yang dapat mengirim permintaan HTTP dapat mencatat jejak — dan secara opsional menjalankan evaluasi deterministik dalam permintaan yang sama. GET /api/v1/capabilities di port yang sama mengatakan apa yang dapat dinilai server ini, apa yang dibutuhkan setiap aturan, status hakim dengan langkah-langkah yang mengaktifkannya, dan batasannya — objek yang sama yang dilayani sumber daya MCP iris://capabilities — sehingga pemanggil HTTP memiliki bingkai yang didapat klien MCP saat inisialisasi:
curl -s -X POST "http://127.0.0.1:6920/api/v1/traces" \
-H "Content-Type: application/json" \
-d '{
"agent_name": "support-bot",
"input": "What is the refund policy?",
"output": "Refunds are available within 30 days of purchase.",
"evaluate": true,
"eval_type": "safety"
}'
Mengembalikan 201 dengan trace_id yang tersimpan dan hasil evaluasi (dalam mode --demo endpoint menolak penulisan dengan 403, sehingga data demo tidak pernah bercampur dengan milik Anda). Endpoint menerima badan yang sama dengan alat log_trace dan berada di belakang tumpukan middleware yang sama dengan dasbor lainnya: ikatan loopback dan penjaga pengikatan ulang DNS secara default, plus autentikasi Bearer saat Anda menetapkannya. Dua fakta sederhana tentangnya: ia menerima penulisan tanpa autentikasi kecuali Iris dimulai dengan --api-key (atau IRIS_API_KEY) — ikatan loopback adalah yang menjaganya tetap di mesin Anda secara default, jadi tetapkan kunci sebelum mengikat di luar loopback; dan apa yang disimpannya adalah kata demi kata — input dan output mendarat di iris.db persis seperti yang dikirim, termasuk teks apa pun yang kemudian ditandai no_pii. Kontrak lengkap, referensi bidang, dan semantik kesalahan: docs/http-ingest.md.
Tangkap setiap giliran Claude Code (opsional)
/plugin marketplace add iris-eval/mcp-server
/plugin install iris-eval-capture@iris-eval
Plugin kedua yang diinstal terpisah: tiga hook mencatat prompt setiap giliran, panggilan alat, dan jawaban akhir dan menyerahkannya ke iris-eval ingest, terlepas, dengan rentang kritis disunting dalam teks evaluasi yang disimpan — penangkapan yang tidak bergantung pada model yang memutuskan untuk memanggil alat. Ia tidak pernah mencatat giliran yang sudah dicatat model, tidak pernah mencetak, tidak pernah memblokir, tidak pernah mengirim apa pun ke mana pun. Menginstal iris-eval saja tidak mengubah apa pun tentang loop giliran Anda. Batasan dan penghapusan: claude-plugin-capture/README.md.
Python
pip install iris-eval
from iris_eval import IrisClient
iris = IrisClient() # IRIS_URL, or the running dashboard's runtime.json
iris.evaluate_output("…", input="…", agent_name="support-bot")["verdict"] # {"state": "pass", "basis": "clean", "by": []}
Klien tipis di atas API HTTP server 0.16.0 dan yang lebih baru, diberi versi sendiri — iris_eval.__version__ dan halaman PyPI membawa nomornya, yang bukan nomor server: log_trace(), evaluate_output(), get_traces(), get_trace(), health(), capabilities(), sinkron dan asinkron, jawaban bertipe, kalimat server sendiri tentang penolakan — dan plugin pytest: perlengkapan iris dan assert_iris(output, expect="pass") yang menegaskan status vonis. packages/python/README.md.
Rekam setiap panggilan OpenAI dan Anthropic
from iris_eval import wrap_openai
client = wrap_openai(OpenAI(), agent_name="support-bot") # every call: a GenAI span to POST /v1/traces, scored
import { wrapOpenAI } from '@iris-eval/sdk';
const openai = wrapOpenAI(new OpenAI(), { agentName: 'support-bot' });
Bungkus klien penyedia sekali dan setiap panggilan model menjadi satu span OpenTelemetry GenAI yang dikirim ke pintu OTLP, disimpan dengan input, output, penggunaan token, dan panggilan alatnya, dan dinilai: penangkapan yang tidak bergantung pada model yang memanggil alat. wrap_openai / wrap_anthropic di klien Python; wrapOpenAI, wrapAnthropic dan irisMiddleware untuk Vercel AI SDK di @iris-eval/sdk. Keduanya belum diterbitkan (rilis iris-eval berikutnya di PyPI; @iris-eval/sdk dibangun dari sumber hingga rilis npm pertamanya). Streaming, pembantu streaming SDK, dan panggilan alat tercakup, klien asli tidak diubah, dan Iris yang mati tidak pernah merusak panggilan — packages/sdk/README.md, packages/python/README.md.
Nilai setiap eksekusi LangChain dan LangGraph
from iris_eval.langchain import IrisCallbackHandler
graph.invoke(inputs, config={"callbacks": [IrisCallbackHandler(agent_name="support-bot")]})
Setiap eksekusi tingkat atas menjadi satu jejak (eksekusi, panggilan modelnya, panggilan alatnya, dan node grafnya sebagai span GenAI) dengan input, output, panggilan alat, penggunaan token, dan vonis. Python di klien (rilis berikutnya, belum diterbitkan ke PyPI), JavaScript sebagai @iris-eval/langchain (belum diterbitkan ke npm). Keduanya terbukti di CI terhadap aplikasi LangGraph nyata dengan model berskrip; ekspor OpenTelemetry LangSmith sendiri terbukti dengan cara yang sama — docs/otel-recipes.md.
Gerbang CI, tanpa server yang diperlukan
npx -y @iris-eval/mcp-server ingest --file traces.ndjson --evaluate --fail-on detector_veto
Atau GitHub Action (0.16.0), yang menggagalkan pekerjaan pada vonis yang Anda sebutkan, menulis tanda terima ke ringkasan pekerjaan dan mempostingnya sebagai satu komentar permintaan tarik yang diperbarui di tempat: uses: iris-eval/mcp-server/.github/actions/gate@v0.19.0 dengan traces: traces.ndjson — docs/ci-gate.md.
Pintu keempat (0.15.0): POST /v1/traces pada port dasbor menerima OTLP/HTTP JSON atau protobuf yang sudah dihasilkan oleh instrumentasi OpenTelemetry Anda (eksportir Python SDK hanya berbicara protobuf, jadi ini juga pintu untuk Python), dan setiap trace OTLP menjadi trace Iris dengan span-span-nya — docs/otel-integration.md; satu resep per kerangka kerja (Pydantic AI, Google ADK, LangGraph via LangSmith, CrewAI, OpenAI Agents SDK dalam Python dan JavaScript, LlamaIndex, AutoGen, Microsoft Agent Framework, Semantic Kernel, Vercel AI SDK dan Mastra), masing-masing dibuktikan oleh fixture, di docs/otel-recipes.md. ingest membaca satu trace JSON (atau NDJSON, satu per baris) dari stdin atau file, menyimpannya, mengevaluasinya dengan aturan yang persis sama seperti yang dijalankan evaluate_output, mencetak satu baris JSON per trace dengan vonis dan dasarnya, dan keluar dengan kode 1 ketika vonis cocok dengan --fail-on. --dataset <id|label> membatasi gerbang tersebut hanya pada kunci kasus dalam sebuah dataset (POST /api/v1/datasets mempromosikan kunci kasus dari sebuah run menjadi satu), sehingga sebuah pekerjaan hanya gagal pada kasus yang Anda pilih. Resep lengkap, kode keluar, dan delapan dasar tersebut ada di docs/ci-gate.md.
Menulis aturan sebagai kode
eval.plugins di config.json memuat aturan yang Anda tulis — sebuah modul ES yang ekspor default-nya adalah { name, kind, mechanism, version, needs, evaluate(ctx) } — yang dipatok oleh sha256 dari file tersebut, sehingga file yang berubah sejak Anda mematoknya akan menolak untuk memulai daripada dijalankan. Plugin yang dimuat akan menyala seperti bawaan dan tampil di list_rules di bawah plugins. Kontrak, resep hash, dan apa yang boleh dikembalikan oleh plugin: docs/plugins.md.
Menggunakan mesin di proses Anda sendiri
Mesin evaluasi dapat diimpor — tanpa server, tanpa database, tanpa model:
import { EvalEngine, defaultConfig } from '@iris-eval/mcp-server/engine';
const engine = new EvalEngine(defaultConfig.eval.defaultThreshold, defaultConfig.eval.ruleThresholds, defaultConfig.eval);
const result = await engine.evaluateAll({ output: answer, input: prompt, toolCalls, costUsd });
result.verdict.state; // 'pass' | 'fail' | 'unknown', with result.verdict.basis and result.interpretations
Mesin yang sama, aturan yang sama, dan komposer yang sama yang dijalankan server; builtInRules(), createCustomRule(), compose() dan pembaca akurasi yang dipublikasikan diekspor di sampingnya.
Klien bertipe untuk rute HTTP
import { createClient } from '@iris-eval/mcp-server/client';
const iris = createClient({ baseUrl: 'http://127.0.0.1:6920', apiKey: process.env.IRIS_API_KEY });
const { trace_id, evaluation } = await iris.logTrace({ agent_name: 'support-bot', input, output, tool_calls, evaluate: true });
evaluation?.verdict?.state; // the same object evaluate_output returns
Satu body di setiap pintu: itulah yang diterima oleh log_trace dan iris-eval ingest. Penolakan melempar IrisClientError dengan kalimat dan status dari server itu sendiri. Kedua subpath diperiksa dari tarball yang dikemas pada setiap build.
Verifikasi instalasi Anda
npx @iris-eval/mcp-server --self-test # offline diagnostic; exit 0 = healthy, 1 = a check failed
npx @iris-eval/mcp-server --version # prints the bare version, e.g. 1.2.3
--self-test pertama-tama membuat home Iris Anda jika belum ada dan memeriksa apakah dapat ditulis (keluar dengan kode 1, menyebutkan jalurnya, jika tidak), melaporkan di mana indeks pencarian database Anda berada (utuh, berapa banyak trace yang telah diindeks oleh build latar belakang sejauh ini, atau tanpa FTS5 pada SQLite ini), membaca skema database Anda (keluar dengan kode 1, beserta perbaikannya, ketika versi ini atau klien MCP yang dipatok ke rilis lama tidak dapat membukanya), lalu menjalankan pemeriksaannya — penyimpanan bolak-balik, SSN yang ditanam dan injeksi yang ditanam yang tertangkap oleh aturan keamanan, boot dasbor, penjaga anti-DNS-rebinding — di dalam home sementara yang terisolasi. Database asli Anda hanya dibaca, tidak pernah diubah. Semua yang ditulis Iris berada di satu direktori, home Iris Anda: ~/.iris secara default (%USERPROFILE%\.iris di Windows), atau di mana pun IRIS_HOME menunjuk. Di situlah iris.db, config.json, custom-rules.json, audit.log, preferences.json dan file demo berada; arahkan IRIS_HOME ke direktori sementara untuk mencoba Iris tanpa menyentuh data asli Anda.
Pengaturan per alat
| Klien | Status | Artinya | Baca |
|---|---|---|---|
| Claude Code | terverifikasi | sebuah tes menjalankan klien asli pada setiap run CI | 2026-09-25 |
| Claude Desktop | diklaim | penginstal menulis bentuk yang didokumentasikan klien, dan penulis itu diuji pada bentuk tersebut; tidak ada orang di sisi Iris yang telah melihatnya terhubung | 2026-09-25 |
| Cursor | diklaim | penginstal menulis bentuk yang didokumentasikan klien, dan penulis itu diuji pada bentuk tersebut; tidak ada orang di sisi Iris yang telah melihatnya terhubung | 2026-09-25 |
| Devin Desktop (Windsurf) | diklaim | penginstal menulis bentuk yang didokumentasikan klien, dan penulis itu diuji pada bentuk tersebut; tidak ada orang di sisi Iris yang telah melihatnya terhubung | 2026-09-25 |
| Continue | diklaim | penginstal menulis bentuk yang didokumentasikan klien, dan penulis itu diuji pada bentuk tersebut; tidak ada orang di sisi Iris yang telah melihatnya terhubung | 2026-09-25 |
| VS Code | diklaim | penginstal menulis bentuk yang didokumentasikan klien, dan penulis itu diuji pada bentuk tersebut; tidak ada orang di sisi Iris yang telah melihatnya terhubung | 2026-09-25 |
| Cline | diklaim | penginstal menulis bentuk yang didokumentasikan klien, dan penulis itu diuji pada bentuk tersebut; tidak ada orang di sisi Iris yang telah melihatnya terhubung | 2026-09-25 |
| Zed | diklaim | penginstal menulis bentuk yang didokumentasikan klien, dan penulis itu diuji pada bentuk tersebut; tidak ada orang di sisi Iris yang telah melihatnya terhubung | 2026-09-25 |
| OpenAI Codex CLI | diklaim | penginstal menulis bentuk yang didokumentasikan klien, dan penulis itu diuji pada bentuk tersebut; tidak ada orang di sisi Iris yang telah melihatnya terhubung | 2026-09-25 |
| Gemini CLI | terverifikasi | sebuah tes menjalankan klien asli pada setiap run CI | 2026-09-25 |
Setiap baris dengan apa yang diperiksa: iris-eval.com/clients. Tidak ada klien yang disebut didukung tanpa sebuah baris.
npx -y @iris-eval/mcp-server install <client> menulis masing-masing ini untuk Anda. Secara manual, per klien:
Claude Desktop
Edit file konfigurasi MCP Anda:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Tambahkan konfigurasi JSON di atas, lalu mulai ulang Claude Desktop.
Claude Code
claude mcp add --transport stdio iris-eval -- npx -y @iris-eval/mcp-server
Lalu mulai ulang sesi (/clear atau luncurkan ulang) agar alat dimuat.
Catatan Windows: Jangan tidak gunakan pembungkus
cmd /c— ini menyebabkan masalah penguraian jalur. Perintahnpxbekerja langsung.
Cursor
Tambahkan konfigurasi JSON di atas ke ~/.cursor/mcp.json (setiap proyek) atau .cursor/mcp.json di ruang kerja, dengan "type": "stdio" di entri iris-eval — dokumen Cursor menandainya sebagai wajib.
Devin Desktop (Windsurf)
Tambahkan konfigurasi JSON di atas ke mcp_config.json: ~/.config/devin/mcp_config.json di macOS dan Linux, %APPDATA%\devin\mcp_config.json di Windows.
Continue
Simpan konfigurasi JSON di atas sebagai file sendiri di folder mcpServers Continue: ~/.continue/mcpServers/iris-eval.json (setiap ruang kerja) atau .continue/mcpServers/iris-eval.json di salah satunya.
VS Code (MCP asli)
Tambahkan ke .vscode/mcp.json di ruang kerja Anda (catatan: VS Code menggunakan servers, bukan mcpServers):
{
"servers": {
"iris-eval": {
"command": "npx",
"args": ["-y", "@iris-eval/mcp-server"]
}
}
}
Cline
Buka panel Server MCP Cline → Konfigurasi Server MCP, dan tambahkan konfigurasi JSON mcpServers di atas ke cline_mcp_settings.json (~/.cline/data/settings/cline_mcp_settings.json, dibagikan oleh Cline di VS Code, JetBrains dan CLI).
Zed
Tambahkan ke settings.json Zed:
{
"context_servers": {
"iris-eval": {
"command": "npx",
"args": ["-y", "@iris-eval/mcp-server"],
"env": {}
}
}
}
OpenAI Codex CLI
Tambahkan ke ~/.codex/config.toml:
[mcp_servers.iris-eval]
command = "npx"
args = ["-y", "@iris-eval/mcp-server"]
Gemini CLI
Tambahkan konfigurasi JSON mcpServers di atas ke ~/.gemini/settings.json. Gemini CLI terhubung ke server MCP hanya di folder yang dipercayainya: jika gemini mcp list menampilkan iris-eval sebagai Dinonaktifkan, jalankan /permissions di folder itu.
Apa pun yang berbicara MCP
Iris adalah server MCP stdio standar — satu perintah npx @iris-eval/mcp-server, tanpa SDK, tanpa perubahan kode. Jika klien Anda mendukung MCP, ia mendukung Iris. Format konfigurasi klien berubah; jika ragu, periksa dokumen MCP klien Anda dan arahkan ke perintah itu.
Metode Instalasi Lainnya
# Global install (recommended for persistent data and faster startup)
npm install -g @iris-eval/mcp-server
iris-eval --dashboard
# Docker — two servers, two ports: 3000 = MCP HTTP transport,
# 6920 = dashboard (which also serves the POST /api/v1/traces ingest endpoint).
# The image binds 0.0.0.0 inside the container, so a key is required (see Production).
# The volume is the Iris home: the database, deployed rules and audit log persist in it.
docker run -p 3000:3000 -p 6920:6920 -v iris-data:/data \
-e IRIS_API_KEY="$(openssl rand -hex 32)" ghcr.io/iris-eval/mcp-server
Tip: Instalasi global (
npm install -g) menyimpan trace secara persisten di~/.iris/iris.db. Dengannpx, trace bertahan di lokasi yang sama, tetapi startup lebih lambat karena resolusi paket.
Apa yang Anda Dapatkan
| Pencatatan Trace | Pohon span hierarkis dengan latensi per panggilan alat, penggunaan token, dan biaya dalam USD. Disimpan di SQLite, dapat ditanyakan secara instan. |
| Evaluasi Output | 25 aturan bawaan di 4 kategori: kelengkapan, relevansi, keamanan, biaya. Deteksi PII (21 pola: SSN, kartu kredit, telepon, email, IBAN, DOB, MRN, IP, kunci API, paspor, plus token AWS/Slack/SendGrid/GitHub/Google/npm/DigitalOcean, kredensial di dalam URL, penugasan bernama rahasia, blok kunci privat PEM dan frasa benih; tanggal lahir, nomor rekam medis, paspor dan frasa benih hanya aktif di samping labelnya, sesuai desain), deteksi injeksi prompt (38 pola, frasa + struktural), deteksi output stub, deteksi halusinasi (25 sinyal fabrikasi/kontradiksi yang berlandaskan konteks — berikan input untuk mendasarkannya pada materi sumber agen), dan enam aturan lintasan yang membaca apa yang DILAKUKAN agen: panggilan alat yang gagal tanpa diakui, panggilan yang diulang (per panggilan, per urutan berulang, atau per target setelah Anda mengirim tools), panggilan yang argumennya ditolak oleh Skema JSON alat itu sendiri dan agen tidak pernah mencoba lagi, file, direktori atau URL yang dikutip jawaban yang tidak muncul di apa pun yang dibaca agen, instruksi yang tiba di dalam HASIL ALAT dan kemudian dipatuhi oleh panggilan berikutnya, dan tugas yang membutuhkan lebih banyak panggilan alat daripada anggaran langkah Anda. Sebuah lintasan dapat tiba sebagai tool_calls atau sebagai span TOOL OpenTelemetry. Tambahkan aturan kustom dengan skema Zod. |
| LLM-sebagai-Hakim | Penilaian semantik opsional melalui Anthropic atau OpenAI — bawa kunci API Anda sendiri. Tujuh templat. Dengan IRIS_RELEVANCE_JUDGE_MODEL diatur, answers_the_ask bertanya kepada hakim relevance dan menggagalkan jawaban di luar topik; tanpa itu, aturan membaca pertanyaan secara leksikal dan memberi saran. Batas biaya per-evaluasi yang keras (IRIS_LLM_JUDGE_MAX_COST_USD_PER_EVAL, default $0,25), harga per-evaluasi diungkapkan dalam hasil. |
| Visibilitas Biaya | Biaya agregat di semua agen selama jendela waktu apa pun. Tetapkan ambang anggaran. Dapatkan tanda ketika agen membelanjakan berlebihan. Trace yang mengirim jumlah token dan model tetapi tanpa biaya (sebagian besar trace OpenTelemetry dan kerangka kerja) diberi harga pada harga daftar model dan ditandai sebagai perkiraan di mana pun ia muncul; pricing.models di config.json memberi harga model yang tidak ada di tabel bawaan — docs/cost.md. |
| Dasbor Web | UI mode gelap waktu nyata yang mendarat pada kegagalan, terburuk dan terbaru lebih dulu — visualisasi trace dengan pencarian teks lengkap di setiap teks trace, hasil evaluasi, rincian biaya, dan palet perintah (⌘K) yang mencari aturan, trace, dan evaluasi Anda sendiri. |
| Lokal-pertama | Semuanya ada di SQLite di disk Anda. Tanpa akun, tanpa pendaftaran, tanpa telemetri. HTTP keluar hanya terjadi di tempat Anda memilih: kunci LLM-hakim Anda sendiri, pengambilan kutipan, eksportir OTel yang Anda konfigurasi, atau webhook yang Anda atur. |
Ke mana ini berlanjut: peta kemampuan — setiap pertanyaan yang dapat diajukan ke Iris tentang setiap subjek, dengan apa yang dimilikinya dan apa yang kurang — dan tiga jalur.
Terukur, bukan diklaim
Setiap aturan bawaan memiliki presisi, recall, dan F1 yang dipublikasikan dengan interval kepercayaan 95%, diukur pada korpus berlabel yang berada di repositori ini (proof/corpus/) dan dibuat ulang dengan satu perintah — npm run proof — secara offline, tanpa kunci dan tanpa model dalam prosesnya. Angka-angka tersebut terdiri dari dua jenis yang berbeda, dan halaman tidak pernah menjumlahkannya: beberapa aturan diukur terhadap label yang diberikan model dengan membaca kegagalan itu sendiri, yang mengukur deteksi; sisanya diperiksa terhadap definisi terdokumentasi mereka sendiri, yang diterapkan secara independen, yang menunjukkan kode mengimplementasikan formulanya dan tidak mengatakan apa pun tentang apakah formula tersebut menangkap kegagalan. proof/RESULTS.md dan halaman bukti menandai setiap aturan. CI menjalankan ulang pengukuran pada setiap pull request dan gagal jika angka yang dikomit berbeda dari yang dihasilkan kode, sehingga sebuah aturan tidak dapat berubah tanpa angka-angkanya ikut berubah. Angka-angka tersebut ada di iris-eval.com/proof dan di proof/RESULTS.md; bagaimana korpus dibuat, apa yang bukan, dan cara membaca interval ada di docs/proof.md. Korpus bersifat sintetis dan berlabel model — label buta manusia masih tertunda, dan halaman menyatakannya; node proof/blind-sample.mjs menarik sampel yang dapat direproduksi yang akan menyelesaikannya.
Alat MCP
Iris mendaftarkan dua belas alat yang dapat dipanggil oleh agen yang kompatibel dengan MCP — siklus hidup jejak dan aturan, perbandingan antar proses, LLM-sebagai-juri, dan verifikasi kutipan semantik:
log_trace— Mencatat eksekusi agen dengan span, panggilan alat, penggunaan token, dan biaya; berikanevaluate: trueuntuk menilainya dalam panggilan yang samaevaluate_output— Menilai kualitas keluaran terhadap aturan kelengkapan, relevansi, keamanan, dan biaya (heuristik, deterministik, gratis)get_traces— Mengkueri jejak tersimpan dengan dukungan pemfilteran, paginasi, dan rentang waktu, serta menemukan proses di mana agen mengatakan sesuatu denganq: pencarian teks lengkap atas input, output, nilai panggilan alat, dan metadata, diperingkat, dengan kata yang cocok ditandailist_rules— Mendaftarkan aturan evaluasi kustom yang diterapkan (hanya baca)deploy_rule— Mendaftarkan aturan evaluasi kustom baru sehingga aturan tersebut aktif pada setiapevaluate_outputdari kategori tersebutdelete_rule— Menghapus aturan kustom yang diterapkan (destruktif, idempoten)delete_trace— Menghapus satu jejak tersimpan berdasarkan ID (destruktif, terbatas pada penyewa)evaluate_with_llm_judge— Evaluasi semantik melalui LLM (Anthropic atau OpenAI). Tujuh templat: akurasi, kebermanfaatan, keamanan, kebenaran, kesetiaan, tugas_selesai, relevansi. Berbatas biaya, harga per evaluasi diungkapkan. Bawa kunci API Anda sendiri (IRIS_ANTHROPIC_API_KEYatauIRIS_OPENAI_API_KEY) — Iris tidak memproksi atau meneruskan panggilan LLM.verify_citations— Mengekstrak kutipan dari keluaran (bernomor, penulis-tahun, URL, DOI), mengambil sumber di balik resolver yang dilindungi SSRF + daftar izin domain, dan menggunakan juri LLM untuk memeriksa apakah setiap sumber benar-benar mendukung klaim yang dikutip. HTTP keluar opsional. Persyaratan BYOK yang sama denganevaluate_with_llm_judge.compare_runs— Apakah perubahan membuat agen lebih buruk? Membandingkan dua proses evaluasi tersimpan: uji eksak berpasangan ketika proses berbagi kunci kasus, interval pada selisih jika tidak, "tidak dapat mengatakan" yang jujur dengan jumlah kasus yang diperlukan, atau "setara dalam margin". Setiap aturan membawa uji satu sisi sendiri, dikoreksi bersama (Benjamini–Hochberg) sehingga dua puluh aturan tidak dapat memproduksi regresicompare_traces— Seberapa andal agen menjawab pertanyaan yang sama? Tingkat kelulusan per kasus dengan interval, kasus flaky terlebih dahulu, dan tingkat keseluruhan yang menghormati pengulanganevaluate_runs— Menilai ulang setiap jejak dalam proses di bawah aturan hari ini ke dalam proses baru, sehingga perubahan aturan tidak pernah dibaca sebagai perubahan agen
Aktifkan juri LLM (opsional; aturan deterministik tidak pernah membutuhkannya)
- Dapatkan kunci API dari Anthropic atau OpenAI.
- Letakkan di lingkungan proses yang menjalankan Iris, bukan hanya shell Anda. Claude Code, Claude Desktop, Cursor, dan sebagian besar klien MCP: blok "env" dari entri iris-eval di konfigurasi MCP Anda — "iris-eval": { "command": "npx", "args": ["-y", "@iris-eval/mcp-server"], "env": { "IRIS_ANTHROPIC_API_KEY": "sk-ant-..." } } (IRIS_OPENAI_API_KEY untuk kunci OpenAI). Docker: -e IRIS_ANTHROPIC_API_KEY=... pada perintah run. HTTP atau CI: ekspor sebelum memulai iris-eval.
- Mulai ulang sesi MCP. Proses yang berjalan tidak pernah melihat variabel yang diatur setelah dimulai.
- Konfirmasi dari dalam klien Anda: baca iris://capabilities — judge.enabled harus true di sana. Kunci yang diekspor di shell Anda tidak diteruskan ke proses yang dihasilkan klien Anda kecuali konfigurasinya mencantumkannya. Di mesin,
npx @iris-eval/mcp-server --self-testmencetak baris juri untuk shell tersebut, dan GET /api/v1/health melaporkan judge.enabled pada dasbor yang berjalan. - Pengaman pengeluaran: setiap panggilan dibatasi oleh IRIS_LLM_JUDGE_MAX_COST_USD_PER_EVAL (default 0,25 USD) dan ditolak sebelum pengeluaran apa pun jika kasus terburuk akan melebihi batas. Iris memanggil penyedia secara langsung dengan kunci Anda dan tidak pernah memproksinya.
- Opsional: atur IRIS_RELEVANCE_JUDGE_MODEL ke id model berharga (claude-haiku-4-5, misalnya) agar answers_the_ask meminta juri memeriksa apakah setiap jawaban menangani pertanyaannya, dan gagalkan yang di luar topik. Itu satu panggilan juri per evaluasi yang membawa input, pada kunci Anda dan di bawah batas di atas; kunci saja tidak pernah mengaktifkannya. Setiap panggilan mengirim input dan output tersebut ke penyedia model, dengan flag no_pii untuk data pribadi dan kredensial diganti terlebih dahulu (IRIS_RELEVANCE_JUDGE_REDACT=off mengirimnya apa adanya). Ini menghabiskan paling banyak IRIS_RELEVANCE_JUDGE_DAILY_BUDGET_USD per hari UTC (default 1 USD) dan membuat paling banyak IRIS_RELEVANCE_JUDGE_MAX_CALLS_PER_REQUEST panggilan per permintaan (default 20); melewati salah satunya, answers_the_ask membaca pertanyaan secara leksikal dan menjelaskan alasannya.
Ketika IRIS_OTEL_ENDPOINT dikonfigurasi, panggilan log_trace juga mengeluarkan ekspor JSON OTLP/HTTP upaya terbaik ke kolektor OpenTelemetry apa pun (Jaeger, Grafana Tempo, Datadog OTLP, Honeycomb, dll.). Lihat docs/otel-integration.md.
Bagaimana passed diputuskan
evaluate_output mengembalikan baik score dan flag passed — keduanya menjawab pertanyaan yang berbeda:
score(0..1) adalah rata-rata tertimbang di seluruh aturan yang berjalan — gradien kualitas.passedadalah vonis kirim/jangan-kirim, dan skor tidak pernah dikonsultasikan untuk itu. Seorang komposer membaca setiap aturan berdasarkan jenis klaim yang dibuatnya: kebijakan yang Anda konfigurasi menjadi gerbang; detektor kritis memveto; pemeriksaan kritis yang diminta dan tidak dapat dijawab membuat vonis tidak diketahui (passed: false) daripada bersih; setiap detektor yang tersisa bergabung menjadi satu probabilitas bahwa keluaran buruk, ditimbang terhadap rasio kerugian yang Anda nyatakan dieval.falsePassCost(default 1, sehingga batasnya 0,5).verdict.basismenamai lapisan yang memutuskan danverdict.byaturannya, danverdict.alsomencantumkan setiap lapisan berikutnya yang juga akan memutuskannya;interpretations[]menjelaskan mengapa aturan yang gagal tidak memutuskan dan pengaturan mana yang akan mengubahnya, serta menamai pertanyaan apa pun yang tidak dinilai dan input yang memungkinkannya dinilai.
Pelanggaran keamanan yang nyata gagal-keras. Secara default no_pii, no_injection_patterns, dan no_blocklist_words adalah aturan kritis: jika satu gagal, evaluasi melaporkan passed: false tidak peduli seberapa baik aturan lain dinilai, dan respons menamai pelakunya di critical_failures. SSN yang bocor tidak dapat dirata-ratakan. Aturan bawaan mana yang kritis adalah pengaturan penerapan (eval.criticalRules / eval.nonCriticalRules); setiap hasil aturan membawa flag critical efektif dan criticalSource, dan list_rules melaporkan daftar yang diterapkan server ini. Aturan kustom yang diterapkan dengan severity: "high" atau "critical" gagal-keras dengan cara yang sama; tingkat keparahan low/medium hanya memengaruhi skor. Satu batas yang perlu diketahui, dinyatakan dengan cara yang sama di setiap permukaan: aturan kritis yang dilewati (konteks hilang, definisi rusak, atau regex dihentikan pada anggaran sandbox) belum menilai keluaran dan tidak memveto — setiap aturan tersebut dinamai di critical_skipped. Gerbang yang harus gagal-tertutup memperlakukan critical_skipped yang tidak kosong sebagai tidak diketahui, bukan bersih, dan dapat memperlakukan setiap lompatan budgetExceeded di rule_results dengan cara yang sama.
Untuk gerbang CI: jika Anda menghilangkan eval_type, setiap bundel berjalan — kelengkapan, relevansi, keamanan, biaya, dan aturan kustom apa pun — dan respons mengatakan eval_type: "all" dengan note bahwa default berjalan, plus peta categories per bundel. Bundel tanpa apa pun untuk dinilai (biaya tanpa cost_usd, relevansi tanpa input) melaporkan passed: null di sana — tidak dievaluasi, tidak gagal — dan tidak pernah dihitung menuju vonis. Respons selalu menggema eval_type yang berjalan, sehingga gerbang Anda dapat memverifikasi cakupan; kunci pada passed untuk vonis dan sebutkan bundel hanya ketika Anda menginginkan proses yang lebih sempit.
Menulis aturan kustom
Dua cara untuk menambahkan aturan. Aturan inline ikut serta dalam satu panggilan evaluate_output (custom_rules, hingga 10 per panggilan); aturan tersebut aktif di samping bundel eval_type yang Anda pilih, atau sendiri dengan eval_type: "custom". Aturan diterapkan didaftarkan sekali dengan deploy_rule, bertahan di custom-rules.json di bawah rumah Iris Anda, dan aktif pada setiap evaluate_output masa depan dari evalType mereka. Definisi memiliki bentuk yang sama dalam kedua kasus:
| Bidang | Diperlukan | Apa itu |
|---|---|---|
name | ya | 1–80 karakter; muncul sebagai ruleName dalam hasil |
type | ya | salah satu dari regex_match · regex_no_match · min_length · max_length · contains_keywords · excludes_keywords · json_schema · cost_threshold |
config | ya | kunci untuk jenis itu: pattern (+ opsional flags) untuk dua jenis regex · min_length / max_length (jumlah karakter) · keywords (+ opsional threshold, 0–1, default 1 = semua harus muncul) untuk dua jenis kata kunci · {} untuk json_schema · max_cost dalam USD untuk cost_threshold |
weight | tidak | bobot dalam skor; default 1 |
deploy_rule membungkus definisi dengan name, opsional description, evalType (completeness · relevance · safety · cost · custom) dan severity. Tingkat keparahan mengatakan apa arti kegagalan: low/medium hanya menurunkan skor; high/critical gagal-keras evaluasi — passed: false, aturan yang dinamai di critical_failures — apa pun skor tertimbangnya. Aturan yang dilewati (aturan cost_threshold tanpa cost_usd, atau regex yang dihentikan pada anggaran sandbox 100 ms) belum menilai keluaran dan dicantumkan di critical_skipped sebagai gantinya. Terapkan aturan kritis yang melarang nama host internal dalam apa pun yang dikatakan agen:
{
"name": "no_internal_hostnames",
"description": "Output must not mention internal hostnames.",
"evalType": "safety",
"severity": "critical",
"definition": {
"name": "no_internal_hostnames",
"type": "regex_no_match",
"config": { "pattern": "\\b[a-z0-9-]+\\.internal\\.example\\b", "flags": "i" }
}
}
Responsnya adalah aturan yang dipertahankan — simpan id untuk delete_rule:
{ "rule": { "id": "rule-588823d0", "name": "no_internal_hostnames", "evalType": "safety", "severity": "critical", "enabled": true, "version": 1, "definition": { "…": "…" } } }
Dari evaluate_output berikutnya dengan eval_type: "safety", keluaran yang menyebutkan db-primary.internal.example kembali passed: false dengan critical_failures: ["no_internal_hostnames"] — bahkan meskipun kelima aturan keamanan bawaan lulus dan skor tertimbangnya 0,895. Pola regex harus lulus pemeriksaan ReDoS pada saat penerapan dan selalu berjalan di pekerja sandbox di bawah tenggat keras 100 ms. list_rules menunjukkan apa yang diterapkan; komposer aturan dasbor membangun bentuk yang sama dari kegagalan yang Anda klik. Referensi lengkap, penilaian per jenis, dan contoh kerja: docs/custom-rules.md.
Skema dan konfigurasi alat lengkap: iris-eval.com
Fitur yang dihosting
Iris berjalan sepenuhnya di mesin Anda hari ini, dan semua yang dilakukannya gratis dan berlisensi MIT tanpa batasan dan tanpa akun. Penyimpanan ter-hosting, riwayat tim bersama, dan alerting sedang dipertimbangkan, bukan sedang dibangun. Belum ada harga, dan tidak ada yang perlu dibeli. Jika riwayat bersama berguna bagi Anda, daftar tunggu adalah cara kami mengetahui apakah itu layak dibangun — itu tidak mengikat Anda pada apa pun.
Dua komitmen tetap berlaku apa pun yang terjadi: tidak ada yang gratis hari ini yang akan dipindahkan ke balik paywall, dan tidak ada sertifikasi kepatuhan yang akan diklaim sebelum sertifikasi tersebut dimiliki.
Contoh
- Pengaturan Claude Desktop — Konfigurasi MCP untuk mode stdio dan HTTP
- TypeScript — klien MCP SDK — hubungkan dan panggil alat
- Transport HTTP (TS + Python) — kode klien lengkap untuk integrasi gaya REST
- Agen LangGraph, dinilai jalankan demi jalankan (Python) —
IrisCallbackHandlerdalam callback grafik; CI menjalankan grafik yang sama dengan model berskrip - Crew CrewAI melalui OpenTelemetry (Python) — instrumentor OpenInference langsung ke pintu OTLP Iris, resep CrewAI sebagai skrip
- Agen OpenAI Agents SDK melalui OpenTelemetry (Python) dan (JavaScript), dan agen LlamaIndex — setiap resep sebagai skrip yang dijalankan CI terhadap server Iris nyata
Komunitas
- Masalah GitHub — Laporan bug dan permintaan fitur
- Diskusi GitHub — Pertanyaan dan ide
- Panduan Kontribusi — Cara berkontribusi
- Ingest HTTP — Penangkapan jejak deterministik melalui
POST /api/v1/traces - Peta kemampuan — Setiap pertanyaan yang dapat diajukan ke Iris, dan apa yang kurang
- Kebijakan versi — Apa yang dijanjikan setiap nomor versi, dan apa yang harus benar sebelum 1.0
Konfigurasi & Keamanan
Argumen CLI
| Bendera | Default | Deskripsi |
|---|---|---|
--transport | stdio | Jenis transport: stdio atau http |
--port | 3000 | Port transport HTTP |
--db-path | ~/.iris/iris.db | Jalur basis data SQLite |
--config | ~/.iris/config.json | Jalur file konfigurasi |
--api-key | — | Kunci API untuk autentikasi HTTP (transport dan dasbor, termasuk POST /api/v1/traces) |
--dashboard | false | Aktifkan dasbor web. Juga satu-satunya cara titik akhir ingest POST /api/v1/traces dimulai — titik akhir itu tidak pernah dimulai secara implisit dengan --transport http |
--dashboard-port | 6920 | Port dasbor |
--dashboard-host | 127.0.0.1 | Alamat bind dasbor. Loopback secara default — dasbor tidak diautentikasi kecuali --api-key diatur, jadi mengikat di luar loopback mengekspos seluruh riwayat jejak Anda |
--demo | false | Seed basis data demo (terpisah dari jejak nyata Anda) dan sajikan dasbor terhadapnya |
--demo-clear | false | Hapus basis data demo dan keluar |
--self-test | false | Jalankan diagnostik instalasi offline di home sementara yang terisolasi, lalu keluar (0 = sehat, 1 = pemeriksaan gagal). Ini juga membaca basis data yang dikonfigurasi, hanya-baca, dan gagal ketika versi ini atau klien MCP yang dipasang tidak dapat membukanya |
--purge | false | Hapus setiap jejak, span, dan evaluasi yang tersimpan dari basis data yang dikonfigurasi, kompak file dan potong log tulis-depan sehingga teks yang dihapus tidak tertinggal di disk, lalu keluar. Aturan yang diterapkan, log audit, dan preferensi dipertahankan. Tidak dapat dibatalkan. Hentikan server Iris yang berjalan terlebih dahulu — file dikompaksi di tempatnya. Menolak untuk digabungkan dengan --demo, --demo-clear atau --self-test |
--version | — | Cetak versi telanjang (mis. 1.2.3) ke stdout dan keluar 0. Tidak membaca apa pun di bawah home Iris Anda |
Tiga perintah mengambil argumennya sendiri dan keluar: iris-eval ingest memuat jejak dari file atau stdin (Gerbang CI, tanpa server diperlukan), iris-eval export traces|evaluations --format csv|jsonl menulis apa yang disimpan, difilter seperti daftar dasbor, ke stdout atau --out (docs/api-reference.md), dan iris-eval install <client> menulis Iris ke dalam konfigurasi klien MCP — --uninstall menghapusnya, --list menampilkan klien yang ditemukan di mesin ini dan Iris yang dijalankan masing-masing, --upgrade memindahkan setiap klien yang menjalankan Iris ke versi ini (Hubungkan agen Anda sendiri, Memperbarui). Tidak ada yang memulai server.
config.json divalidasi saat Iris dimulai. Kunci yang tidak dibaca Iris — salah ketik seperti eval.critcalRules, kunci dari alat lain — atau nilai dengan tipe yang salah menolak startup dengan satu kalimat yang menyebutkan kunci lengkap, kunci yang paling mungkin dimaksud, atau tipe yang diinginkannya. Tidak ada apa pun dalam file yang diabaikan secara diam-diam.
Variabel Lingkungan
Setiap variabel --help didokumentasikan. Bendera CLI lebih diutamakan daripada variabel lingkungan ketika keduanya diatur.
| Variabel | Deskripsi |
|---|---|
IRIS_TRANSPORT | Jenis transport (stdio atau http) |
IRIS_HOST | Alamat bind transport HTTP (default 127.0.0.1) |
IRIS_PORT | Port transport HTTP (1-65535, default 3000) |
IRIS_HOME | Direktori untuk semua file per-pengguna: config.json, iris.db, custom-rules.json, audit.log, preferences.json (default ~/.iris) |
IRIS_DB_PATH | Jalur basis data SQLite (menimpa IRIS_HOME hanya untuk basis data) |
IRIS_SQLITE_DRIVER | Driver SQLite mana yang memegang basis data: native (better-sqlite3, default) atau node (node:sqlite bawaan Node, Node 22.13+). Tidak diatur: native, dan ketika modul native tidak dapat dimuat (atau merupakan build yang akan berhenti pada Node ini) Iris memperingatkan sekali dan kembali ke bawaan |
IRIS_SEARCH_BUDGET_MS | Berapa lama satu pencarian jejak (q) dapat membaca sebelum menjawab dengan kecocokan yang ditemukan sejauh ini dan search.complete: false, dalam milidetik (50 hingga 60000, default 1000). Pencarian menahan permintaan lain saat membaca, jadi ini juga waktu terlama yang dapat membuat mereka menunggu. Juga storage.searchBudgetMs di config.json |
IRIS_SEARCH_INDEX | on (default) atau off. off tidak menyimpan indeks teks-lengkap dari jejak: penulisan menyimpan jejak dan tidak lebih, dan pencarian jejak (q) membaca jejak itu sendiri dalam IRIS_SEARCH_BUDGET_MS, terbaru lebih dulu, jadi pada penyimpanan besar ia dapat menjawab dengan sebagian kecocokan (search.complete: false). Mematikannya menghapus indeks yang disimpan basis data; menyalakannya lagi membangun yang baru di latar belakang. Juga storage.searchIndex di config.json |
IRIS_LOG_LEVEL | Tingkat log: debug, info, warn, error |
IRIS_DASHBOARD | true/1/yes/on mengaktifkan dasbor web; false/0/no/off menonaktifkannya (juga menimpa dashboard.enabled di config.json) |
IRIS_DASHBOARD_PORT | Port dasbor (1-65535, default 6920) |
IRIS_WEBHOOK_URL | Penerima webhook yang memicu pada suatu momen — digabungkan di atas notify.webhook di config.json (docs/webhooks.md) |
IRIS_WEBHOOK_SECRET | Kunci penandatanganan webhook (string apa pun, atau whsec_ + base64); format iris menolak untuk berjalan tanpa satu |
IRIS_DASHBOARD_HOST | Alamat bind dasbor (default 127.0.0.1) |
IRIS_API_KEY | Kunci API untuk autentikasi HTTP. Diperlukan untuk mengikat transport HTTP atau dasbor di luar loopback (0.0.0.0, alamat LAN, kontainer): tanpa itu server menolak untuk memulai |
IRIS_API_KEY_FILE | Jalur ke file yang isinya dipangkas adalah kunci API — pola file-rahasia yang dipasang Docker dan Kubernetes, sehingga kunci tidak pernah berada di blok lingkungan. Atur ini atau IRIS_API_KEY, bukan keduanya |
IRIS_ALLOW_UNAUTHENTICATED | Atur ke 1 untuk menjalankan bind non-loopback dengan tanpa kunci dengan sengaja (mencabut penolakan; jaringan kemudian menjadi batas Anda) |
IRIS_ALLOWED_ORIGINS | Daftar izin asal yang dipisahkan koma. Dasbor: header CORS (mendukung glob, mis. http://localhost:*). Transport HTTP: daftar izin Origin pencocokan tepat untuk perlindungan DNS-rebinding (glob diabaikan; asal loopback server sendiri selalu diizinkan) |
IRIS_NO_AUTO_LAUNCH | Atur ke 1 untuk menonaktifkan peluncuran otomatis dasbor saat pertama kali dijalankan |
IRIS_ANTHROPIC_API_KEY | Diperlukan oleh evaluate_with_llm_judge + verify_citations dengan provider=anthropic |
IRIS_OPENAI_API_KEY | Diperlukan oleh evaluate_with_llm_judge + verify_citations dengan provider=openai |
IRIS_LLM_JUDGE_MAX_COST_USD_PER_EVAL | Batas biaya keras per panggilan hakim LLM (default 0.25) |
IRIS_RELEVANCE_JUDGE_MODEL | Id model hakim berbayar (mis. claude-haiku-4-5). Ketika diatur, dengan kunci penyedia itu, answers_the_ask meminta hakim LLM ini pada setiap evaluasi yang membawa input dan menggerbang pada putusan relevansinya — satu panggilan hakim per evaluasi, di bawah batas biaya di atas dan dua batas di bawah. Input dan output setiap evaluasi tersebut dikirim ke penyedia model itu (Anthropic atau OpenAI) pada kunci Anda, dengan data pribadi dan kredensial yang ditandai no_pii diganti terlebih dahulu. Tidak diatur (default), answers_the_ask membaca permintaan secara leksikal dan memberi saran, dan tidak ada yang dikirim (docs/llm-as-judge.md) |
IRIS_RELEVANCE_JUDGE_DAILY_BUDGET_USD | Berapa banyak yang dapat dibelanjakan hakim relevansi per hari UTC, per penyewa (default 1). Disimpan di basis data, jadi restart tidak meresetnya. Panggilan dibuat hanya jika kasus terburuknya muat dalam sisa; setelah itu, answers_the_ask membaca permintaan secara leksikal dan judge.withheld adalah daily_budget. 0 menghentikan setiap panggilan |
IRIS_RELEVANCE_JUDGE_MAX_CALLS_PER_REQUEST | Panggilan hakim relevansi yang dapat dibuat satu permintaan (default 20): batch OTLP atau re-score evaluate_runs menilai 20 jejak pertamanya dan membaca sisanya secara leksikal, dengan judge.withheld: "request_cap" |
IRIS_RELEVANCE_JUDGE_REDACT | on (default): setiap span yang ditandai no_pii (data pribadi dan kredensial) dalam input dan output diganti dengan penanda [REDACTED:<kind>#<n>] sebelum dikirim ke hakim relevansi. off mengirimnya apa adanya |
IRIS_CITATION_ALLOW_FETCH | Atur ke 1 untuk mengizinkan HTTP keluar di verify_citations (mati secara default) |
IRIS_CITATION_DOMAINS | Daftar izin nama host yang dipisahkan koma untuk verify_citations (pencocokan akhiran) |
IRIS_OTEL_ENDPOINT | Aktifkan ekspor jejak OTLP/HTTP JSON upaya-terbaik ke URL kolektor ini |
IRIS_OTEL_SERVICE_NAME | Atribut sumber daya service.name untuk ekspor OTel (default iris-eval) |
IRIS_OTEL_HEADERS | Header k=v yang dipisahkan koma untuk ekspor OTel (mis. authorization=Bearer abc) |
IRIS_OTEL_TIMEOUT_MS | Batas waktu per-ekspor (default 15000) |
RATE_LIMIT_SALT | Hanya API daftar tunggu situs web — diperlukan ketika situs iris-eval.com diterapkan; server tidak pernah membacanya |
Keamanan
Ketika menggunakan transport HTTP, Iris mencakup:
- Autentikasi kunci API dengan perbandingan aman-waktu (Bearer untuk klien API; masuk browser ke dasbor melalui
?key=) - CORS dibatasi ke localhost secara default
- Pembatasan laju per alamat klien dan menit: 600 permintaan ke API dasbor (
security.rateLimit.api) dan 20 ke titik akhir MCP (security.rateLimit.mcp), keduanya diatur diconfig.json; permintaan MCP yang melebihi batas mendapatkan kesalahan JSON-RPC yang menyebutkan kunci - Header keamanan Helmet
- Validasi input Zod di semua rute
- Regex aman-ReDoS untuk aturan eval kustom
- Satu batas ukuran permintaan 1MB di setiap transport (
security.requestSizeLimit): HTTP menjawab413, stdio menjawab kesalahan JSON-RPC dan menjaga sesi tetap terbuka
# Production deployment
iris-eval --transport http --port 3000 --api-key "$(openssl rand -hex 32)" --dashboard
Dengan kunci yang ditetapkan, klien API — klien MCP, SDK penangkapan, POST /api/v1/traces — mengirim Authorization: Bearer <key>. Untuk membuka dasbor di peramban, tambahkan kunci sekali ke URL dasbor mana pun, http://localhost:6920/?key=<api key>: Iris menukarnya dengan kuki sesi HttpOnly, SameSite=Lax dan mengarahkan ulang ke halaman yang sama dengan kunci dihapus dari bilah alamat. Halaman yang dibuka tanpa sesi menampilkan formulir masuk yang melakukan pertukaran yang sama. Kunci tidak pernah disimpan di peramban, dan sesi hanya hidup di proses server (paling banyak 256 sesi aktif pada satu waktu; masuk yang menemukan semuanya aktif ditolak daripada mengusir salah satunya).
Produksi
Beberapa kunci, dan rotasi tanpa celah. security.apiKeys di config.json menampung sejumlah kunci tambahan, masing-masing dengan id dan tepat satu dari keyFile (file yang isinya yang dipangkas adalah kunci) atau keyHash (hex sha256 dari kunci, sehingga file konfigurasi tidak menyimpan rahasia — printf %s "$KEY" | openssl dgst -sha256), dan opsional expiresAt (ISO 8601) setelah itu kunci berhenti cocok pada saat itu juga. Untuk merotasi: tambahkan kunci baru, pindahkan klien Anda, hapus kunci lama. Kunci di config.json dan di file kunci berlaku tanpa memulai ulang (0.20.0): pada setiap permintaan, server memeriksa apakah config.json atau file kunci yang disebutnya telah berubah, dan jika demikian, membaca ulang kunci sebelum menjawab. Menghapus kunci dari security.apiKeys, atau menghapus file kuncinya, mencabutnya pada permintaan berikutnya: permintaan itu ditolak, dan setiap sesi peramban yang dibuka dengannya keluar. config.json yang tidak dapat dibaca (misalnya, setengah tertulis) gagal tertutup, dan sampai diperbaiki hanya kunci dari IRIS_API_KEY atau --api-key yang diterima. Kunci di IRIS_API_KEY atau --api-key itu sendiri, dan apakah autentikasi aktif sama sekali, tetap hanya berubah saat memulai ulang. Setiap kunci mengautentikasi sampai dihapus atau kedaluwarsa, di jalur Bearer dan di masuk peramban sama; log startup menyebutkan id-nya. security.rateLimit.mcpKeyBy: "apiKey" menghitung anggaran per menit titik akhir MCP per kunci, bukan per alamat klien, sehingga beberapa agen di belakang satu alamat masing-masing mendapatkan menitnya sendiri.
Iris menolak untuk memulai ketika transport HTTP atau dasbor terikat di luar loopback — 0.0.0.0, alamat LAN, kontainer — tanpa kunci API, dan mengatakannya dalam satu kalimat yang menyebutkan IRIS_API_KEY. Itu termasuk docker run telanjang dari gambar, yang mengikat 0.0.0.0 di dalam kontainer karena loopback tidak dapat dijangkau melalui port yang dipublikasikan. Loopback tanpa kunci tetap berfungsi (dengan peringatan pada transport HTTP): batas mesin adalah kontrol paparan di sana.
# The image: pass a key
docker run -p 3000:3000 -p 6920:6920 -v iris-data:/data \
-e IRIS_API_KEY="$(openssl rand -hex 32)" ghcr.io/iris-eval/mcp-server
# Compose: the file requires the variable and refuses before the container starts
IRIS_API_KEY="$(openssl rand -hex 32)" docker compose up
# A network you have already fenced some other way: run open, on purpose
IRIS_ALLOW_UNAUTHENTICATED=1 iris-eval --transport http --dashboard
Terbuka oleh desain, di server dengan kunci: GET /health di transport dan GET /api/v1/health di dasbor menjawab tanpa kunci dan di luar setiap batas laju, dalam satu bentuk: status, versi, waktu aktif, driver SQLite, checks untuk penyimpanan, file aturan yang diterapkan dan migrasi (diterapkan terhadap yang diketahui), status indeks pencarian (search: siap, atau seberapa jauh pembangunan telah berjalan sebagai bagian dari jejak), dan apakah kunci juri ada — tidak pernah kunci, tidak pernah jejak, tidak pernah jumlahnya. status adalah ok hanya ketika setiap pemeriksaan demikian; jika tidak, itu adalah degraded dengan HTTP 503, yang dibaca oleh HEALTHCHECK milik gambar Docker itu sendiri. Segala sesuatu yang lain membutuhkan Authorization: Bearer <key> atau sesi peramban. Retensi berjalan di setiap server: jejak dan evaluasi yang lebih lama dari retention.days (default 30) dihapus saat startup, setelah server menjawab, dan setiap retention.sweepIntervalHours, dalam langkah pendek yang tidak pernah membuat permintaan menunggu lama; --self-test mencetak kebijakan instalasi ini, dan iris://capabilities / GET /api/v1/capabilities membawanya sebagai retention.
Webhook menyala pada suatu saat (0.16.0): notify.webhook di config.json (atau IRIS_WEBHOOK_URL dan IRIS_WEBHOOK_SECRET) menamai penerima, dan Iris mengirim satu pesan yang ditandatangani ketika vonis gagal, veto deteksi kritis, biaya menjadi pencilan, tingkat kegagalan aturan bergeser, atau kasus dijawab dua arah untuk pertama kalinya — id, vonis, aturan dan angka, tidak pernah teks agen. Ditandatangani dengan cara Standard Webhooks dan cara GitHub sekaligus, dicoba ulang dengan backoff, didinginkan per agen dan aturan, tidak pernah menghalangi evaluasi; badan Slack dan Discord dibangun di dalamnya. docs/webhooks.md.
Data Anda di disk
Segala sesuatu yang disimpan Iris berada di bawah rumah Iris Anda (~/.iris, atau IRIS_HOME). iris.db menyimpan setiap jejak input dan output kata demi kata — termasuk teks apa pun yang no_pii lanjutkan untuk ditandai; deteksi tidak menyunting kecuali Anda memintanya: storage.redact: "critical_spans" di config.json menyimpan keluaran setiap evaluasi dengan rentang yang ditandai oleh detektor kritis diganti dengan [REDACTED:<pattern>] (nonaktif secara default; offset bukti masih mengindeks teks yang dilihat pemanggil). storage.synchronous mengatur kapan penulisan mencapai disk: normal (default) menyinkronkan log tulis-ahead di setiap titik pemeriksaan, sehingga kerusakan Iris tidak kehilangan apa pun dan file tidak dapat rusak, tetapi pemadaman listrik atau kerusakan sistem operasi dapat membatalkan penulisan sejak sinkronisasi terakhir; full menyinkronkan setiap komit dan menjaganya melalui keduanya, sekitar 1,5 ms lebih per penulisan. Saat startup, dan setiap retention.sweepIntervalHours (default 24, 0 menonaktifkan pengatur waktu) setelah itu, jejak dan evaluasi yang lebih lama dari retention.days (default 30, 0 menonaktifkan, diatur di config.json) dihapus dan log tulis-ahead diperiksa. Menghapus jejak — oleh delete_trace atau oleh sapuan — menghapus teks setiap evaluasi yang ditautkan ke sana (keluaran, teks yang diharapkan, dan pesan aturan) dan mencap erased_at; vonis, skor dan offset bukti tetap. Setiap penghapusan memeriksa log tulis-ahead sebelum kembali, sehingga teks yang dihapus tidak dibiarkan dapat dibaca di iris.db atau iris.db-wal (jika pencarian membaca file pada saat itu, atau proses lain membaca atau menulisnya, penghapusan kembali tanpa menunggu dan teks meninggalkan file segera setelah selesai). Untuk menghapus semuanya sekarang, hentikan server dan jalankan --purge: itu menghapus setiap jejak, rentang dan evaluasi yang disimpan, memadatkan database dan memotong log tulis-ahead sehingga teks hilang dari disk, dan menjaga aturan yang diterapkan, log audit dan preferensi Anda. Sebelum rilis menerapkan migrasi ke iris.db yang ada, itu menyalin file di sebelahnya (iris.db.<from>-to-<to>.<time>.bak, hanya pemilik, tiga terbaru disimpan; Downgrading): salinan memegang jejak sebagaimana adanya, sehingga sapuan retensi menghapus yang lebih lama dari retention.days dan --purge menghapus semuanya. Server melakukan salinan dan migrasi setelah menjawab kliennya, di utasnya sendiri: panggilan alat, pembacaan sumber daya dan permintaan HTTP yang tiba sementara itu menunggu mereka, paling banyak 30 detik masing-masing, dan kemudian ditolak dengan kalimat yang mengatakan apa yang dilakukan server (IRIS_STORAGE_ERROR, dapat dicoba ulang; HTTP 503 dengan Retry-After). Kesehatan menjawab sepanjang waktu dan mengatakan apa yang dilakukan peningkatan. Dari 0.19.0 pada 100.000 jejak yang masing-masing merupakan loop agen, salinan dan migrasi memakan waktu sekitar 6 detik. iris-eval ingest, --purge dan --self-test masih meningkatkan sebelum melakukan hal lain.
Iris tidak mengenkripsi datanya saat istirahat. iris.db dan file log tulis-aheadnya dibuat hanya pemilik (mode 600), dan direktori rumah Iris dibuat mode 700 (di Windows, ACL file yang mengatur sebagai gantinya). Database tidak menyimpan kunci penyedia LLM: IRIS_ANTHROPIC_API_KEY dan IRIS_OPENAI_API_KEY dibaca dari lingkungan dan tidak pernah ditulis ke disk. Itu menyimpan input dan output jejak kata demi kata, jadi letakkan rumah Iris di disk atau volume terenkripsi (FileVault, BitLocker, LUKS, atau volume cloud terenkripsi untuk /data mount gambar Docker).
Ekspor — tombol Ekspor di halaman Jejak dan Evaluasi dasbor, GET /api/v1/traces/export dan /api/v1/evaluations/export, atau iris-eval export — membawa teks tersimpan ini sebagaimana adanya, sama seperti yang ditampilkan dasbor: input dan output jejak kata demi kata, keluaran evaluasi dengan storage.redact diterapkan. Perlakukan file yang diekspor seperti database asalnya.
Pemecahan Masalah
Langkah pertama: jalankan tes mandiri
npx @iris-eval/mcp-server --self-test
Ini memeriksa penyimpanan, evaluasi deterministik, dan dasbor di rumah temp terisolasi dan mencetak vonis per langkah — keluaran kegagalan menyebutkan langkah yang rusak. Kode keluar 0 berarti instalasi sehat.
Iris tidak mau mulai / ERR_MODULE_NOT_FOUND
Anda mungkin memiliki versi lama yang di-cache. Bersihkan cache npx dan coba lagi:
npx --yes @iris-eval/mcp-server@latest
Atau instal secara global untuk menghindari masalah cache sepenuhnya:
npm install -g @iris-eval/mcp-server@latest
npm install --ignore-scripts merusak pengikatan SQLite
Iris menyimpan jejak dengan better-sqlite3, modul asli yang mengambil atau mengompilasi pengikatannya dalam skrip instalasi. Jika skrip itu dilewati — --ignore-scripts di baris perintah, ignore-scripts=true di .npmrc (umum di mesin perusahaan), atau cermin registri yang menghapus postinstall — startup gagal dengan dump "Tidak dapat menemukan file pengikatan" yang panjang mencantumkan selusin jalur yang dicobanya. Bangun ulang modul itu:
npm rebuild better-sqlite3
# for a global install:
npm rebuild -g better-sqlite3
Alat tidak muncul di Claude Code
Alat MCP hanya dimuat saat sesi dimulai. Setelah menambahkan iris-eval, mulai ulang sesi dengan /clear atau luncurkan ulang terminal.
Pemeriksaan versi
npx @iris-eval/mcp-server --version
Baris log startup pertama juga membawanya (Starting Iris MCP server vX.Y.Z), dan --self-test mencetaknya dalam ringkasannya. Untuk instalasi global, npm ls -g @iris-eval/mcp-server menunjukkan versi yang terinstal.
Memperbarui
Setiap klien MCP di mesin berbagi satu database, ~/.iris/iris.db, dan install menyematkan setiap klien ke rilis yang menulis konfigurasinya. Ketika rilis mengubah skema database, proses pertama dari rilis itu yang membuka file meningkatkan versinya, dan sejak saat itu klien yang masih disematkan ke rilis yang lebih lama menolak untuk memulai. Jadi pindahkan setiap klien dalam satu langkah, sebelum atau tepat setelah Anda meningkatkan:
npx -y @iris-eval/mcp-server@latest install --upgrade
Ini menemukan setiap konfigurasi klien di mesin ini yang menjalankan Iris, memindahkan setiap pin ke rilis itu (menjaga apa pun yang Anda tambahkan ke entri, seperti --dashboard atau blok env), membiarkan pin ke rilis yang lebih baru dan entri yang menjalankan sesuatu selain paket npm, dan mencantumkan apa yang dilakukannya. Mulai ulang klien yang disebutnya. install --list menunjukkan Iris mana yang dijalankan setiap klien.
Dua instalasi hidup di luar file-file itu: ekstensi Claude Desktop (iris-eval.mcpb) bergerak ketika Anda membuka bundel yang lebih baru, dan plugin Claude Code dengan claude plugin marketplace update iris-eval dan kemudian claude plugin update iris-eval@iris-eval (dan claude plugin update iris-eval-capture@iris-eval untuk plugin penangkapan).
Meningkatkan dari 0.19.x ke 0.20.0. 0.20.0 menambahkan indeks pencarian dan tambahan lain ke database (migrasi 015 dan seterusnya). Setelah proses 0.20.0 apa pun membuka ~/.iris/iris.db (ekstensi Claude Desktop, npx iris-eval, atau npx @iris-eval/mcp-server tanpa versi), klien yang disematkan ke 0.19.x berhenti dengan This database was migrated by a newer Iris (…) — migration(s) 015-trace-search, … are unknown to v0.19.0. Upgrade Iris, …. Pesan itu berasal dari 0.19.x dan tidak dapat berubah; perbaikannya adalah perintah di atas. Sebelum peningkatan, 0.20.0 menyalin file di sebelahnya, sehingga kembali juga dimungkinkan (di bawah).
Mulai yang meningkatkan database mencetak apa yang dilakukannya di stderr: salinan yang diambilnya, rilis yang lebih lama mana yang tidak dapat lagi membuka file, dan klien mana pun di mesin ini yang disematkan ke salah satunya, dengan perintah. --self-test membaca database tanpa mengubahnya dan mengatakan hal yang sama sebelum Anda memulai apa pun.
Untuk instalasi global, npm update -g @iris-eval/mcp-server, lalu iris-eval install --upgrade.
Menurunkan versi
Rilis yang meningkatkan basis data akan menyalinnya terlebih dahulu, di sebelahnya: iris.db.<from>-to-<to>.<time>.bak di direktori home Iris Anda (<from> adalah rilis yang terakhir mengubah skema file, <to> adalah yang meningkatkannya; baris startup mencetak jalur persisnya). Untuk kembali:
- Hentikan setiap klien MCP dan proses Iris lain yang menggunakan basis data.
- Simpan file yang telah ditingkatkan, untuk berjaga-jaga jika Anda kembali: ganti nama
iris.dbmenjadiiris.db.upgraded, dan hapusiris.db-waldaniris.db-shmjika ada. - Salin cadangan ke
iris.db:cp ~/.iris/iris.db.0.19.0-to-0.20.0.<time>.bak ~/.iris/iris.db. - Kunci setiap klien kembali ke rilis yang lebih lama:
npx -y @iris-eval/mcp-server@0.19.0 install <client>untuk masing-masing (install --upgradetidak pernah memindahkan klien kembali).
Jejak yang disimpan setelah peningkatan berada di iris.db.upgraded, bukan di cadangan. Jika tidak ada salinan yang diambil (baris startup menjelaskan alasannya, misalnya disk penuh), rilis yang lebih lama tidak dapat membuka file yang telah ditingkatkan, dan jalan ke depan adalah install --upgrade.
Driver penyimpanan
Pada platform tanpa better-sqlite3 yang sudah dikompilasi sebelumnya, instalasi tetap berhasil. better-sqlite3 adalah dependensi opsional: ketika npm tidak dapat mengunduh biner yang sudah dikompilasi untuk Node dan platform Anda maupun mengompilasinya (kompilasi membutuhkan Python dan toolchain C++ — alat build C++ Visual Studio di Windows), npm mencetak kesalahan build, melewati modul, dan menyelesaikan instalasi. Iris kemudian berjalan di SQLite bawaan Node, dan mengatakannya: startup mencetak satu baris di stderr yang menyebutkan alasannya, dan --self-test menampilkan driver node: better-sqlite3 is not installed …. Untuk mendapatkan driver asli kembali, instal di tempat yang memiliki prebuild atau toolchain (npm install better-sqlite3 di proyek; untuk instalasi global, instal Iris lagi dengan npm install -g @iris-eval/mcp-server setelah toolchain tersedia). CI menginstal server yang dikemas dengan build asli yang dipaksa gagal pada setiap perubahan, dan mengharuskan instalasi selesai serta self-test untuk menyimpan dan membaca jejak di bawaan.
Iris menyimpan semuanya dalam satu file SQLite, dibuka oleh better-sqlite3 — addon asli yang diunduh atau dikompilasi untuk Node dan platform Anda. Ketika modul itu tidak dapat dimuat, Iris jatuh kembali ke SQLite bawaan Node (node:sqlite, Node 22.13 atau lebih baru) dengan satu peringatan di stderr, sehingga prebuild yang hilang adalah start yang lebih lambat, bukan yang mati. Ia melakukan hal yang sama, sebelum memuatnya, untuk better-sqlite3 yang dikompilasi di mesin Anda terhadap header Node 24.19 atau lebih baru: pada setiap rilis 24.x sejauh ini, biner semacam itu menghentikan seluruh proses saat pertama kali membebaskan pernyataan (Assertion failed: (env) != nullptr, nodejs/node#65446), dan npm rebuild better-sqlite3 menggantinya dengan biner yang sudah dikompilasi, yang aman. IRIS_SQLITE_DRIVER=node memilih bawaan dengan sengaja, native melarang fallback. Bawaan dibuka dengan ekstensi dimatikan dan trusted_schema dimatikan; Node mencetak baris ExperimentalWarning: SQLite is an experimental feature sendiri di stderr saat memuat, dan Iris tidak membungkamnya. --self-test dan GET /health menyebutkan driver yang digunakan; setiap angka di halaman bukti diukur pada driver asli, dan rangkaian pengujian berjalan pada keduanya di CI.
Versi Node.js
Iris membutuhkan Node.js 22.13 atau lebih baru. Node 20 mencapai akhir masa pakainya pada 2026-04-30 dan tidak didukung; Node 18 berakhir pada April 2025.
Batas bawahnya adalah 22.13, bukan 22.0, karena 22.13.0 adalah rilis pertama yang mengirimkan node:sqlite. Itu menjadikannya versi pertama di mana setiap instalasi Iris yang didukung memiliki driver penyimpanan kedua: ketika addon better-sqlite3 asli tidak dapat dimuat, Iris jatuh kembali ke SQLite bawaan Node alih-alih gagal untuk memulai. Di bawah 22.13 — dan di Node 20, sepanjang masa pakainya — hanya ada satu driver, dan prebuild yang hilang adalah start yang mati.
node --version # Must be v22.13.0 or newer
Windows: cmd /c tidak diperlukan
/doctor Claude Code mungkin menyarankan membungkus npx dengan cmd /c. Ini tidak diperlukan dan menyebabkan masalah penguraian jalur. Gunakan npx secara langsung:
# Correct
claude mcp add --transport stdio iris-eval -- npx -y @iris-eval/mcp-server
# Wrong (causes /c to be parsed as a path)
claude mcp add --transport stdio iris-eval -- cmd /c "npx -y @iris-eval/mcp-server"
Jika Iris berguna bagi Anda, pertimbangkan untuk memberi bintang pada repo — ini membantu orang lain menemukannya.
Dilisensikan di bawah MIT.