Local AI agent telemetry, benchmarking, and model calibration for OpenCode agents.
Originally developed within the Gentle AI ecosystem.
Metronous tracks every tool call, session, and cost from your OpenCode agents β then runs weekly benchmarks to tell you which agents are underperforming and which model would save you money.
- Tracks agent sessions, tool calls, tokens, and cost in real-time
- Benchmarks each agent against accuracy and ROI thresholds
- Recommends model switches with data-driven reasoning
- Visualizes everything in a 5-tab terminal dashboard (TUI)
OpenCode β metronous-plugin.ts β HTTP POST /ingest β metronous daemon β SQLite
β
metronous dashboard (TUI)
- Plugin (
metronous-plugin.ts): OpenCode plugin that captures agent events and forwards them to the daemon via HTTP. Accumulates cost fromstep-finishevents, can sendX-Metronous-AuthwhenMETRONOUS_INGEST_TOKENis set, and persists session cost to~/.metronous/data/session_costs.jsonacross restarts. - MCP shim (
metronous mcp): stdioβHTTP bridge launched by OpenCode as an MCP server. Reads the daemon port from~/.metronous/data/mcp.port, forwards events, and mirrors the same optional ingest token. - Daemon (
metronous server --daemon-mode): Long-lived background service (systemd on Linux) that ingests events, stores them in SQLite, and runs weekly benchmarks at Monday 02:00 local time. IfMETRONOUS_INGEST_TOKENis set, it validates ingest headers and logs unauthenticated requests during the transition. - TUI Dashboard: 5-tab terminal UI with live tracking, benchmark results, cost charts, and config editing.
For full component details see docs/ARCHITECTURE.md.
For benchmark methodology see docs/BENCHMARKS.md.
- OpenCode installed β
curl -fsSL https://opencode.ai/install | bash
Metronous works with OpenCode's built-in agents out of the box. If you have an opencode.json, Metronous will patch it automatically. If not, it will create one and you can add providers and agents to it later.
Go 1.22+ is only required for source builds and go install.
- Linux: official install flow (one command)
- macOS: official install flow (one command)
- Windows: experimental/manual
curl -fsSL https://github.com/kiosvantra/metronous/releases/latest/download/install.sh | bashThis script downloads the latest release, verifies the checksum, installs the binary to ~/.local/bin, and runs metronous install to set up the systemd service and configure OpenCode automatically.
Do not run with
sudo. Must run as the same normal user that runs OpenCode.
VERSION=$(curl -sSL https://api.github.com/repos/kiosvantra/metronous/releases/latest | grep '"tag_name"' | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+' | head -1)
ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')
TARBALL="metronous_${VERSION#v}_linux_${ARCH}.tar.gz"
curl -fsSLO "https://github.com/kiosvantra/metronous/releases/download/${VERSION}/${TARBALL}"
curl -fsSLO "https://github.com/kiosvantra/metronous/releases/download/${VERSION}/checksums.txt"
sha256sum -c --ignore-missing checksums.txt
tar -xzf "${TARBALL}"
mkdir -p ~/.local/bin
install -m 0755 ./metronous ~/.local/bin/metronous
rm -f "${TARBALL}" checksums.txt
~/.local/bin/metronous installgo install github.com/kiosvantra/metronous/cmd/metronous@latest
# Ensure the installed binary is on your PATH, then run:
metronous installgit clone https://github.com/kiosvantra/metronous
cd metronous
go build -o metronous ./cmd/metronousLinux:
mkdir -p ~/.local/bin
install -m 0755 ./metronous ~/.local/bin/metronous
~/.local/bin/metronous install# Download the matching Windows archive from GitHub Releases,
# for example: metronous_<version>_windows_amd64.zip
# Run PowerShell as Administrator before continuing.
$archive = "metronous_<version>_windows_amd64.zip"
Expand-Archive -Path $archive -DestinationPath .\metronous-release -Force
$exe = Get-ChildItem .\metronous-release -Recurse -Filter metronous.exe | Select-Object -First 1
$dest = "$env:LOCALAPPDATA\Programs\Metronous"
New-Item -ItemType Directory -Force -Path $dest | Out-Null
Move-Item $exe.FullName "$dest\metronous.exe" -Force
& "$dest\metronous.exe" installOptionally verify the archive before extracting it by comparing its SHA-256 hash with checksums.txt from the same release.
Run the elevated PowerShell session as the same Windows user account that runs OpenCode.
Windows support is currently experimental. The native service/install flow is still being hardened, so Linux is the only officially supported installer path.
curl -fsSL https://github.com/kiosvantra/metronous/releases/latest/download/install.sh | bashSame as Linux β downloads the latest release, verifies the checksum, installs the binary to ~/.local/bin, and runs metronous install to set up the daemon and configure OpenCode automatically.
Supports both Intel (amd64) and Apple Silicon (arm64).
Do not run with
sudo. Must run as the same normal user that runs OpenCode.
& "$env:LOCALAPPDATA\Programs\Metronous\metronous.exe" installNote:
metronous installon Windows requires an elevated terminal (Run as Administrator) to register the Windows service.
For manual control:
& "$env:LOCALAPPDATA\Programs\Metronous\metronous.exe" service start
& "$env:LOCALAPPDATA\Programs\Metronous\metronous.exe" service stop
& "$env:LOCALAPPDATA\Programs\Metronous\metronous.exe" service status
& "$env:LOCALAPPDATA\Programs\Metronous\metronous.exe" service uninstallAfter running metronous install on Linux, your OpenCode will be configured with:
- MCP shim: the installed executable path plus
mcpfor telemetry ingestion - OpenCode plugin:
metronous.tscopied to~/.config/opencode/plugins/
The plugin captures agent sessions and forwards events to the daemon via HTTP.
Then restart OpenCode and it will show "Metronous Connected".
metronous dashboardThe dashboard has five tabs (press the number key to switch):
| # | Tab | Description |
|---|---|---|
| 1 | Benchmark History Summary | Weighted historical view of all (agent, model) pairs active in the last 4 weekly cycles. Cascade sort: active model first (marked β), superseded models below. Verdict shown only for the active model. |
| 2 | Benchmark Detailed | Per-run history grouped into Sunday-bounded run cycles. Press Enter to freeze/unfreeze the detail panel. PgUp/PgDn to navigate cycles. Press F5 to trigger an intraweek benchmark run. |
| 3 | Tracking | Real-time session stream (last 20 sessions, refreshes every 2s). Press Enter on a session to open the Session Timeline popup showing per-event cost breakdown. |
| 4 | Charts | Monthly cost chart by model (log scale, stacked bars) with a day tooltip. Also shows Performance and Responsibility top-3 cards. β/β to navigate months, k/l or mouse to move the day cursor. |
| 5 | Config | Edit performance thresholds. Changes are saved to ~/.metronous/thresholds.json and propagated live to the benchmark engine. |
For keyboard navigation see docs/tui-controls.md.
Press Enter on any session row in the Tracking tab to open a popup with the full event timeline for that session. The popup shows:
| Column | Meaning |
|---|---|
Spent(acc) |
Accumulated cost up to this event (cumulative snapshot stored in the DB) |
Spent(step) |
Delta between consecutive events = per-LLM-call cost (matches provider billing) |
Spent(step) is the most useful column for validating costs: each entry corresponds to one LLM request and its value should match what the provider charges per call.
The plugin computes session cost by summing the cost field from every step-finish event emitted by OpenCode's message.part.updated hook. This gives the actual per-request cost that accumulates across the session.
Key behaviors:
- Cost is persisted to
~/.metronous/data/session_costs.jsonso restarts mid-session do not lose accumulated cost. lastActiveModelonly updates when the model string has a provider prefix (e.g.opencode/claude-sonnet-4-6). Bare model names likeclaude-sonnet-4-6are never used to downgrade a known provider-prefixed model.- NaN and non-finite values in cost and token fields are silently dropped.
# Via TUI: press F5 on the Benchmark Detailed tab
# Via CLI:
METRONOUS_DATA_DIR=~/.metronous/data go run cmd/run-benchmark/main.goAll data lives in ~/.metronous/:
~/.metronous/
βββ data/
β βββ tracking.db # Event telemetry (SQLite, WAL mode)
β βββ benchmark.db # Benchmark run history (SQLite)
β βββ mcp.port # Dynamic HTTP port (runtime)
β βββ metronous.pid # Server PID (runtime)
β βββ session_costs.json # Persisted session costs across plugin restarts
β βββ plugin.log # Plugin debug log (when METRONOUS_DEBUG=true)
βββ thresholds.json # Performance thresholds (editable via TUI)
The Config tab (5) exposes three active fields:
| Field | Default | Effect |
|---|---|---|
| Min Accuracy | 0.85 | Accuracy below this triggers SWITCH |
| Min ROI Score | 0.05 | ROI below this triggers SWITCH (paid models only) |
| Max Cost/Session | $0.50 | Reference for cost semaphore color in the Tracking tab; also used for urgent spike detection |
ROI = accuracy / avg_cost_per_session. Higher ROI means more accurate output per dollar spent.
For the full threshold schema and urgent triggers see docs/BENCHMARKS.md.
- Accuracy =
(total_events - error_events) / total_events - ROI =
accuracy / cost_per_sessionwhere cost_per_session =sum of MAX(cost_usd) per session_id - Health score = 60 pts accuracy + 25 pts verdict + 15 pts ROI (0β100 scale)
- Verdicts:
KEEP/SWITCH/URGENT_SWITCH/INSUFFICIENT_DATA - Minimum sample size: 50 events (below this β
INSUFFICIENT_DATA) URGENT_SWITCHtriggers when accuracy < 0.60 or error rate > 30%
For full methodology details see docs/BENCHMARKS.md.
Metronous automatically discovers all agents from events in the tracking database:
- Built-in agents:
build,plan,general,explore - Custom agents: any agent defined in
opencode.jsonor~/.config/opencode/agents/*.md
For benchmarking, each agent is evaluated independently per model used. Here is an example set from the Gentle AI SDD ecosystem:
| Agent | Role |
|---|---|
sdd-orchestrator |
Coordinates sub-agents, never does work inline |
sdd-apply |
Implements code changes from task definitions |
sdd-explore |
Investigates codebase and thinks through ideas |
sdd-verify |
Validates implementation against specs |
sdd-spec |
Writes detailed specifications from proposals |
sdd-design |
Creates technical design from proposals |
sdd-propose |
Creates change proposals from explorations |
sdd-tasks |
Breaks down specs and designs into tasks |
sdd-init |
Bootstraps SDD context and project configuration |
sdd-archive |
Archives completed change artifacts |
MIT β see LICENSE
