Right-moment trigger router for personal behavior change. Built on the Fogg Behavior Model — behavior happens when Motivation, Ability, and a Trigger converge. Kairos is the trigger layer: it watches your intents, infers when M and A are both above threshold, and fires the right type of trigger at the opportune moment.
Most reminder systems are dumb cron jobs — they fire signals regardless of state, train themselves into noise, and get dismissed. Kairos routes by trigger type:
- Signal (high M + high A) — just a green light. "Kitchen counter."
- Spark (low M + high A) — reconnects you with why you cared.
- Facilitator (high M + low A) — pre-loads the first 5-minute step.
Named after kairos — the ancient Greek word for the opportune moment.
intents (what you want to do)
│
▼ tick (every 2 min)
rules engine (7 fire gates + MAP inference)
│
▼ if should_fire
LLM renderer (Claude Sonnet 4.6, per-trigger-type prompt)
│
▼
Slack DM with interactive buttons
│
▼ user taps Done / Snooze / Not now
outcome logged to fires table (the data flywheel)
Every fire and outcome is logged. The longer it runs, the better it gets at knowing when not to fire. Dismiss is signal, not failure.
git clone https://github.com/w00jay/Kairos.git
cd Kairos
# Configure
cp .env.example .env # fill in credentials
cp config/owner.example.yaml config/owner.yaml # edit rhythm, timezone, DND windows
# Apply schema (Supabase SQL Editor or psql)
psql "$KAIROS_SUPABASE_URL" -f migrations/0001_kairos_schema.sql
# Run
export $(grep -v '^#' .env | grep -v '^$' | xargs)
go run ./cmd/kairos/Or with Docker:
docker compose up -dexport $(grep -v '^#' .env | grep -v '^$' | xargs)
kairosctl create \
--title "Practice ukulele" \
--why "so I can play with my kid without looking at my phone" \
--minutes 10 --cost low --constraints "at_home"The --why field is what makes Kairos different from a reminder app. When
the spark renderer fires, it echoes your words back — not a generic
motivational message.
kairosctl create --title "..." --why "..." [--minutes N] [--cost low|med|high] [--constraints "a,b"]
kairosctl intents [active|snoozed|done|archived]
kairosctl inspect <intent-id>
kairosctl fires <intent-id> [limit]
kairosctl done <intent-id>
kairosctl snooze <intent-id> <1h|4h|tomorrow|RFC3339>
kairosctl archive <intent-id>Kairos exposes 5 tools as an MCP server so any Claude session can manage intents:
| Tool | Purpose |
|---|---|
kairos_promote_thought |
Create an intent (optionally from a thought) |
kairos_list_intents |
List intents by status |
kairos_snooze |
Snooze an intent until a time |
kairos_complete |
Mark an intent done |
kairos_force_fire |
Bypass rules and fire immediately (testing) |
Configure your MCP client to connect to the server's HTTP endpoint.
See .env.example for the full list. The service degrades
gracefully: without ANTHROPIC_API_KEY it runs in dry-run mode, without
Slack tokens it logs fires to DB only.
Controls when and how often Kairos fires:
timezone— your local timezonedaily_fire_budget— max Slack DMs per daydnd_windows— no-fire zones (e.g. 22:00–07:30)deep_work_windows— blocks Kairos doesn't know from calendarbrain_cost_windows— time-of-day rules per brain cost levelcooldown_minutes— minimum gap between fires for the same intent
See config/owner.example.yaml for the full schema.
Seven fire gates (all must pass):
- Status is
active next_eligible_athas passed- Not in a DND window
- Brain cost compatible with time of day
- Not within cooldown of last fire
- Daily fire budget not exhausted
- Calendar shows a free gap (stubbed as always-free for now)
Trigger type selection infers Motivation and Ability from intent age,
dismissal history, ability_minutes, and brain_cost. These thresholds
are deliberately crude — tune from the fires table after a week.
Two tables in Supabase Postgres under the kairos schema:
intents— what you want to do (title, why, ability_minutes, brain_cost, constraints, status)fires— every trigger fired (trigger_type, rules_snapshot, rendered_message, outcome). Append-only — has a delete trigger preventing row removal.
- Language: Go
- DB: Supabase Postgres
- LLM: Claude Sonnet 4.6 via Anthropic API
- Slack: Socket Mode (no public URL needed)
- Calendar: Google Calendar free/busy (interface ready, stubbed for now)
cmd/kairos/ main service (ticker + Slack + MCP in one process)
cmd/kairosctl/ operator CLI
internal/
config/ env + YAML config loader
store/ persistence interface + pgx implementation
rules/ fire/no-fire gates + trigger type selection
render/ LLM renderer (three trigger-type prompts)
slack/ Socket Mode bridge + interactive buttons
ticker/ in-process evaluation loop + dispatchers
anthropic/ minimal Anthropic API client
calendar/ calendar free/busy reader (stubbed)
mcp/ MCP tool server (5 tools)
migrations/ Supabase schema
prompts/ per-trigger-type LLM prompts
config/ owner rhythm config
MIT — see LICENSE.