Agent Mail via MCP Agent Mail
Status: shipped — all phases complete
Date: 2026-02-28
Deciders: Joel Hooks
Supersedes: None
Related: ADR-0169 (CLI capability contracts), ADR-0170 (agent role system), ADR-0171 (system prompt architecture), ADR-0181 (AT Proto adapter track)
Context
Multiple agents (gateway, codex workers, loop workers, interactive pi) operate on the same codebase simultaneously. Without coordination:
- Agents overwrite each other’s edits
- File conflicts cause silent data loss
- No way to communicate task status or friction between agents
- Branch-based isolation creates worktree management overhead Joel calls “a huge problem”
Joel identified Dicklesworthstone/mcp_agent_mail as the coordination layer. It’s an MCP HTTP server providing:
- Agent identity registration (memorable names)
- Inbox/outbox messaging with GFM markdown
- Advisory file reservations (leases) to signal edit intent
- Searchable, threaded message history
- Git-backed audit trail (human-readable artifacts)
- SQLite indexing for fast queries
Decision
Adopt mcp_agent_mail as the joelclaw mail adapter
Per ADR-0169 (CLI capability contracts), joelclaw mail is a port with a swappable adapter. The first adapter wraps mcp_agent_mail’s HTTP API.
Architecture
joelclaw mail send → CLI command
→ MailPort interface (ADR-0169)
→ McpAgentMailAdapter
→ HTTP POST to mcp_agent_mail server (:8765)
→ SQLite + Git storageWhy this project
- MCP-native — standard protocol, not proprietary API
- File reservations — advisory leases prevent edit conflicts, exactly what loop workers need
- Git-backed — every message and reservation is auditable
- Actively maintained — large test suite, Docker support, multi-agent design
- Agent-agnostic — works with any MCP client (Claude Code, Codex, Gemini, etc.)
Why NOT build from scratch
Joel has agent_mail and swarm-tools/swarm-mail as prior art. mcp_agent_mail subsumes both with a more complete implementation (identity management, file reservations, search, threading).
Integration plan
Phase 1: CLI wrapper (ADR-0169 port)
joelclaw mail register— register agent identityjoelclaw mail send <to> <message>— send messagejoelclaw mail read [--unread]— read inboxjoelclaw mail reserve <path>— claim file reservationjoelclaw mail release <path>— release reservation- HATEOAS JSON envelope on all responses
Phase 2: Pi extension tool
- Register
mailas pi tool viapi.registerTool() - Tool shells to
joelclaw mailunder the hood - Available to all pi sessions (gateway, interactive)
Phase 3: Pipeline integration
- Loop workers (ADR-0170) must
reservebefore editing,releaseafter commit - Story pipeline checks reservations before dispatching to workers
- Conflict detection: fail-fast if reserved by another agent
Boundary clarification (2026-03-06)
File reservations are advisory coordination, not runtime isolation.
They help agents avoid stepping on each other, but they do not guarantee:
- a clean mutable checkout
- stable execution identity across resumed runs
- isolation from unrelated host dirt
For autonomous story execution that mutates code, the runtime boundary now belongs to ADR-0205 and ADR-0206. This ADR continues to own coordination and auditability.
AT Protocol migration path
The MailPort interface (ADR-0169) is designed for adapter swapping, but AT Proto implementation scope is now tracked explicitly in ADR-0181.
This ADR ships MCP mail as the production adapter. Any atproto-pds implementation, parity testing, and rollout/rollback policy is governed by ADR-0181 so this ADR can remain closed as shipped.
Implementation Summary
Infrastructure (✅ done)
- mcp_agent_mail server running at
http://127.0.0.1:8765(FastAPI/uvicorn, SQLite + Git storage) - Source:
~/Code/Dicklesworthstone/mcp_agent_mail(local checkout now tracksjoelhooks/mcp_agent_mailasorigin,Dicklesworthstone/mcp_agent_mailasupstream), launched via uv - Health:
/health/liveness→{"status":"alive"} - Endpoints confirmed:
/mail,/mail/api/unified-inbox,/mail/api/locks,/mail/projects,/mcp - Process: PID-managed bash wrapper, logs to
/tmp/agentmail.log
Phase 1: CLI wrapper (✅ shipped 2026-02-28)
joelclaw mail status— server health + unified inbox summaryjoelclaw mail register— register agent (ensure_project + register_agent MCP tools)joelclaw mail send— send message (sender_name, to, subject, body_md)joelclaw mail inbox— fetch inbox with optional —unread filterjoelclaw mail read— mark message read + displayjoelclaw mail reserve— file path reservations (advisory locks) with explicit lease TTL (--ttl-seconds, short default)joelclaw mail renew— extend active reservation leases (--extend-seconds, optional--paths)joelclaw mail release— release reservations (—paths or —all)joelclaw mail locks— list active file reservationsjoelclaw mail search— full-text search over project messages- All commands return HATEOAS JSON envelopes via
respond() - Default project:
/Users/joel/Code/joelhooks/joelclaw(abs path required by server) - Default agent:
GreenPanda(server requires AdjectiveNoun format) - HTTP helper:
packages/cli/src/lib/agent-mail.ts(MCP JSON-RPC + REST) - Server naming: agents get auto-named if provided name not in dictionary
Phase 2: Pi extension + skill (✅ shipped 2026-02-28)
- Pi extension at
~/.pi/agent/extensions/agent-mail/index.ts- 6 tools:
mail_send,mail_inbox,mail_read,mail_reserve,mail_release,mail_status - All shell to
joelclaw mail— CLI is the single interface (no direct MCP registration in pi) - TypeBox schemas for typed tool calling
- 6 tools:
- Skill at
skills/agent-mail/SKILL.md(symlinked to~/.agents/skills/and~/.pi/agent/skills/)- Coordination patterns (file reservation workflow, task handoff, loop worker coordination)
- Full CLI quick reference
- Troubleshooting guide
- launchd plist at
~/Library/LaunchAgents/com.joelclaw.agent-mail.plist- KeepAlive + RunAtLoad, auto-restart on crash
- Logs to
~/.joelclaw/logs/agent-mail.{stdout,stderr}.log
- Health check in
joelclaw status—agent_mailliveness probe added - Session reminder policy in
pi/extensions/session-lifecycleexplicitly enforces announce/inbox/reserve/renew/release behavior. - Daily monitor+steer automation (✅ shipped 2026-03-01) now runs once/day in
session-lifecycle: computes mail/OTEL effectiveness signals, persists snapshot (~/.joelclaw/workspace/agent-mail-steering/YYYY-MM-DD.json), appends daily log summary, emitsagent-mail/steering.reviewed, and injects targeted reminder hints when drift is detected. - Steering signal integrity hardening (✅ shipped 2026-03-01): the daily steering loop treats
joelclaw mail searchtool/database failures as degraded signals (not zero traffic), preventing false low-coordination scoring. - Event emission env fallback hardening (✅ shipped 2026-03-01):
session-lifecycleresolvesINNGEST_EVENT_KEY/INNGEST_BASE_URLfrom process env,~/.config/inngest/env,~/.config/system-bus.env, thenpackages/system-bus/.env; smoke-verified by captured HTTP POST to/e/<event-key>. - Canonical protocol skill hardening (✅ shipped 2026-03-01): added
skills/clawmail/SKILL.mdas the comprehensive coordination contract (CLI-first, subject taxonomy, lock lifecycle, prompt author checklist).skills/agent-mail/SKILL.mdis now a compatibility alias that redirects to clawmail. - Mail search reliability hardening (✅ shipped locally 2026-03-01): patched
mcp_agent_mailLIKE fallback escaping to use a dedicated escape marker (!) with explicitESCAPE '!'clauses, avoiding SQLite ESCAPE edge-case failures on malformed FTS queries used by steering traffic analysis. Changes are in commitf76e905onjoelhooks/mcp_agent_mailand proposed upstream via PRDicklesworthstone/mcp_agent_mail#110. - Fork ownership for operational control (✅ shipped 2026-03-01): created
joelhooks/mcp_agent_mail, rewired local checkout remotes (origin= joelhooks fork,upstream= Dicklesworthstone upstream), and kept runtime on127.0.0.1:8765pinned to the patched local checkout.
Phase 3: Pipeline integration (✅ shipped 2026-02-28)
agent-loop/utils.ts:callAgentMailMcp,reserveFiles,releaseFiles,loopAgentNameagent-loop/implement.ts: reserve before tool spawn, release on all exit paths (commit, cancel, blocked, idempotent)- Deterministic AdjectiveNoun agent names via hash of loopId (100 combinations)
- Non-fatal — loop continues if agent-mail is down
- Auto-registers project + agent on first reservation (idempotent)
Current state
- Server live and healthy at
:8765, managed by launchd (auto-restart) - CLI fully functional, health check in
joelclaw status - Pi extension registers 6 tools, shells to CLI (no direct MCP in pi)
- Skill documents coordination patterns and troubleshooting
- Project
joelclawcreated, test agents registered (BlueFox, RedStone) - Test message sent and received successfully
Next steps
Build✅joelclaw mailCLI commands (Phase 1)Pi extension + skill + launchd + health check (Phase 2)✅Integrate file reservations into loop workers (Phase 3)✅Register production agent identities (Panda → MaroonReef)✅Gateway auto-registers its agent identity on boot✅Review step checks active reservations before dispatching parallel stories✅
Consequences
- Agents can coordinate without shared branches or worktrees
- File reservations prevent silent edit conflicts
- All agent communication is auditable via git
joelclaw mailbecomes mandatory in SYSTEM.md principles (already done)- mcp_agent_mail server must be running for agent coordination (add to health checks)
- AT Proto adapter work is separated into ADR-0181; this ADR remains the shipped MCP baseline