ccmon
A TUI (Terminal User Interface) application for monitoring Claude Code API usage through OpenTelemetry (OTLP) telemetry data. ccmon displays real-time statistics for token usage, costs, and request counts with separate tracking for base (Haiku) and premium (Sonnet/Opus) models.
Inspired by ccusage, but uses OTLP to receive Claude Code usage data.
Features
- Real-time Monitoring: Live TUI dashboard showing Claude Code API usage statistics
- Token Tracking: Separate monitoring for base (Haiku) and premium (Sonnet/Opus) models
- Cost Analysis: Track API costs and usage patterns
- Block Progress: Monitor Claude token limit progress with 5-hour block tracking and beautiful gradient progress bars
- Time Filtering: Filter data by various time periods (last hour, day, week, etc.)
- Configurable Refresh: Customizable monitor refresh intervals (1s to 5m)
- OTLP Integration: Receives telemetry data via OpenTelemetry protocol
- Dual Operating Modes: Monitor mode (TUI) and server mode (headless collector)
Installation
Homebrew (macOS and Linux)
# Add the tap from the main repository
brew tap elct9620/ccmon https://github.com/elct9620/ccmon
# Install stable release from pre-built binaries
brew install ccmon
# Or install latest development version from source (requires Go and protobuf)
brew install --head ccmon
Pre-built Binaries
Download the latest release for your platform from the releases page.
Docker
# Pull the latest image
docker pull ghcr.io/elct9620/ccmon:latest
# Check version
docker run --rm ghcr.io/elct9620/ccmon:latest --version
# Run in server mode (recommended for security)
# Note: Binding to 127.0.0.1:4317 restricts access to localhost only
docker run -d \
--name ccmon \
-p 127.0.0.1:4317:4317 \
-v ccmon-data:/data \
ghcr.io/elct9620/ccmon:latest
Build from Source
git clone https://github.com/elct9620/ccmon.git
cd ccmon
make build
Usage
Operating Modes
ccmon has two distinct operating modes that work together:
1. Server Mode (Required First)
Headless OTLP collector + gRPC query service that receives telemetry data from Claude Code:
./ccmon -s
# or
./ccmon --server
Important: You must run the server mode first to collect telemetry data before using the monitor.
2. Monitor Mode
TUI dashboard that connects to the server and displays usage statistics:
./ccmon # Connect to default server (localhost:4317)
./ccmon --monitor-server host:port # Connect to specific server
3. Block Tracking Mode
Monitor with Claude token limit progress bars for 5-hour blocks:
./ccmon -b 5am # Track usage from 5am start blocks
./ccmon --block 11pm # Track usage from 11pm start blocks
Check the installed version of ccmon:
./ccmon --version
# or
./ccmon -v
This will display:
- Version number (e.g., v0.4.0 for releases or "dev" for development builds)
- Git commit hash
- Build date
Quick Start
- Start the server (receives telemetry data):
# Using Docker (recommended)
docker run -d \
--name ccmon \
-p 127.0.0.1:4317:4317 \
-v ccmon-data:/data \
ghcr.io/elct9620/ccmon:latest
# Or using binary
./ccmon --server
- Configure Claude Code to send telemetry:
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
# ... other OTEL variables (see configuration section)
-
Use Claude Code to generate some API requests
-
Start the monitor to view data:
# Using Docker
docker run --rm -it --network host ghcr.io/elct9620/ccmon:latest --monitor-server localhost:4317
# Or using binary
./ccmon
Docker Usage
Server Mode (Step 1 - Required)
# Run server with persistent data (bind to localhost only for security)
docker run -d \
--name ccmon \
-p 127.0.0.1:4317:4317 \
-v ccmon-data:/data \
-e TZ=UTC \
ghcr.io/elct9620/ccmon:latest
# Check server logs
docker logs ccmon
Monitor Mode (Step 4 - After server is running)
# Connect to existing server on same host
docker run --rm -it \
--network host \
ghcr.io/elct9620/ccmon:latest
# Connect to server on different host
docker run --rm -it \
ghcr.io/elct9620/ccmon:latest \
--monitor-server your-server:4317
Docker Compose
Create a docker-compose.yml file:
version: '3.8'
services:
ccmon:
image: ghcr.io/elct9620/ccmon:latest
container_name: ccmon
ports:
- "127.0.0.1:4317:4317" # Bind to localhost only for security
volumes:
- ccmon-data:/data
- ./config.toml:/app/config.toml:ro # Optional: custom config
environment:
- TZ=UTC
restart: unless-stopped
healthcheck:
test: ["CMD", "./ccmon", "--help"]
interval: 30s
timeout: 10s
retries: 3
volumes:
ccmon-data:
Run with Docker Compose:
# Start the server
docker-compose up -d
# View logs
docker-compose logs -f
# Connect with monitor mode
docker run --rm -it \
--network host \
ghcr.io/elct9620/ccmon:latest \
--monitor-server localhost:4317
# Stop the server
docker-compose down
Configuration
ccmon supports configuration files in TOML, YAML, or JSON format. The application searches for configuration files in:
- Current directory:
./config.{toml,yaml,json}
- User config directory:
~/.ccmon/config.{toml,yaml,json}
Example Configuration
[database]
# Path to the BoltDB database file
path = "~/.ccmon/ccmon.db"
[server]
# gRPC server address for OTLP receiver + Query service
address = "127.0.0.1:4317"
[monitor]
# gRPC server address for query service
server = "127.0.0.1:4317"
# Timezone for time filtering and display
timezone = "UTC"
# Monitor refresh interval (how often the TUI updates)
refresh_interval = "5s" # Options: "1s", "5s", "10s", "30s", "1m", etc.
[claude]
# Claude subscription plan for automatic token limit detection
plan = "pro" # Options: "unset", "pro", "max", "max20"
# Custom token limit override (optional)
max_tokens = 7000
See config.toml.example for a complete configuration example.
Monitor Customization
The monitor mode can be customized to fit different usage patterns and system capabilities:
Refresh Interval
Control how frequently the TUI updates its data display:
[monitor]
refresh_interval = "5s" # Default: matches Claude Code telemetry frequency
# refresh_interval = "1s" # Fast refresh for active development
# refresh_interval = "10s" # Balanced refresh for normal usage
# refresh_interval = "30s" # Slower refresh to save resources
# refresh_interval = "1m" # Minimal overhead for background monitoring
Guidelines:
- 1-2 seconds: Best for active development and real-time monitoring
- 5 seconds: Default rate, aligns with Claude Code's telemetry frequency
- 10-30 seconds: Good balance between responsiveness and resource usage
- 1-5 minutes: Minimal overhead for background monitoring on slower systems
Note: Claude Code sends telemetry approximately every 5 seconds, so refresh intervals shorter than 5s may not show new data more frequently.
Claude Code Integration
To send telemetry data to ccmon, configure Claude Code with these environment variables:
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=otlp
export OTEL_LOGS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
If running ccmon server on a different host:
export OTEL_EXPORTER_OTLP_ENDPOINT=http://your-server:4317
Development
Prerequisites
- Go 1.24.3+
- Make
- Protocol Buffers compiler (protoc) v30.2+
Build Commands
# Generate protobuf code
make generate
# Build the application
make build
# Format code
gofmt -w .
# Clean build artifacts
make clean
Development with Docker
# Build local image
docker build -t ccmon:dev .
# Run development server (bind to localhost for security)
docker run --rm -p 127.0.0.1:4317:4317 ccmon:dev
Architecture
ccmon follows Clean Architecture and Domain-Driven Design (DDD) principles:
- Handler Layer: Separate TUI and gRPC handlers
- Usecase Layer: Business logic with CQRS commands and queries
- Repository Layer: Data access with entity conversion
- Entity Layer: Domain entities with encapsulated business logic
- gRPC Communication: Monitor mode communicates via gRPC queries
For detailed architecture documentation, see CLAUDE.md.
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature)
- Commit your changes using conventional commits
- Push to the branch (
git push origin feature/amazing-feature)
- Open a Pull Request
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Acknowledgments