Desktop and LAN web dashboard for Claude Code hook events
Project description
Claudehub Monitor
A desktop and LAN web dashboard that shows what Claude Code is doing in real time — across every repo and machine on your network.
claudehub-monitor is the central collector: Claude Code hooks POST lifecycle
events to it over HTTP, and it surfaces them as an animated desktop card, system
sounds, a scrolling history, a usage quota toast, and a live web page you can
open from your phone.
Claude Code (any repo / any machine)
│ hook fires → claudehub-hooks → HTTP POST /event
▼
claudehub-monitor ──► desktop flash card + toasts + sounds + history (SQLite)
│
└─► web dashboard ◄── browser on the LAN (SSE live updates)
Quick start
- Start the monitor (once per machine):
pip install claudehub-monitor
claudehub # short alias
claudehub-monitor # full name (same command)
- Wire hooks into each repo you use with Claude Code:
pip install claudehub-hooks
claudehub-hooks install
claudehub-hooks install --url http://192.168.1.50:7070/event # remote monitor
- Open Claude Code in that repo — events flow to the monitor automatically.
Test hook connectivity:
python .claude/hooks/claude_hook.py --test
Install
Monitor (claudehub-monitor):
pip install claudehub-monitor
claudehub # short alias
claudehub-monitor # full name (same command)
Hooks (claudehub-hooks — separate package, stdlib only):
pip install claudehub-hooks
claudehub-hooks install
Components
| Package / path | Role |
|---|---|
claudehub-monitor (claudehub/monitor.py) |
Monitor: HTTP server, desktop UI, web dashboard, SQLite store. |
claudehub-hooks |
Pip installer that writes .claude/hooks/claude_hook.py + settings.json entries. |
claudehub/dashboard.html |
Web dashboard page (served at /). |
monitor_config.json |
Example monitor config (copy to ~/.claude/monitor_config.json). |
.claude/hooks/monitor_config.json |
Per-repo hook transport config (written by claudehub-hooks install). |
~/.claude/claude_events.db |
SQLite history + per-session status (auto-created). |
Hook events
claudehub-hooks install registers these Claude Code hooks:
| Event | When it fires | Monitor behavior |
|---|---|---|
SessionStart |
Session begins | Card shows “Session Started”; history entry |
UserPromptSubmit |
User sends a message | Thinking — ring animation, persistent toast |
PostToolUse |
Tool used (matcher: Edit|Write|NotebookEdit|MultiEdit|Read) |
Reading (Read) or Editing (others); brief flash → back to thinking |
Stop |
Turn completes | Done — green tick, ding, clears session |
StopFailure |
API / runtime error | Error — red card, pong sound |
Notification |
Claude needs input | Waiting — persistent ask toast |
PermissionRequest |
Allow/deny dialog shown | Waiting — permission toast + orange card |
PermissionGranted |
User approved a tool | Resumes Thinking; history shows “Allowed ✓” |
PermissionDenied |
User denied a tool | Resumes Thinking; history shows “Denied ✗” |
PreToolUse |
Tool about to run | Resolves pending permission → Thinking (implicit allow for sub-tools) |
Hook self-test (claude_hook.py --test) sends __test__ — shown on the card as a purple “Test” flash (not recorded in history).
Event payload (from hooks)
Hooks POST JSON to POST /event:
{
"event": "PostToolUse",
"datetime": "<ISO-8601 UTC>",
"session_id": "<str>",
"host": "<hostname>",
"cwd": "<working dir>",
"files": ["<path>"], // PostToolUse
"prompt": "<first 500 chars>", // UserPromptSubmit
"tool_name": "<tool>", // PostToolUse / Permission* / PreToolUse
"command": "<cmd>", // Permission* / PreToolUse
"notification_type": "<type>", // Notification
"error_type": "<type>", // StopFailure
"error_message": "<msg>" // StopFailure
}
Status model
Each surfaced status maps to colour, icon, and animation on the desktop:
| Status | Trigger (hook event) | Colour | Desktop animation |
|---|---|---|---|
| Thinking | UserPromptSubmit |
blue | rotating arc ring |
| Reading | PostToolUse (Read) |
teal | sweeping scan bar |
| Editing | PostToolUse (Edit/Write/…) |
blue | rippling bars |
| Waiting | PermissionRequest / Notification |
amber | persistent ask toast |
| Allowed | PermissionGranted / PreToolUse (after approve) |
green | ding; back to thinking |
| Denied | PermissionDenied |
red | thud; back to thinking |
| Done | Stop |
green | ✓ tick + ding |
| Error | StopFailure |
red | pong |
Read/Edit briefly flash, then the card returns to Thinking until the turn
ends (Stop) — mirroring how Claude actually works. The desktop card shows the
status name; the history table and web feed show the matching icon.
Usage toast
When Claude Code OAuth credentials exist (~/.claude/.credentials.json), a fixed
top-right toast shows subscription quota:
- 5-hour session and 7-day weekly utilization (%)
- Reset times for each window
- Refreshed every 5 minutes (one minimal Haiku probe call per refresh)
If credentials are missing, the toast is skipped.
Run it
claudehub
claudehub-monitor
python -m claudehub
The app starts hidden in the system tray by default (the HTTP server and web dashboard run regardless). Double-click the tray icon to open the window; "Minimize to Tray" or closing the window hides it again; the tray menu's Quit exits. Only one instance runs per machine.
Web dashboard (view on the go)
With the monitor running, open from any device on the LAN:
http://<monitor-ip>:7070/
It shows a live grid of active sessions, the last prompt, and a recent-activity feed — pushed over Server-Sent Events (auto-reconnecting), with a JSON snapshot for the initial load.
Open TCP 7070 on the monitor machine's firewall:
New-NetFirewallRule -DisplayName "Claude Monitor" -Direction Inbound `
-Protocol TCP -LocalPort 7070 -Action Allow
HTTP API
| Method / path | Purpose |
|---|---|
POST /event |
Ingest one hook event (from claudehub-hooks dispatcher). |
GET / |
The web dashboard. |
GET /api/status |
Active sessions snapshot + last prompt (JSON). |
GET /api/events |
Recent events feed (JSON). |
GET /events/stream |
Live event stream (SSE). |
GET /health |
{"status":"ok"}. |
Configuration
Monitor (claudehub-monitor)
Copy monitor_config.json to ~/.claude/monitor_config.json, or set
CLAUDE_MONITOR_CONFIG to point at a file:
{
"transport": { "http": { "enabled": true, "url": "http://127.0.0.1:7070/event", "timeout_s": 2.0 } },
"monitor": { "http_host": "0.0.0.0", "http_port": 7070, "history_max": 50, "start_hidden": true },
"logging": { "level": "INFO", "file": "", "max_bytes": 1048576, "backup_count": 5 },
"sounds": { "enabled": true }
}
Monitor env vars (override the file): CLAUDE_MONITOR_CONFIG, CLAUDE_MONITOR_PORT,
CLAUDE_MONITOR_HOST, CLAUDE_MONITOR_SOUNDS, CLAUDE_MONITOR_LOG_LEVEL,
CLAUDE_MONITOR_LOG_FILE.
Logs and the SQLite database default to ~/.claude/.
Hooks (claudehub-hooks)
Per-repo transport config lives at .claude/hooks/monitor_config.json (created
by claudehub-hooks install). Point hooks at a monitor on another machine:
{
"transport": {
"http": { "url": "http://192.168.1.50:7070/event" }
}
}
Hook env vars (override the file):
| Variable | Default | Meaning |
|---|---|---|
CLAUDE_HUB_URL |
http://127.0.0.1:7070/event |
Monitor endpoint |
CLAUDE_HUB_TIMEOUT |
2.0 |
HTTP timeout (seconds) |
CLAUDE_HUB_HTTP_ENABLED |
true |
Set to false to silence all hooks |
CLAUDE_HUB_CONFIG |
— | Path to a monitor_config.json override |
CLAUDE_HOOK_LOG_LEVEL |
INFO |
Dispatcher log level |
CLAUDE_HOOK_LOG_FILE |
~/.claude/claude_hook.log |
Dispatcher log path |
Multi-instance & reopen recovery
The monitor tracks status per session in SQLite, so:
- Several Claude instances (local or remote) can report at once — the card shows the latest, the history/web distinguish by host + session.
- If you close and reopen the monitor mid-turn, it restores the in-progress
state from
session_status; a 2-second watchdog idles a session that goes silent.
Requirements
- Python 3.11+ (monitor); Python 3.10+ (hooks)
claudehub-monitor: PySide6 and anthropic (installed automatically)claudehub-hooks: stdlib only- Windows for sounds (
winsound); silently disabled elsewhere.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file claudehub_monitor-0.1.9.tar.gz.
File metadata
- Download URL: claudehub_monitor-0.1.9.tar.gz
- Upload date:
- Size: 33.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
37a44a0e97e6b70e610239b595a47e5ad36af7321646a5ef30aabbdaefe99eee
|
|
| MD5 |
b58f6e8a03ab365b7210be248601eaf9
|
|
| BLAKE2b-256 |
1255e0b2fb0d7e160622563d06d1eb21071dd3df891866e0c9805d3d270dc592
|
File details
Details for the file claudehub_monitor-0.1.9-py3-none-any.whl.
File metadata
- Download URL: claudehub_monitor-0.1.9-py3-none-any.whl
- Upload date:
- Size: 34.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b4d331ef73bdb4002ec140981cfabf611e0af473989e157bf7a8133f755d76e4
|
|
| MD5 |
4deee5de2af205dfe278e71b0a96f74f
|
|
| BLAKE2b-256 |
52b550cadcc1cfce597c9c3ec631fdc087201f0c799b3541049ad9b592761e0d
|