A Slack bot powered by Claude that provides DM chat, daily channel summaries, PagerDuty alert investigation, Airflow delay monitoring, and @mention-triggered persistent CLI sessions in any channel.
- Node.js 22+
- Claude CLI installed and authenticated (
claudeon PATH) - A Slack app with Socket Mode enabled, plus bot and app-level tokens
- (Optional) PagerDuty API token for alert acknowledgement
# Install dependencies
npm install
# Copy and fill in environment variables
cp .env.example .env
# Edit .env with your Slack tokens, owner user ID, channels, etc.Bot Token Scopes: chat:write, channels:history, channels:read, im:history, im:read, im:write, users:read
App-Level Token: Socket Mode must be enabled. Generate an app-level token with connections:write scope.
# Start as background daemon (logs to data/enzo.log)
npm start # or: ./enzo start
# Stop the daemon
npm stop # or: ./enzo stop
# Restart
npm run restart # or: ./enzo restart
# Check status + health endpoint
npm run status # or: ./enzo status
# Tail live logs
npm run logs # or: ./enzo logsnpm run dev./start.shRuns the bot in a loop, restarting automatically on exit (useful for supervised deployments).
DM the bot for a one-shot Claude CLI response. Only the configured OWNER_USER_ID gets responses. No session tracking — each message is independent.
Scheduled channel summaries delivered as a DM. Uses Claude Agent SDK with Slack MCP tools to read channels and produce a summary.
- Schedule:
DAILY_SUMMARY_TIME(default07:00) - Channels:
DAILY_SUMMARY_CHANNELS(comma-separated) - Manual trigger:
POST http://localhost:3000/daily-summary
Watches configured channels for PagerDuty messages. When detected:
- Auto-acknowledges the PD incident via API
- Spawns a Claude CLI process to investigate using a configurable skill (default:
one:pay-ops-production) - Owner can reply in the thread for follow-up investigation
- Auto-cleans up after feedback timeout
Configure: MONITOR_CHANNELS, ALERT_SKILL, ALERT_MODEL, PAGERDUTY_API_TOKEN
Watches channels for Airflow task delay alerts. Counts occurrences within a time window and triggers investigation when threshold is reached.
- Matches task name patterns:
DELAY_ALERT_TASK_PATTERNS - Threshold:
DELAY_ALERT_THRESHOLD(default: 3 within 1 hour) - Skill:
DELAY_ALERT_SKILL(default:one:pay-ops-tax-production)
Configure: MONITOR_DELAY_CHANNELS, DELAY_ALERT_TASK_PATTERNS, DELAY_ALERT_THRESHOLD
@EnzoBot in any channel starts a persistent Claude CLI session in that thread. Thread replies with @mention continue the session. Thread context from other users is automatically fetched and included.
Thread commands (via @mention):
@EnzoBot !compact— Compact the CLI session context when it gets large@EnzoBot !exit— End the session
Configure: DISCUSS_MODEL
Use Gemini for ground-truth checking with live web data. Responses can be carried over as context when switching back to Claude.
Commands (via @mention):
@EnzoBot use gemini <query>— Query Gemini (default:gemini-2.5-flash)@EnzoBot use gemini pro <query>— Usegemini-3.1-pro@EnzoBot use gemini 2.5 pro <query>— Usegemini-2.5-pro@EnzoBot use gemini 3 flash <query>— Usegemini-3-flash@EnzoBot use claude code <instruction>— Switch back to Claude CLI with Gemini responses as context
Configure: GEMINI_API_KEY
| Endpoint | Method | Description |
|---|---|---|
/ |
GET | Status page (HTML) |
/health |
GET | Health check (JSON): uptime, Slack connection, active sessions |
/daily-summary |
POST | Manually trigger daily summary |
All configuration is via environment variables (.env file). See .env.example for the full reference with descriptions.
| Variable | Required | Default | Description |
|---|---|---|---|
SLACK_BOT_TOKEN |
Yes | — | xoxb-... bot token |
SLACK_APP_TOKEN |
Yes | — | xapp-... app-level token |
SLACK_SIGNING_SECRET |
Yes | — | Slack signing secret |
OWNER_USER_ID |
Yes | — | Slack user ID of the bot owner |
DATABASE_PATH |
No | ./data/bot.db |
SQLite database path |
PORT |
No | 3000 |
HTTP server port |
AGENT_MODEL |
No | sonnet |
Claude model for daily summaries |
DAILY_RESTART_HOUR |
No | 23 |
Hour (0-23) to auto-restart |
DAILY_SUMMARY_CHANNELS |
No | — | Comma-separated channel names |
DAILY_SUMMARY_TIME |
No | 07:00 |
Schedule time (HH:MM, local) |
DAILY_SUMMARY_MODEL |
No | sonnet |
Model for summaries |
MONITOR_CHANNELS |
No | — | PagerDuty alert channels (prefix ! to disable) |
ALERT_SKILL |
No | one:pay-ops-production |
Skill invoked for PD alerts |
ALERT_MODEL |
No | claude-opus-4-6 |
Model for alert investigation |
PAGERDUTY_API_TOKEN |
No | — | PagerDuty API token |
PAGERDUTY_FROM_EMAIL |
No | — | PagerDuty "From" email |
MONITOR_DELAY_CHANNELS |
No | — | Airflow delay channels (prefix ! to disable) |
DELAY_ALERT_TASK_PATTERNS |
No | — | Task name patterns (CSV) |
DELAY_ALERT_THRESHOLD |
No | 3 |
Alert count before triggering |
DELAY_ALERT_WINDOW_MS |
No | 3600000 |
Time window (ms) |
DELAY_ALERT_SKILL |
No | one:pay-ops-tax-production |
Skill for delay alerts |
DISCUSS_MODEL |
No | claude-sonnet-4-5-20250929 |
Model for DM and @mention CLI sessions |
PAYMENTS_REPO_PATH |
No | ~/go/src/github.com/payments |
Working directory for CLI processes |
REQUIRED_MCP_SERVERS |
No | chrome-devtools,athena |
MCP servers to force-enable |
GEMINI_API_KEY |
No | — | Gemini API key for Google Search grounding |
src/
index.ts # Entry point: Slack app init, scheduling, shutdown
config.ts # Environment variable parsing
server.ts # HTTP server (health, daily summary trigger)
handlers/
message.ts # DM one-shot CLI + channel @mention discuss sessions
alert-monitor.ts # PagerDuty message detection + workflow trigger
delay-alert-monitor.ts # Airflow task alert counting + threshold trigger
services/
agent.ts # Claude Agent SDK wrapper for DM chat
daily-summary.ts # Daily summary via Agent SDK + Slack MCP
claude-cli.ts # Claude CLI child process spawner
alert-workflow.ts # PagerDuty alert investigation lifecycle
delay-alert-workflow.ts # Airflow delay investigation lifecycle
discuss-workflow.ts # Discuss session lifecycle (start/reply/compact/exit)
database.ts # SQLite (sessions + messages)
session.ts # In-memory processing locks
pagerduty.ts # PagerDuty incident acknowledgement API
mcp-config.ts # MCP server override detection
gemini.ts # Gemini API client with Google Search grounding
- SQLite database:
./data/bot.db(daily summary data) - Logs:
./data/enzo.log(when running via./enzo start) - PID file:
.enzo.pid(managed by./enzo)