anomaly-detection
This skill runs daily metric queries against your Postgres database, detects statistical anomalies, and delivers a structured report to your alert channel.
When to invoke
- Daily on a cron schedule (recommended: 7am before business hours)
- When the user asks "any anomalies today?" or "how are our metrics?"
- After a deploy, incident, or data pipeline change
Steps to execute
Load metric configuration from memory
- Read MEMORY.md for: metric names, SQL queries, alert thresholds (if custom), alert channel (Slack/Telegram)
- If no metrics are configured, ask the user to provide their key metric queries
Run current-period queries
- Execute each metric SQL query via the Postgres MCP server
- Record: metric name, current value, query timestamp
Run baseline queries
- For each metric, run the same query for each of the past 7 days
- Build a 7-day array:
[d-7, d-6, d-5, d-4, d-3, d-2, d-1]
Compute statistics using the detect.py helper
- Pass results to
scripts/detect.py via stdin as JSON:{"metric": "daily_revenue", "current": 24150, "baseline": [24800, 23900, 25100, 24200, 23800, 24900, 24100]}
- The script returns:
{"metric": "daily_revenue", "mean": 24400, "std": 422, "z_score": -0.59, "is_anomaly": false}
- An anomaly is flagged when
|z_score| > 2.0
Build the report
- Summary line: "All metrics normal" or "X anomalies detected"
- For each metric: current value, 7-day avg, % change, anomaly flag
- For anomalies: include possible causes from the user's mental model (stored in MEMORY.md)
Deliver the report
- Send to the configured alert channel (Slack or Telegram)
- For anomalies: send an immediate separate alert with higher urgency
Update memory
- Record today's values in MEMORY.md under the metric history
- Note any anomalies and whether they were followed by a user explanation
Example output
Daily Metrics — 2026-03-31 07:00
All clear — all metrics within normal range.
DAU: 8,432 (7d avg: 8,168 ↑ 3.2%) ✅
Revenue: $24,150 (7d avg: $24,420 ↓ 1.1%) ✅
New signups: 312 (7d avg: 309 ↑ 1.0%) ✅
Activation rate: 67.3% (7d avg: 68.1% ↓ 0.8%) ✅
For anomalies:
ANOMALY ALERT — 2026-03-31 07:00
Revenue: $15,200 (7d avg: $24,420 — z-score: −2.8) ⚠️
This is 38% below average. Possible causes:
- Payment processor issue
- Regional outage
- Recent pricing change
Check: SELECT * FROM payment_failures WHERE created_at >= CURRENT_DATE
Error handling
- If Postgres MCP is unavailable: report the connection error and skip the run
- If a query fails: skip that metric, continue with others, note the failure in the report
- If the alert channel is unavailable: save report to
/sandbox/anomaly-report-[date].json
Notes
- Use a read-only database role for the connection string (see guide for SQL setup)
- The
scripts/detect.py helper handles all statistical computation — no external libraries needed in the LLM
- After 30+ daily runs, Hermes will auto-create an optimized version of this skill calibrated to your metrics
1---2name: anomaly-detection3description: Daily database anomaly detection — runs metric queries against Postgres, flags deviations > 2σ from the 7-day baseline, and sends a summary to Slack or Telegram4license: MIT5---67# anomaly-detection89This skill runs daily metric queries against your Postgres database, detects statistical anomalies, and delivers a structured report to your alert channel.1011## When to invoke1213- Daily on a cron schedule (recommended: 7am before business hours)14- When the user asks "any anomalies today?" or "how are our metrics?"15- After a deploy, incident, or data pipeline change1617## Steps to execute18191. **Load metric configuration from memory**20 - Read MEMORY.md for: metric names, SQL queries, alert thresholds (if custom), alert channel (Slack/Telegram)21 - If no metrics are configured, ask the user to provide their key metric queries22232. **Run current-period queries**24 - Execute each metric SQL query via the Postgres MCP server25 - Record: metric name, current value, query timestamp26273. **Run baseline queries**28 - For each metric, run the same query for each of the past 7 days29 - Build a 7-day array: `[d-7, d-6, d-5, d-4, d-3, d-2, d-1]`30314. **Compute statistics using the detect.py helper**32 - Pass results to `scripts/detect.py` via stdin as JSON:33 ```json34 {"metric": "daily_revenue", "current": 24150, "baseline": [24800, 23900, 25100, 24200, 23800, 24900, 24100]}35 ```36 - The script returns:37 ```json38 {"metric": "daily_revenue", "mean": 24400, "std": 422, "z_score": -0.59, "is_anomaly": false}39 ```40 - An anomaly is flagged when `|z_score| > 2.0`41425. **Build the report**43 - Summary line: "All metrics normal" or "X anomalies detected"44 - For each metric: current value, 7-day avg, % change, anomaly flag45 - For anomalies: include possible causes from the user's mental model (stored in MEMORY.md)46476. **Deliver the report**48 - Send to the configured alert channel (Slack or Telegram)49 - For anomalies: send an immediate separate alert with higher urgency50517. **Update memory**52 - Record today's values in MEMORY.md under the metric history53 - Note any anomalies and whether they were followed by a user explanation5455## Example output5657```58Daily Metrics — 2026-03-31 07:005960All clear — all metrics within normal range.6162DAU: 8,432 (7d avg: 8,168 ↑ 3.2%) ✅63Revenue: $24,150 (7d avg: $24,420 ↓ 1.1%) ✅64New signups: 312 (7d avg: 309 ↑ 1.0%) ✅65Activation rate: 67.3% (7d avg: 68.1% ↓ 0.8%) ✅66```6768For anomalies:69```70ANOMALY ALERT — 2026-03-31 07:007172Revenue: $15,200 (7d avg: $24,420 — z-score: −2.8) ⚠️73This is 38% below average. Possible causes:74- Payment processor issue75- Regional outage76- Recent pricing change77Check: SELECT * FROM payment_failures WHERE created_at >= CURRENT_DATE78```7980## Error handling8182- If Postgres MCP is unavailable: report the connection error and skip the run83- If a query fails: skip that metric, continue with others, note the failure in the report84- If the alert channel is unavailable: save report to `/sandbox/anomaly-report-[date].json`8586## Notes8788- Use a read-only database role for the connection string (see guide for SQL setup)89- The `scripts/detect.py` helper handles all statistical computation — no external libraries needed in the LLM90- After 30+ daily runs, Hermes will auto-create an optimized version of this skill calibrated to your metrics