Files
claude-mail-buddy/plan.md

2.5 KiB

claude-mail-buddy — Plan

Concept

Poll a dedicated IMAP mailbox for incoming mail from a trusted sender, dispatch the message as a prompt to Claude Code via claude-remote, and have Claude reply via a CCC send-email action.


Sender Verification

The allowed_sender config filter is a basic check but not cryptographically sound. Stronger options (in increasing strength):

  • Authentication-Results header — check that the inbound mail server stamped DKIM/SPF pass before dispatching. Practical and low-effort since your mail server already does the verification.
  • DKIM — cryptographic signature from the sending domain's DNS key. Proves the message genuinely originated from that domain.
  • PGP/S/MIME — end-to-end signature tied to the sender's personal key, independent of mail infrastructure. Strongest guarantee; requires signing outbound mail from your client.

For now, allowed_sender substring match is sufficient for exploration. Worth adding Authentication-Results checking before using this for anything sensitive.


Implementation Stages

Stage 1 — Explore the message object

Receive a message and inspect() the full imapflow msg object to understand what data is available (headers, body parts, envelope, flags, etc.).

Stage 2 — Prompt construction

Parse the message into a well-formed prompt using mailparser. Use HTML body for better encoding/structure fidelity. Instruct Claude to reply via CCC per email_protocol.md.

Stage 3 — CCC send-email action

send-email action already existed in claude-code-conduit with full SMTP, permission store, and topic-based access control. Tested and working end-to-end.

Stage 4 — Wire it together

make_prompt + send_to_claude wired up. Full flow working: email in → Claude processes → replies via CCC send-email → email out.

Stage 5 — Adaptive polling

High/low frequency mode: switch to fast polling (e.g. 10s) when a message arrives, step back down to slow polling (e.g. 45s) after a configurable idle period with no new messages (e.g. 5 minutes). Keeps the conversation feeling responsive without hammering the server during quiet periods.

Stage 6 — Persist last UID

Save the last processed UID to a state file so the script picks up where it left off across restarts rather than skipping everything that existed at startup.

Stage 7 — Hardening

  • Verify Authentication-Results header for DKIM/SPF pass
  • Mark messages seen only after successful dispatch
  • Reconnect/retry logic for IMAP drops