Skip to main content

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

  1. Start the monitor (once per machine):
pip install claudehub-monitor
claudehub          # short alias
claudehub-monitor  # full name (same command)
  1. 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
  1. 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

claudehub_monitor-0.1.7.tar.gz (33.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

claudehub_monitor-0.1.7-py3-none-any.whl (34.8 kB view details)

Uploaded Python 3

File details

Details for the file claudehub_monitor-0.1.7.tar.gz.

File metadata

  • Download URL: claudehub_monitor-0.1.7.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

Hashes for claudehub_monitor-0.1.7.tar.gz
Algorithm Hash digest
SHA256 54a15f2fe33f01ebab5aff28f23658e39ae30df3e7c138a63c6530bd3c11c3df
MD5 85a8b38283d8677e4dff769958805ef9
BLAKE2b-256 e7a87c18fb3cbd362590e6a0a9e76d23f951606cb3720b877ccb44da45967235

See more details on using hashes here.

File details

Details for the file claudehub_monitor-0.1.7-py3-none-any.whl.

File metadata

File hashes

Hashes for claudehub_monitor-0.1.7-py3-none-any.whl
Algorithm Hash digest
SHA256 05fe665458438909f5818fcaa577e08cfc772023adf88379291f2ecd133ec536
MD5 17331ef7e683286fb093e868d3dfedf0
BLAKE2b-256 f6a9e5de07959d48b78601e9b1566b62828cdfca2d40f03e47966d4b53e2f0c1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page