Track every LLM call, prompt, tool invocation, conversation and token spent across your IDEs, CLIs and agents. Run the collector as a binary or container, store events in SQLite by default, and inspect usage through the built-in dashboard.
- Collector-first workflow. Web UI, REST API, OTLP receiver and SQLite storage ship together.
- Multiple capture paths. Native OTLP, direct REST events, SDKs and HTTPS proxy capture cover different agent setups.
- Multi-agent reporting. Cursor, VS Code / GitHub Copilot, Claude Code, Codex CLI, Eclipse, OpenCode β all in one place.
- FinOps built in. Token and USD cost attribution by model, by day, with burn-rate and per-session breakdowns.
- Trace-level drill-down. Every conversation has a waterfall timeline of prompts, tool calls, latencies and errors when the source exposes them.
# Linux / macOS
curl -fsSL https://raw.githubusercontent.com/dnorio/agent-meter/main/install.sh | bash
# Windows (PowerShell)
irm https://raw.githubusercontent.com/dnorio/agent-meter/main/install.ps1 | iexInstalls a single agent-meter binary to ~/.local/bin. It downloads a
prebuilt release binary when one is available, otherwise builds from source
(needs Rust 1.75+ and git). Then:
agent-meter demo # see it instantly, with realistic synthetic data
agent-meter serve # run for real and ingest your own eventsgit clone https://github.com/dnorio/agent-meter.git
cd agent-meter
# See it instantly, with realistic synthetic data
cargo run -p agent-meter-collector -- demo
# β seeds sample conversations and opens http://127.0.0.1:8081
# Run for real (ingest your own events)
cargo run -p agent-meter-collector -- serve
# β http://127.0.0.1:8081 (UI + REST API)
# β http://127.0.0.1:4318 (OTLP receiver)demo generates realistic activity (multiple agents, models, tools, costs and
errors) so every page has something to show. It never collects real data and
won't re-seed a database that already has data β pass --force to reseed.
By default, state lives in agent-meter.db (SQLite) in the working directory.
Set DATABASE_URL to use Postgres.
docker compose -f docker-compose.standalone.yml up -d --build
open http://localhost:8081The Compose file runs as non-root with a read-only root filesystem, tmpfs at
/tmp, and a named volume at /data for SQLite. See
docs/docker-runtime.md for healthcheck behavior and
troubleshooting.
π¦ Prebuilt binaries β latest release
- Collector:
agent-meter(Linux, macOS, Windows)- HTTPS proxy:
agent-meter-proxy(same platforms)- Install:
install.sh/install.ps1Β· proxy:install-proxy.sh/install-proxy.ps1- Full stack (collector + proxy):
install-full.sh/install-full.ps1Or:curl -fsSL https://raw.githubusercontent.com/dnorio/agent-meter/main/install-full.sh | bashAGENT_METER_WITH_PROXY=1 curl -fsSL β¦/install.sh | bashSDKs:npm install @dnorio/agent-meterΒ·pip install agentmeter-obs(ordnorio-agent-meter)
agent-meter accepts telemetry three ways:
| Method | Source | How |
|---|---|---|
| REST | Any agent / script | POST /events/tool-call (JSON) |
| OTLP | VS Code (GitHub Copilot), SDKs, any OTel exporter | POST /v1/traces on :8081 or dedicated :4318 |
| HTTPS proxy | Cursor, Eclipse, Claude Code, Codex CLI | mitmproxy addons in eclipse-proxy/ |
See docs/capture-setup.md for proxy and IDE-specific setup.
curl -X POST http://127.0.0.1:8081/events/tool-call \
-H "Content-Type: application/json" \
-d '{
"event_id": "11111111-1111-4111-8111-111111111111",
"tool_name": "read_file",
"mcp_server": "filesystem",
"agent": "cursor",
"model": "gpt-4o",
"conversation_id": "demo-1",
"started_at": "2026-01-15T10:00:00Z",
"ended_at": "2026-01-15T10:00:01Z",
"ok": true,
"estimated_input_tokens": 1200,
"estimated_output_tokens": 300
}'{
"github.copilot.chat.otel.enabled": true,
"github.copilot.chat.otel.otlpEndpoint": "http://127.0.0.1:4318"
}π§ Running on WSL? Follow the step-by-step WSL + Copilot quickstart to capture live Copilot activity from another machine.
| Page | Route | What it shows |
|---|---|---|
| Dashboard | / |
KPIs, calls over time, top tools & MCP servers |
| Conversations | /conversations |
Agent sessions grouped by conversation_id, with drill-down |
| Timeline | /conversations/:id/timeline |
Per-conversation waterfall of tool calls |
| Reports | /reports |
Query-able tiles; every tile is also a JSON endpoint |
| Cost | /cost |
Token usage and USD attribution by model and day |
| Method | Endpoint | Description |
|---|---|---|
POST |
/events/tool-call |
Ingest a tool-call event |
POST |
/v1/traces |
OTLP trace ingest (port :4318) |
GET |
/api/conversations |
List conversations (paginated) |
GET |
/api/conversations/:id/timeline |
Conversation timeline (events + summary) |
GET |
/reports/calls-over-time |
Time-series of tool calls |
GET |
/reports/top-tools |
Most-used tools |
GET |
/reports/top-mcp-servers |
Most active MCP servers |
GET |
/api/cost/summary |
Token & USD cost summary |
DELETE |
/api/conversations/:id |
Delete one session and all its events |
POST |
/api/admin/reset |
Wipe all ingested events (local reset) |
GET |
/health |
Health check |
GET |
/openapi.json |
OpenAPI 3.1 spec |
GET |
/api/version |
Collector version and config flags |
Machine-readable API: /openapi.json (also linked from /api/version).
All settings have sensible defaults; override via environment variables or a TOML
file (--config agent-meter.toml, see agent-meter.example.toml).
| Variable | Default | Description |
|---|---|---|
AGENT_METER_HOST |
127.0.0.1 |
Bind address |
AGENT_METER_PORT |
8081 |
UI + REST port |
AGENT_METER_OTLP_PORT |
4318 |
OTLP receiver port |
DATABASE_URL |
sqlite://agent-meter.db |
SQLite by default; postgres://β¦ also supported |
AGENT_METER_NO_OPEN |
(unset) | Set to skip auto-opening the browser |
AGENT_METER_REQUIRE_API_KEY |
0 |
Set to 1 to require Bearer API keys on ingest |
RUST_LOG |
info |
Log level |
PostgreSQL is optional. Point
DATABASE_URLat apostgres://URL for a shared/server deployment; SQLite is the zero-config default.
Cost estimates. When a client doesn't send an explicit cost, agent-meter estimates USD from token counts using approximate public per-model list prices, so the FinOps views always have a sensible number.
# Delete one conversation (and all its events)
curl -X DELETE http://127.0.0.1:8081/api/conversations/demo-conv-03
# Wipe everything (fresh start before a live capture)
curl -X POST http://127.0.0.1:8081/api/admin/resetThese admin endpoints are unauthenticated. Keep the collector bound to
127.0.0.1 for local use, or put it behind your own auth/reverse proxy when
exposing it beyond a trusted machine.
For Docker on a network interface, use
docker-compose.secure.yml to require API keys on
ingest (AGENT_METER_REQUIRE_API_KEY=1).
# Create a key (secret shown once)
agent-meter keys create --name my-sdk
# List key prefixes
agent-meter keys list
# Require keys on ingest
export AGENT_METER_REQUIRE_API_KEY=1
agent-meter serveagent-meter/
βββ crates/
β βββ collector/ # Axum HTTP server (REST API + OTLP + embedded Web UI)
β β βββ src/
β β β βββ routes/ # API + page handlers
β β β βββ otlp/ # OTLP receiver + IDE detection
β β β βββ services/ # Event mapping, ingest buffer
β β β βββ demo.rs # Synthetic data generator (`demo` command)
β β βββ ui/ # HTML pages + static assets (embedded in the binary)
β βββ db/ # Database trait + SQLite & Postgres implementations
β βββ cli/ # CLI client
β βββ proxy/ # HTTPS proxy helpers
β βββ mcp-wrapper/ # MCP wrapper proxy
βββ eclipse-proxy/ # mitmproxy addon (Eclipse + Copilot CLI)
βββ sdk/ # Client SDKs (Node, Python)
βββ migrations/ # Postgres migrations (optional backend)
βββ docs/ # Documentation
βββ docker-compose.standalone.yml
- Prompt-aware telemetry. Prompts can be stored when the source exposes content; VS Code requires
captureContent: truefor prompt text. - No credentials stored. The collector records telemetry fields, not API keys or bearer tokens.
- Deployment boundary is yours. The default bind address is local; use normal network/auth controls if you expose the collector elsewhere.
- Pre-public gates:
oss-scrub-check.sh(tree) +secret-scan-history.sh(gitleaks + all blobs) +history-audit.sh(history). - Private pattern checks: maintainers can provide local-only patterns via ignored
scripts/ci/private-patterns.txt. - Report issues: SECURITY.md
MIT Β© agent-meter contributors


