@semboja/opencode-claude
v0.2.1
Published
Claude usage tracking plugin for OpenCode - monitor tokens, costs, sessions, and API performance
Maintainers
Readme
@semboja/opencode-claude
Features
- Token Tracking: Input, output, cache read, and cache creation tokens
- Cost Monitoring: Track USD costs per request and session
- Performance Metrics: API latency and tool execution times
- Model Breakdown: Usage statistics per model
- Tool Analytics: Track tool invocations and success rates
- Daily Aggregation: View usage trends over time
- Multiple Storage Backends: File-based or in-memory storage
- Prometheus Integration: Export metrics for scraping or push to Pushgateway
- Grafana Dashboard: Pre-built dashboard for visualization
Installation
npm install @semboja/opencode-claude
# or
bun add @semboja/opencode-claudeConfiguration
1. Enable OpenTelemetry in OpenCode
Add to your .opencode/opencode.json:
{
"experimental": {
"openTelemetry": true
},
"plugin": ["@semboja/opencode-claude"]
}2. Environment Variables (Optional)
| Variable | Default | Description |
|----------|---------|-------------|
| CLAUDE_TRACKER_STORAGE | file | Storage type: file or memory |
| CLAUDE_TRACKER_PATH | ~/.opencode/claude-usage | Storage directory path |
| CLAUDE_TRACKER_VERBOSE | 0 | Set to 1 for verbose logging |
| CLAUDE_TRACKER_FLUSH_INTERVAL | 30000 | Flush interval in milliseconds |
3. Prometheus Configuration (Optional)
| Variable | Default | Description |
|----------|---------|-------------|
| CLAUDE_TRACKER_PROMETHEUS | 0 | Set to 1 to enable Prometheus metrics server |
| CLAUDE_TRACKER_PROMETHEUS_PORT | 9464 | Port for /metrics endpoint |
| CLAUDE_TRACKER_PUSHGATEWAY_URL | - | Pushgateway URL (e.g., http://localhost:9091) |
| CLAUDE_TRACKER_PUSHGATEWAY_JOB | claude_tracker | Job name for Pushgateway |
| CLAUDE_TRACKER_PUSHGATEWAY_INTERVAL | 15000 | Push interval in milliseconds |
Usage
Once configured, the plugin automatically tracks all Claude API usage. No additional code changes required.
Viewing Usage Reports
Use the CLI to view your usage:
# Show usage report
npx claude-tracker report
# List recent sessions
npx claude-tracker sessions 20
# Export as JSON
npx claude-tracker export json > usage.json
# Export as CSV
npx claude-tracker export csv > usage.csvExample Report Output
=== Claude Usage Report ===
Total Sessions: 42
Total API Requests: 1,337
Total Cost: $12.3456
Token Usage:
Input: 1,234,567
Output: 456,789
Cache Read: 789,012
Cache Creation: 123,456
Total: 2,603,824
Usage by Model:
Model Requests Tokens Cost
---------------------------------------------------------------------------
claude-sonnet-4-20250514 1000 1,500,000 $8.5000
claude-opus-4-20250514 337 1,103,824 $3.8456
Top Tools:
Tool Calls Success Avg Time
---------------------------------------------------
Read 500 99.8% 12ms
Edit 250 98.5% 45ms
Bash 200 95.0% 234msCost Calculation
The plugin automatically calculates costs based on Claude model pricing:
| Model | Input (per MTok) | Output (per MTok) | |-------|------------------|-------------------| | Claude Opus 4 | $15.00 | $75.00 | | Claude Sonnet 4 | $3.00 | $15.00 | | Claude Haiku 4 | $0.80 | $4.00 |
Cache tokens are also calculated:
- Cache read: 10% of input price
- Cache creation: 25% more than input price
Prices are updated as of January 2025. The plugin normalizes model names (e.g., claude-opus-4-5 → Opus 4 pricing).
Data Storage
By default, usage data is stored in ~/.opencode/claude-usage/:
~/.opencode/claude-usage/
├── sessions/
│ ├── <session-id>.json # Session summaries
│ └── ...
└── requests/
├── <session-id>.jsonl # Individual API requests
└── ...Tracked Metrics
Per API Request
- Timestamp
- Model name
- Duration (ms)
- Input tokens
- Output tokens
- Cache read tokens
- Cache creation tokens
- Cost (USD)
- Success/failure status
Per Session
- Session ID
- Start/end time
- Total tokens by type
- Total cost
- API request count
- Tool usage breakdown
- Per-model breakdown
Aggregated Statistics
- Total sessions
- Total API requests
- Total tokens by type
- Total cost
- Usage by model
- Usage by day
- Top tools by invocation count
Prometheus & Grafana Integration
This section provides a complete, step-by-step guide to set up monitoring for your Claude usage using Prometheus and Grafana. No prior experience with these tools is required.
What is Prometheus and Grafana?
- Prometheus: A time-series database that collects and stores metrics (numbers over time)
- Grafana: A visualization tool that creates beautiful dashboards from your metrics
- Pushgateway: A bridge that accepts metrics from short-lived jobs (like CLI commands)
Together, they let you see charts of your Claude API usage, costs, and performance over time.
Prerequisites
Before starting, make sure you have:
Docker and Docker Compose installed
# Check if Docker is installed docker --version # Should output something like: Docker version 24.0.0 # Check if Docker Compose is installed docker compose version # Should output something like: Docker Compose version v2.20.0If not installed, download from: https://docs.docker.com/get-docker/
Node.js 18+ installed
node --version # Should output v18.0.0 or higherThe plugin installed in your OpenCode project
npm install @semboja/opencode-claude
Step 1: Start the Monitoring Stack
First, clone the repository (or copy the docker-compose.yml to your project):
# Clone the repository
git clone https://github.com/SembojaTech/opencode-claude.git
cd opencode-claude
# Start all services in the background
docker compose up -dYou should see output like:
[+] Running 4/4
✔ Network claude-monitoring Created
✔ Container claude-pushgateway Started
✔ Container claude-prometheus Started
✔ Container claude-grafana StartedStep 2: Verify Services Are Running
Check that all containers are healthy:
docker compose psExpected output:
NAME STATUS PORTS
claude-grafana running 0.0.0.0:3000->3000/tcp
claude-prometheus running 0.0.0.0:9090->9090/tcp
claude-pushgateway running 0.0.0.0:9091->9091/tcpTest each service in your browser:
| Service | URL | What You Should See | |---------|-----|---------------------| | Prometheus | http://localhost:9090 | Prometheus web UI with query box | | Pushgateway | http://localhost:9091 | Pushgateway status page | | Grafana | http://localhost:3000 | Login page (use admin/admin) |
Step 3: Configure the Plugin
You have two options for sending metrics. Choose based on your use case:
Option A: Pushgateway (Recommended for CLI usage)
Best for: Short-lived OpenCode sessions, CLI tools
# Add to your shell profile (~/.bashrc, ~/.zshrc) or run before starting OpenCode
export CLAUDE_TRACKER_PUSHGATEWAY_URL=http://localhost:9091
export CLAUDE_TRACKER_VERBOSE=1 # Optional: see logsOption B: Direct Prometheus Scraping
Best for: Long-running OpenCode sessions, server deployments
export CLAUDE_TRACKER_PROMETHEUS=1
export CLAUDE_TRACKER_PROMETHEUS_PORT=9464
export CLAUDE_TRACKER_VERBOSE=1 # Optional: see logsNote: You can enable both options simultaneously.
Step 4: Generate Some Test Metrics
Now use OpenCode normally to generate some Claude API calls:
# Start OpenCode with the environment variables set
opencodeMake a few requests to Claude (ask questions, run commands, etc.). The plugin will automatically track:
- Token usage (input, output, cache)
- Costs in USD
- API latency
- Tool invocations
Step 5: Verify Metrics Are Being Collected
If using Pushgateway:
- Open http://localhost:9091 in your browser
- You should see metrics listed under "claude_tracker" job
- Look for metrics like
claude_tokens_total,claude_sessions_total
If using direct scraping:
- Check the metrics endpoint directly:
curl http://localhost:9464/metrics - You should see output like:
# HELP claude_tokens_total Total number of tokens used # TYPE claude_tokens_total counter claude_tokens_total{type="input",model="claude-sonnet-4"} 1234 claude_tokens_total{type="output",model="claude-sonnet-4"} 567 ...
Verify in Prometheus:
- Open http://localhost:9090
- In the query box, type:
claude_tokens_total - Click "Execute"
- You should see your metrics data
If you see "No data points found", wait a minute and try again - Prometheus scrapes every 15 seconds.
Step 6: Set Up Grafana Dashboard
First-time Grafana Login:
- Open http://localhost:3000
- Login with:
- Username:
admin - Password:
admin
- Username:
- You'll be prompted to change the password (you can skip this for local testing)
Import the Dashboard:
Method 1: Auto-provisioned (if using docker-compose)
The dashboard should already be available:
- Click the hamburger menu (☰) on the left
- Click "Dashboards"
- Look for "Claude Usage Dashboard"
Method 2: Manual Import
- Click the hamburger menu (☰) on the left
- Click "Dashboards"
- Click "New" → "Import"
- Either:
- Click "Upload JSON file" and select
grafana/claude-usage-dashboard.json - Or paste the contents of the JSON file
- Click "Upload JSON file" and select
- Click "Load"
- Select "Prometheus" as the data source
- Click "Import"
Step 7: Understanding the Dashboard
The dashboard shows several panels:
| Panel | What It Shows | |-------|---------------| | Total Tokens | Cumulative token count across all sessions | | Total Cost (USD) | How much you've spent on Claude API | | Total API Requests | Number of API calls made | | Total Sessions | Number of OpenCode sessions | | Token Rate by Type | Input vs output tokens over time | | Cost Rate by Model | Spending per model (Opus, Sonnet, etc.) | | API Request Latency | How fast Claude responds (p50, p95, p99) | | API Requests by Status | Success vs error rates | | Top 10 Tools | Most frequently used tools (Read, Edit, Bash, etc.) | | Tool Execution Latency | How long each tool takes |
Step 8: Test the Complete Pipeline
Let's verify everything works end-to-end:
# 1. Make sure environment is set
export CLAUDE_TRACKER_PUSHGATEWAY_URL=http://localhost:9091
export CLAUDE_TRACKER_VERBOSE=1
# 2. Start OpenCode and make some requests
opencode
# 3. In OpenCode, ask Claude something like:
# "What is 2 + 2?"
# "Read the README.md file"
# 4. Exit OpenCode (this flushes metrics)Now check your data:
- Pushgateway (http://localhost:9091): Should show new metrics
- Prometheus (http://localhost:9090): Query
claude_sessions_total- should show at least 1 - Grafana (http://localhost:3000): Dashboard should show updated graphs
Prometheus Metrics Reference
| Metric | Type | Labels | Description |
|--------|------|--------|-------------|
| claude_tokens_total | Counter | type, model | Total tokens by type (input, output, cache_read, cache_creation) |
| claude_cost_usd_total | Counter | model | Total cost in USD |
| claude_api_requests_total | Counter | model, status | API request count by status (success/error) |
| claude_sessions_total | Counter | - | Total session count |
| claude_tool_invocations_total | Counter | tool, status | Tool invocations by status |
| claude_api_request_duration_seconds | Histogram | model | API request latency |
| claude_tool_duration_seconds | Histogram | tool | Tool execution latency |
| claude_session_tokens | Gauge | type | Current session token counts |
| claude_session_cost_usd | Gauge | - | Current session cost |
Example Prometheus Queries
Try these queries in Prometheus (http://localhost:9090):
# Total tokens used (all time)
sum(claude_tokens_total)
# Total tokens in the last hour
sum(increase(claude_tokens_total[1h]))
# Current cost in USD
sum(claude_cost_usd_total)
# Cost rate by model ($ per minute)
sum(rate(claude_cost_usd_total[5m])) by (model) * 60
# API request success rate (percentage)
sum(rate(claude_api_requests_total{status="success"}[5m])) /
sum(rate(claude_api_requests_total[5m])) * 100
# 95th percentile API latency (seconds)
histogram_quantile(0.95, sum(rate(claude_api_request_duration_seconds_bucket[5m])) by (le))
# Top 5 most used tools
topk(5, sum(claude_tool_invocations_total) by (tool))
# Average tokens per request
sum(rate(claude_tokens_total[5m])) / sum(rate(claude_api_requests_total[5m]))Troubleshooting
"No data" in Grafana
Check Prometheus is receiving data:
- Go to http://localhost:9090
- Query:
up- should show1for all targets - Query:
claude_sessions_total- should return data
Check Pushgateway has metrics:
- Go to http://localhost:9091
- Look for metrics under the job name
Verify environment variables:
echo $CLAUDE_TRACKER_PUSHGATEWAY_URL # Should output: http://localhost:9091Check plugin logs (if CLAUDE_TRACKER_VERBOSE=1):
- Look for "Pushed metrics to Pushgateway" messages
Prometheus can't scrape metrics
Check if metrics server is running:
curl http://localhost:9464/metrics # Should return Prometheus-formatted metricsOn Linux, you may need to update
prometheus/prometheus.yml:# Change from: - targets: ['host.docker.internal:9464'] # To your host IP: - targets: ['172.17.0.1:9464']Then restart Prometheus:
docker compose restart prometheus
Services won't start
Port conflicts - Check if ports are in use:
lsof -i :9090 # Prometheus lsof -i :9091 # Pushgateway lsof -i :3000 # GrafanaDocker issues - Reset and try again:
docker compose down -v docker compose up -d
Metrics are stale or not updating
- Force a flush in OpenCode by exiting the session
- Check Pushgateway interval:
export CLAUDE_TRACKER_PUSHGATEWAY_INTERVAL=5000 # Push every 5 seconds
Stopping the Monitoring Stack
When you're done:
# Stop all services (keeps data)
docker compose down
# Stop and remove all data
docker compose down -vAdvanced: Running in Production
For production use, consider:
Persistent storage: The docker-compose already includes volumes for data persistence
Security: Change default Grafana password:
# In docker-compose.yml environment: - GF_SECURITY_ADMIN_PASSWORD=your-secure-passwordRemote Pushgateway: Point to your production Pushgateway:
export CLAUDE_TRACKER_PUSHGATEWAY_URL=https://pushgateway.yourcompany.comAlerting: Set up Grafana alerts for cost thresholds:
- Go to Dashboard → Edit panel → Alert tab
- Create alert when
claude_cost_usd_total > 100
License
MIT
