KeyzHub
19Keys Β· community archive

agent-proactive-email

Make your agent email you first: daily digests and alerts via trigger, agent compose, and a safe stdlib sender.

β—† 2 commits history main
UNLOCK THE CODE

Read the overview free. Drop your email once to unlock the clone command and source across the whole archive.

One email unlocks every project here. No spam.

main
β–Έ examples/
Β· .gitignore
Β· README.md
Β· SETUP.md
README

Make your AI agent email you β€” proactively

An agent that only answers when you ask is an assistant. An agent that emails you first β€” the morning digest, the overnight-build report, the "something broke" alert β€” is an operator. This guide wires that up with parts you already have if you followed /ai-agents-setup.

The whole trick is one pipeline:

trigger (schedule or event)  β†’  agent writes the email  β†’  a send script delivers it

Nothing exotic. A scheduler fires, your agent composes, a 40-line Python script sends. Everything below is copy-paste.


Step 1 β€” The send script (works with any provider)

examples/send_email.py in this repo is a complete stdlib-only sender β€” no pip installs. It reads everything from environment variables:

export AGENT_SMTP_HOST=smtp.gmail.com        # or 127.0.0.1 for Proton Mail Bridge
export AGENT_SMTP_PORT=587
export AGENT_SMTP_USER=you@example.com       # keyzhub-allow placeholder
export AGENT_SMTP_PASS=your_app_password_here   # keyzhub-allow placeholder
export AGENT_EMAIL_TO=you@example.com        # keyzhub-allow placeholder

Test it:

echo "The pipeline is alive." | python3 examples/send_email.py --subject "Agent test"

Success looks like: sent: Agent test in the terminal, and the email in your inbox.

Provider notes (the part everyone gets stuck on):

Provider Host The catch
Gmail smtp.gmail.com:587 You need an App Password (requires 2FA on) β€” your normal password will NOT work
Proton Mail 127.0.0.1:1025 Runs through Proton Mail Bridge on the same machine; Bridge shows you the local SMTP password
iCloud smtp.mail.me.com:587 App-specific password from appleid.apple.com
Resend / Postmark HTTPS API Best deliverability for higher volume; one curl call instead of SMTP

Step 2 β€” Let the agent write the body

Any agent CLI that can print to stdout can compose the email. Two real examples:

Claude Code, non-interactive (-p prints and exits):

claude -p "Read progress.md and feature_list.json in this repo and write a 5-line
status email: what moved, what's blocked, what's next. Plain text, no preamble." \
  | python3 examples/send_email.py --subject "Daily build report"

Hermes or any other CLI: same shape β€” prompt in, text out, pipe to the sender.

The prompt is the product here. Tell it exactly what to read, exactly what shape to write, and "no preamble" β€” you want an email, not a chat reply.


Step 3 β€” The trigger (this is what makes it proactive)

macOS/Linux, cron β€” every weekday at 7:00 AM:

crontab -e
# add (one line, with your real paths):
0 7 * * 1-5  cd /path/to/project && /usr/local/bin/claude -p "..." | python3 /path/to/send_email.py --subject "Morning digest"

examples/digest.sh in this repo is that one-liner as a proper script β€” point cron at it instead and keep the prompt editable in one place.

macOS, launchd (survives reboots better than cron): examples/com.agent.digest.plist β€” edit the paths, then:

cp examples/com.agent.digest.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/com.agent.digest.plist

Event triggers (beyond schedules): anything that can run a command can send an email β€” a git post-receive hook (build reports on push), a failing health check, a new row in a database. Same pipeline, different trigger.

OpenClaw users: Clawd's heartbeat already fires on a schedule β€” its natural proactive channel is Telegram/WhatsApp/Discord, and for email it can simply run this repo's send script like any other shell command.


The rules (read these before you automate)

  1. Email yourself first. Only yourself. Run the loop to your own inbox for two weeks before any wider audience. You'll be surprised what it sends at 7 AM.
  2. Never let an agent email other people unreviewed. Draft-then-approve is the pattern: the agent writes, a human clicks send. Fully autonomous outbound to real contacts is how trust (and deliverability) dies.
  3. Anything commercial is CAN-SPAM territory β€” real postal address, working unsubscribe, honest subject lines. Digests to yourself: exempt. Marketing to a list: law.
  4. Keys in the environment, never in the crontab line (crontabs get copied into dotfile repos). examples/digest.sh sources them from a gitignored env file.
  5. Rate-limit by design. A schedule caps itself; an event trigger needs a guard (the example script refuses to send more than one email per 5 minutes unless you pass --force).

Files in this repo

File What it is
examples/send_email.py Stdlib SMTP sender: env-driven, STARTTLS, rate-limit guard
examples/digest.sh The cron target: env file β†’ agent prompt β†’ send
examples/com.agent.digest.plist launchd schedule for macOS (7:00 weekdays)
examples/agent-email.env.example The env file template (copy, fill, gitignore)

Part of KeyzHub β€” take the code, build your own. Previous rung: /ai-agents-setup.

Prefer your phone over your inbox? Same pipeline, Telegram last mile: /telegram-bot-setup.