The EventFeed component was filtering events twice: 1. First in useEvents hook (backend query with event_types filter) 2. Then again in EventFeed component (client-side filter) This caused filter issues where switching between filters would show incorrect events (e.g., switching from SESSIONS to ALL would only show session events). Fixed by removing the duplicate client-side filter, as useEvents already provides correctly filtered events from the backend. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Claude Code Monitor
Real-time monitoring dashboard for Claude Code activity. Track tool usage, agent spawns, sessions, and events with a beautiful dark-themed web interface.
Features
- Real-time Event Tracking: Monitor Claude Code events as they happen via WebSocket
- Statistics Dashboard: Track total events, tools used, agents spawned, and sessions
- Event Filtering: Filter events by category (ALL, TOOLS, AGENTS, PROMPTS, SESSIONS)
- Dark Theme UI: Beautiful dark-themed interface optimized for developers
- Docker Deployment: Easy deployment with Docker Compose
- Non-intrusive Monitoring: Lightweight hooks that don't slow down Claude Code
Architecture
Claude Code → Hook Scripts → FastAPI Backend → WebSocket → React Frontend
↓
SQLite DB
Prerequisites
- Docker & Docker Compose (recommended)
- jq (for hook scripts):
brew install jq(macOS) orapt-get install jq(Linux) - Claude Code installed and configured
Quick Start
1. Clone or Download
cd /path/to/claude-monitor
2. Install Hooks
The hook scripts capture Claude Code events and send them to the backend.
./install_hooks.sh
This will:
- Copy hook scripts to
~/.claude/hooks/ - Display the configuration you need to add to
~/.claude/settings.json
3. Configure Claude Code
Add the following to your ~/.claude/settings.json:
{
"hooks": {
"PreToolUse": [{
"matcher": "*",
"hooks": [{
"type": "command",
"command": "/Users/YOUR_USERNAME/.claude/hooks/pre_tool_use.sh"
}]
}],
"PostToolUse": [{
"matcher": "*",
"hooks": [{
"type": "command",
"command": "/Users/YOUR_USERNAME/.claude/hooks/post_tool_use.sh"
}]
}],
"SessionStart": [{
"hooks": [{
"type": "command",
"command": "/Users/YOUR_USERNAME/.claude/hooks/session_start.sh"
}]
}],
"SessionEnd": [{
"hooks": [{
"type": "command",
"command": "/Users/YOUR_USERNAME/.claude/hooks/session_end.sh"
}]
}],
"SubagentStop": [{
"hooks": [{
"type": "command",
"command": "/Users/YOUR_USERNAME/.claude/hooks/subagent_stop.sh"
}]
}],
"UserPromptSubmit": [{
"hooks": [{
"type": "command",
"command": "/Users/YOUR_USERNAME/.claude/hooks/user_prompt.sh"
}]
}]
}
}
Important: Replace /Users/YOUR_USERNAME with your actual home directory path.
4. Start the Application
docker-compose up --build
This will:
- Build and start the FastAPI backend (port 8000)
- Build and start the React frontend (port 3000)
- Create a persistent SQLite database in
./data/
5. Open the Dashboard
Navigate to http://localhost:3000
You should see:
- Connection status indicator (green = connected)
- Statistics cards showing 0 events initially
- Empty event feed
6. Test It
Open a new terminal and use Claude Code:
claude
Start a conversation or run commands. You'll see events appear in the dashboard in real-time!
Development Setup
Backend (FastAPI)
cd backend
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Run development server
python -m app.main
Backend runs on http://localhost:8000
API documentation: http://localhost:8000/docs
Frontend (React + Vite)
cd frontend
# Install dependencies
npm install
# Run development server
npm run dev
Frontend runs on http://localhost:5173
API Endpoints
Events
POST /api/events- Create new event (called by hooks)GET /api/events- List events with filtering- Query params:
skip,limit,event_type,session_id,tool_name
- Query params:
DELETE /api/events/reset- Reset all statistics
Statistics
GET /api/statistics- Get current statisticsGET /api/statistics/tools- Get tool usage breakdownGET /api/statistics/sessions- Get session list
WebSocket
WS /ws- WebSocket connection for real-time updates
Health
GET /health- Health check
Event Types
The monitor captures these Claude Code events:
| Event Type | Description | Filter |
|---|---|---|
PreToolUse |
Before tool execution | TOOLS |
PostToolUse |
After tool execution | TOOLS |
SessionStart |
Session started | SESSIONS |
SessionEnd |
Session ended | SESSIONS |
SubagentStop |
Agent completed | AGENTS |
UserPromptSubmit |
User submitted prompt | PROMPTS |
Configuration
Environment Variables
Backend (docker-compose.yml):
DATABASE_URL- SQLite database pathCORS_ORIGINS- Allowed CORS origins
Frontend (frontend/.env):
VITE_API_URL- Backend API URL (default: http://localhost:8000)VITE_WS_URL- WebSocket URL (default: ws://localhost:8000/ws)
Troubleshooting
Hooks Not Working
Problem: Events not appearing in dashboard
Solutions:
-
Check hook scripts are executable:
chmod +x ~/.claude/hooks/*.sh -
Verify
jqis installed:which jq -
Test hook manually:
echo '{"session_id":"test","tool_name":"Bash"}' | ~/.claude/hooks/post_tool_use.sh -
Check backend logs:
docker-compose logs backend
Backend Connection Issues
Problem: "DISCONNECTED" status in dashboard
Solutions:
-
Verify backend is running:
curl http://localhost:8000/health -
Check Docker containers:
docker-compose ps -
Restart services:
docker-compose restart
Port Conflicts
Problem: Ports 8000 or 3000 already in use
Solutions:
-
Find process using port:
lsof -i :8000 lsof -i :3000 -
Kill the process or change ports in
docker-compose.yml:ports: - "8001:8000" # Backend - "3001:80" # Frontend
Database Issues
Problem: Database errors or corruption
Solutions:
-
Stop containers:
docker-compose down -
Remove database:
rm data/claude_monitor.db* -
Restart:
docker-compose up -d
Project Structure
claude-monitor/
├── backend/
│ ├── app/
│ │ ├── main.py # FastAPI application
│ │ ├── database.py # SQLAlchemy models
│ │ ├── schemas.py # Pydantic schemas
│ │ ├── crud.py # Database operations
│ │ ├── websocket.py # WebSocket manager
│ │ └── api/
│ │ ├── events.py # Event endpoints
│ │ ├── statistics.py # Statistics endpoints
│ │ └── websocket_endpoint.py
│ ├── requirements.txt
│ └── Dockerfile
├── frontend/
│ ├── src/
│ │ ├── App.tsx # Main component
│ │ ├── components/ # React components
│ │ ├── hooks/ # Custom hooks
│ │ ├── api/ # API clients
│ │ ├── types/ # TypeScript types
│ │ └── styles/ # CSS styles
│ ├── package.json
│ ├── vite.config.ts
│ └── Dockerfile
├── .claude/
│ └── hooks/ # Hook scripts
├── data/ # SQLite database (created on first run)
├── docker-compose.yml
├── install_hooks.sh
└── README.md
Performance
The monitor is designed to be lightweight and non-intrusive:
- Hook execution: <10ms (runs in background)
- Backend processing: <50ms per event
- WebSocket latency: <100ms
- Database size: ~1KB per event
For high-volume usage, events auto-delete after 10,000 entries (configurable).
Security
- Hooks run with your user permissions
- Backend only accepts localhost connections by default
- No authentication required (localhost only)
- For production: Add authentication and restrict CORS origins
Contributing
Contributions welcome! Areas for improvement:
- Agents Graph visualization
- Event search functionality
- Export events to CSV/JSON
- Session timeline view
- Advanced filtering
- Performance metrics
- Authentication system
License
MIT License - feel free to use and modify
Credits
Built with:
- FastAPI - Backend framework
- React - Frontend framework
- Vite - Build tool
- SQLAlchemy - Database ORM
Inspired by Claude Code's powerful hook system.
Support
For issues or questions:
- Check the troubleshooting section above
- Review Claude Code documentation: https://code.claude.com/docs
- Open an issue in this repository
Changelog
v1.0.0 (2025-12-15)
- Initial release
- Real-time event monitoring
- Statistics dashboard
- Event filtering
- Docker deployment
- Dark theme UI