A web dashboard for watching Claude Code hook events in real time.
services:
app:
image: ghcr.io/felipeelias/hook-lab:latest
ports:
- "4000:4000"
volumes:
- hook_lab_data:/app/data
environment:
SECRET_KEY_BASE: ${SECRET_KEY_BASE}
DATABASE_PATH: /app/data/hook_lab.db
PHX_HOST: localhost
volumes:
hook_lab_data:export SECRET_KEY_BASE=$(openssl rand -base64 64)
docker compose up -dOpen http://localhost:4000.
This repo includes a docs/claude-settings.example.json that sends every hook event to HookLab over HTTP. Each hook has a 1-second timeout. If HookLab isn't running, Claude Code moves on.
Copy the hooks block from that file into ~/.claude/settings.json or your project's .claude/settings.json. Here's a stripped-down version with just two events if you want to start small:
{
"hooks": {
"PreToolUse": [
{
"hooks": [
{
"type": "http",
"url": "http://localhost:4000/api/hooks",
"timeout": 1
}
]
}
],
"PostToolUse": [
{
"hooks": [
{
"type": "http",
"url": "http://localhost:4000/api/hooks",
"timeout": 1
}
]
}
]
}
}Hook settings are read at session start, so open a new Claude Code session after changing them.
If HookLab is running on a different host or port, replace http://localhost:4000/api/hooks in each hook entry with your URL. HTTP hooks don't support environment variable interpolation in the url field, so the URL must be edited directly in the settings file.
mix setup
mix phx.server
# http://localhost:4000mix cidocker compose build
SECRET_KEY_BASE=$(openssl rand -base64 64) docker compose up
