← back to Claude Mail
README.md
65 lines
# claude-mail
A back-and-forth **email channel for Claude** at `claude@agentabrams.com`.
Steve (or an allowlisted person) emails the address; a local poller reads it,
runs `claude` headless on this Mac with full local access, and replies in-thread.
Reply to the reply → it keeps the conversation going.
## How it works
```
sender ──▶ claude@agentabrams.com (Purelymail mailbox)
│ IMAP (imap.purelymail.com)
▼
poller.js ──▶ [ SENDER GATE ] ──▶ runClaude(-p) ──▶ SMTP reply in-thread
3 locks, all required (Max-plan auth, local tools)
```
### The sender gate — 3 independent locks (all must pass)
1. **Allowlist** — `From` must be one of `ALLOWED_SENDERS`.
2. **Secret phrase** — the subject must contain `[ok:<SECRET_PHRASE>]` (or the bare phrase).
3. **Email auth** — inbound mail must pass DKIM/DMARC/SPF (anti-spoof), unless `REQUIRE_AUTH_PASS=false`.
Anything failing the gate is **silently ignored** (marked read, no reply, no `claude` run).
Strangers get total silence and never reach the machine.
### Autonomy rails (injected into every run via `--append-system-prompt`)
- Safe / reversible / local / read-only work runs directly and is reported.
- **Gated** actions (prod writes, sends to third parties, DNS, spend, deletes,
customer-facing, remote pushes) are **NOT executed** — Claude describes the plan
and asks for a "go". Default `CLAUDE_PERMISSION_MODE=acceptEdits` also keeps the
headless run from running unattended `Bash` (Read/Grep/Glob/Edit/Write still work).
## Files
- `poller.js` — one poll pass (run on an interval by launchd). Idempotent.
- `lib.js` — config, sender gate, quote-stripping, claude runner, mailer.
- `send.js` — one-off sender: `node --env-file=.env send.js <to> "<subj>" < body.txt`.
- `imap-check.js` — read-only connectivity check (no claude, no send).
- `run.sh` — wrapper used by the LaunchAgent.
- `.env` — secrets + config (gitignored).
- `~/Library/LaunchAgents/com.steve.claude-mail.plist` — the scheduler (every 120s).
## Activate the always-on poller
```sh
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.steve.claude-mail.plist
launchctl kickstart -k gui/$(id -u)/com.steve.claude-mail # run once now
```
Stop / disable:
```sh
launchctl bootout gui/$(id -u)/com.steve.claude-mail
```
Logs: `tail -f ~/Projects/claude-mail/poller.log`
## Manual run (no scheduler)
```sh
cd ~/Projects/claude-mail && ./run.sh # one pass
node --env-file=.env imap-check.js # read-only inbox peek
```
## Tuning
- **Allowlist / phrase** — edit `.env` (`ALLOWED_SENDERS`, `SECRET_PHRASE`).
- **Let it run Bash unattended** — set `CLAUDE_PERMISSION_MODE=bypassPermissions`
(more capable, more risk; the gate + rails are then the only guardrails).
- **Deliverability** — `agentabrams.com` may need DKIM enabled (Purelymail +
Cloudflare DNS) so replies don't land in spam. Gated DNS change — do separately.