
Agent Mail
- 23 installs
- 416 repo stars
- Updated August 5, 2026
- boshu2/agentops
agent-mail is a Claude skill that coordinates multiple agents on a shared repo using file reservations, inboxes, threads, and handoffs to prevent write collisions.
About
Operating doctrine for Agent Mail, a side channel that coordinates multiple agents sharing one repo through file reservations, inboxes, threads, acknowledgements, and handoffs. A developer uses it when two or more agent lanes write the same repo and need to reserve a hot path before editing to prevent silent clobbering. It also defines the boundary: Agent Mail handles leases and notifications, while BR/beads remains the durable source of truth for work state and evidence.
- Coordinates multiple agents with file reservations, inboxes, threads, and handoffs to prevent write collisions
- Draws the boundary between Agent Mail (leases/notifications) and BR/beads (durable work-state source of truth)
- Provides both an MCP-tool surface and an `am` CLI for any shell agent
Agent Mail by the numbers
- 23 all-time installs (skills.sh)
- Ranked #10,032 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
agent-mail capabilities & compatibility
- Capabilities
- agent coordination · file reservation · agent handoff · swarm orchestration
- Works with
- github
- Use cases
- orchestration
What agent-mail says it does
Agent Mail is the side channel for leases, notifications, acknowledgements, and handoffs.
One-writer-per-hot-dir rule: reserve the path before editing it.
npx skills add https://github.com/boshu2/agentops --skill agent-mailAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 23 |
|---|---|
| repo stars | ★ 416 |
| Last updated | August 5, 2026 |
| Repository | boshu2/agentops ↗ |
What it does
Coordinate two or more agent lanes on a shared repo with file reservations and inbox notifications to prevent write collisions.
Who is it for?
Swarms or concurrent agent sessions where two or more lanes share a repo and must avoid clobbering shared files.
Skip if: A single sole-writer session with no concurrent lane, where coordination is an unnecessary session-start tax.
When should I use this skill?
When two or more agent lanes or panes share a repo and need file reservations, cross-lane ACKs, or handoffs.
What you get
One-writer-per-hot-path reservations and auditable lane messaging keep parallel agent waves from colliding.
- File reservations on hot paths
- Auditable lane messages and ACKs
By the numbers
- 5 coordination disciplines (cards 1-5)
- coordination boundary table with 4 need-to-source-of-truth rows
Files
<!-- TOC: Boundary | Disciplines | When to Use What | Bootstrap | Reservations | Beads | Troubleshooting | References -->
Using Agent Mail
Core Insight: Agent Mail is the side channel for leases, notifications, acknowledgements, and handoffs. BR/beads is the durable coordination bus and source of truth for work state, evidence, and decisions.
⚠️ TWO SURFACES — read this first. Every operation has BOTH an MCP-tool form (send_message,fetch_inbox, …) AND a CLI form (am mail send,am mail inbox, …). The MCP tools are only present when the agent-mail MCP server is wired into your session's tool surface — a plain CLI/shell agent (or a session where the MCP server didn't load) will NOT have them. In that case use theamCLI, which works from any shell. Discoverability trap (br cp-jgcl): the send/reply verbs live under theam mailgroup, whicham --helpdoes NOT list, and the read commands have flat aliases (am inbox,am status) but `am send` does not exist — it is `am mail send`. When in doubt:am mail --help,am macros --help,am file_reservations --help.
Don't re-learn the command surface from this skill. The MCP server self-describes its tools and resources in your tool list; the CLI self-describes via am --help and the group helps above. This skill carries only the operating doctrine: when to use mail, the reservation discipline, and the coordination boundaries. Full tool/parameter catalog: TOOLS.md.
When this applies (scope guard). Agent Mail coordination — start-session, identity registration, file reservations, cross-lane ACKs — is required when ≥2 lanes/panes share the repo (a swarm, or you plus a concurrent peer session). With only one active writer (no second lane/pane), do not register or reserve against yourself — coordination is an escalation, not a session-start tax. If you are the sole writer, skip to the work. (Doctrine: operating-loop principle 8 — single-agent-first.)>
Asymmetry guardrail — the part of the de-mandate that does NOT relax. AM answers a contention axis; ATM answers a separate durability axis (they're not a package — full 4-case matrix in `using-atm`). The de-mandate removes the single-writer session-start tax, not the collision guard. The costs are asymmetric: an unneeded AM call costs one command; a missing one lets two writers silently clobber a shared file and the merge looks like ordinary conflict cleanup while the design forked. So the `≥2-writers → reserve` reflex stays non-negotiable. "Trust the models" does not grant two concurrent writers consistency on one path. Partition before you lock: if you can cut the write-sets disjoint (sole writer per file), do that instead of reserving — locks are the fallback when partition fails.
Coordination Boundary
| Need | Source of truth |
|---|---|
| Work queue, status, dependencies, priority, closure evidence | BR/beads (br/bv) |
| File ownership, active edit leases, lane notifications, acks | Agent Mail |
| Final proof that work is done | Bead notes/closure plus git/CI evidence |
| "Who may write this hot path right now?" | Agent Mail file reservation |
Use Agent Mail to prevent collisions and notify active agents. Do not use it as the durable task queue, audit log, or final evidence store. If a mail thread and BR disagree, reconcile the bead first and link the mail thread from the bead note if the conversation matters.
One-writer-per-hot-dir rule: reserve the path before editing it. If the reservation conflicts, do not write into that path; coordinate with the holder, narrow scope, or wait for the lease to clear.
Coordination disciplines (2026-06-09, cards 1–5, cp-hhd7)
Durable lane identities (card 1, cp-9lrb)
Register a durable adjective+noun identity at session start. Pane text and human relay are unauditable and load the operator. The ledger is the bus — both lanes must be registered to exchange auditable messages. Do not coordinate via informal pane text when send_message + fetch_inbox is available.
Content-push, not pointers (card 2, cp-9lrb)
When sending a lane a message, push the content — include the actual text, diff, or decision. A pointer to a message-id the recipient cannot discover by inbox is still a relay. If the recipient's inbox is broken and they cannot read by-id, a pointer is a dead end. Short content fits in the body; long content goes to a committed artifact with an absolute path, not an AM-internal id.
Intent on the graph first — dedup (card 3, cp-hhtu)
Before any actor acts on a bead (intake, admit, implement, validate, mutate), update the bead status and set the actor on the graph first, then check for an existing actor. Parallel pipelines are blind to each other at every tier — dedup via the ledger, not behavioral coordination. Five exhibits of same-bead parallel work hit the fleet in one day (impl/validate/admission/mutation/intake, cp-hhtu). The fix is structural: intent on the graph is the lock.
ACK-with-id on routed writes (card 5, cp-fmt8)
When routing a write through a single writer (e.g. a beads-intake lane), require ACK-with-id back to the requester — the AM message id of the filed bead or the br show <id> output confirming the record exists. An unacknowledged routed write is invisible work. "Are these filed?" must not be a question — the ACK closes it.
When to Use What
| Situation | Action |
|---|---|
| Starting any agent session | macro_start_session (CLI: am macros start-session) |
| Confirm a lane actually registered | am robot agents --project <abs> --active — must list your name and each peer lane |
| About to edit files | reserve paths → edit → release reservations |
| Need to tell another agent something | send_message with thread_id (CLI: am mail send) |
| Picking up someone else's work | macro_prepare_thread |
| Need durable work state or evidence | Update BR/beads, then link the mail thread if useful |
| Can't message an agent | request_contact → wait for approval |
| Server seems broken | health_check() first; CLI-only: doctor check --verbose → doctor repair --yes |
Session Bootstrap
*Call `macro_start_session` (or `am macros start-session --project <abs> --program <p> --model <m> --task "<desc>"`) at the start of every multi-lane agent session* (skip it when you are the sole writer — see the scope guard above). One call: ensures project exists → registers your identity → reserves files → fetches inbox. Returns {project, agent, file_reservations, inbox}.
Verify the lane registered. A pane can look spawned and still have never registered — its start-session may not have landed. Confirm with:
am robot agents --project <abs> --active # should list YOUR name and each peer laneIf your name (or a peer's) is missing, that lane's start-session did not land — do not assume the coordination leg is live. Re-run start-session for the missing lane before relying on mail/reservations between you. Skipping this check is how the coordination leg silently goes unverified.
Identity notes:
- Agents get adjective+noun names (GreenCastle, BlueLake). Omit
name/--nameto auto-generate a valid one. am macros start-sessionauto-generates a fresh identity per project; you will have a different name in each project. Confirm yours viaam agent start.- The other macros (
macro_prepare_thread,macro_file_reservation_cycle,macro_contact_handshake) and the fastresource://reads are self-described by the server; catalog in TOOLS.md and RESOURCES.md.
File Reservations — Reserve Before Editing
The discipline, not the syntax (syntax: am file_reservations --help or the file_reservation_paths tool):
1. Reserve before the first write. Glob patterns are fine (src/auth/**/*.ts). Set a real ttl_seconds and put the bead id in reason. 2. Check `conflicts` in the response. On conflict: wait for TTL expiry, message the holder, or share with exclusive=false. Never write into a conflicted path. 3. Release when done (release_file_reservations / am file_reservations release <abs> <me>). Don't squat on leases across unrelated work.
Beads Integration
Use bead IDs as your threading anchor. BR remains authoritative; mail carries the lease, notification, and discussion side channel.
1. Pick work: br ready --json → choose bd-123
2. Reserve files: file_reservation_paths(..., reason="bd-123")
3. Announce: send_message(..., thread_id="bd-123", subject="[bd-123] Starting...")
4. Work: Reply in thread with progress
5. Record evidence: br update bd-123 --notes "Validation: tests, commit, CI, or handoff proof"
6. Complete: br close bd-123, release_file_reservations(...), final messageBead ID (often bd-###) goes in: thread_id, subject prefix, reservation reason, commit message
Do not infer durable state from mail silence. A missing reply is not proof that a bead is abandoned, blocked, or complete. Check br show <id> --json, bv --robot-insights, git state, and CI evidence before changing work state.
Quick Troubleshooting
| Error | Fix |
|---|---|
| "sender_name not registered" | Call macro_start_session first |
| Pane looks spawned but coordination is silent | A pane can look spawned yet never have registered. Run am robot agents --project <abs> --active — if the lane is absent, its start-session didn't land; re-run it |
| "FILE_RESERVATION_CONFLICT" | Wait, coordinate, or use exclusive=false |
| "CONTACT_BLOCKED" | Use request_contact, wait for approval |
| Server unreachable | am robot health (works CLI-only, direct SQLite) or health_check() (MCP). curl …:8765/health only resolves if the HTTP MCP server is running; CLI-only deploys have no :8765 listener. Start the server with am |
| Guard blocks commit | Set AGENT_NAME env var; emergency bypass: AGENT_MAIL_BYPASS=1 git commit |
Deeper diagnostics (doctor check/repair), the pre-commit guard (install_precommit_guard), the human-overseer web UI, and FTS5 search syntax are all self-described by the server/CLI — see RECOVERY.md and ADVANCED.md.
References
| Topic | Reference |
|---|---|
| All MCP tools | TOOLS.md |
| Workflow patterns | WORKFLOWS.md |
| MCP resources | RESOURCES.md |
| Cross-project setup | CROSS-PROJECT.md |
| Doctor & recovery | RECOVERY.md |
| Installation | INSTALL.md |
| Fix MCP config | FIX-MCP-CONFIG.md |
| Product bus, build slots, internals | ADVANCED.md |
Validation
am robot health # PRIMARY check — CLI/direct SQLite, works without the HTTP server
am agent start --json # cockpit; flags a missing :8765 listener under mcp_endpoint=fail
curl http://127.0.0.1:8765/health # ONLY if the HTTP MCP server is up (am serve-http); CLI-only deploys have no :8765 listener
am # start server if needed---
Fork maintenance. am is Bo's fork (boshu2/mcp_agent_mail_rust). To pull upstream fixes, use the fork-sync factory in ~/dev/mcp_agent_mail_rust: make fork-status → make fork-preview → make fork-sync (its AGENTS.md § "Upstream sync"; never rebase main by hand). Divergence facts are owned by FORKS-MAP F-3.
Advanced Agent Mail Features
Table of Contents
---
Product Bus
Group multiple repositories under a single product for unified inbox/search.
CLI Commands
# Ensure product exists
mcp-agent-mail products ensure MyProduct --name "My Product"
# Link project to product
mcp-agent-mail products link MyProduct /abs/path/backend
mcp-agent-mail products link MyProduct /abs/path/frontend
# Product status
mcp-agent-mail products status MyProduct
# Product-wide search
mcp-agent-mail products search MyProduct "urgent AND deploy" --limit 50
# Product-wide inbox
mcp-agent-mail products inbox MyProduct GreenCastle --urgent-only --include-bodies
# Product-wide thread summary
mcp-agent-mail products summarize-thread MyProduct "bd-123"Use Cases
- Monorepo with multiple packages
- Frontend/backend split repos
- Microservices architecture
- Shared component libraries
---
Build Slots
Advisory locks for long-running tasks (dev servers, watchers, builds).
Tools
| Tool | Purpose |
|---|---|
acquire_build_slot(project_key, agent_name, slot, ttl_seconds?, exclusive?) | Acquire slot |
renew_build_slot(project_key, agent_name, slot, extend_seconds?) | Extend TTL |
release_build_slot(project_key, agent_name, slot) | Release slot |
CLI Helpers
# Print environment keys for scripts
mcp-agent-mail amctl env --path . --agent GreenCastle
# Wrap command with env keys set
mcp-agent-mail am-run frontend-build -- npm run devExample Workflow
1. Acquire slot: acquire_build_slot(project_key, agent_name, "dev-server", ttl_seconds=3600)
2. Start process: npm run dev
3. Renew as needed: renew_build_slot(project_key, agent_name, "dev-server", extend_seconds=1800)
4. Release on exit: release_build_slot(project_key, agent_name, "dev-server")---
Client Integrations
Claude Code
Integration script: scripts/integrate_claude_code.sh
- Configures
.claude/settings.json - Installs hooks for inbox reminders
- MCP server configuration
Hooks for Inbox Reminders:
- Fire after tool invocations
- Rate limited to once per 2 minutes
- Uses fast curl calls (no Python import overhead)
Codex CLI
Integration script: scripts/integrate_codex_cli.sh
- Configures
~/.codex/config.toml - Uses
notifyhandler for reminders
Gemini CLI
Integration script: scripts/integrate_gemini_cli.sh
- Configures
~/.gemini/settings.json
Automatic Inbox Reminders
All integrations support inbox reminder hooks:
{
"hooks": {
"post_tool_call": [
{
"command": "curl -s http://127.0.0.1:8765/api/inbox-reminder?agent=${AGENT_NAME}",
"rate_limit_seconds": 120
}
]
}
}---
On-Disk Layout
<STORAGE_ROOT>/projects/<slug>/
agents/<AgentName>/profile.json
agents/<AgentName>/inbox/YYYY/MM/<msg-id>.md
agents/<AgentName>/outbox/YYYY/MM/<msg-id>.md
messages/YYYY/MM/<msg-id>.md
messages/threads/<thread-id>.md # optional digest
file_reservations/<sha1-of-path>.json
attachments/<xx>/<sha1>.webp
build_slots/<slot>/<agent>__<branch>.jsonMessage File Format
GFM Markdown with JSON frontmatter:
---json
{
"id": 1234,
"thread_id": "TKT-123",
"project": "/abs/path/backend",
"from": "GreenCastle",
"to": ["BlueLake"],
"created": "2025-10-23T15:22:14Z",
"importance": "high",
"ack_required": true
}
---
# Message subject
Message body in markdown...File Reservation Format
{
"id": 101,
"agent": "GreenCastle",
"path_pattern": "src/auth/**/*.ts",
"exclusive": true,
"reason": "bd-123",
"created_ts": "2025-10-23T15:00:00Z",
"expires_ts": "2025-10-23T16:00:00Z"
}---
Database Schema
SQLite with FTS5 for full-text search.
Core Tables
projects(id, human_key, slug, created_at)
agents(id, project_id, name, program, model, task_description,
inception_ts, last_active_ts, attachments_policy, contact_policy)
messages(id, project_id, sender_id, thread_id, subject, body_md,
created_ts, importance, ack_required, attachments)
message_recipients(message_id, agent_id, kind, read_ts, ack_ts)
file_reservations(id, project_id, agent_id, path_pattern, exclusive,
reason, created_ts, expires_ts, released_ts)
agent_links(id, a_project_id, a_agent_id, b_project_id, b_agent_id,
status, reason, created_ts, updated_ts, expires_ts)FTS Index
fts_messages(message_id UNINDEXED, subject, body)
-- Auto-maintained via triggers on messages tableKey Relationships
agents.project_id→projects.idmessages.project_id→projects.idmessages.sender_id→agents.idmessage_recipients.message_id→messages.idmessage_recipients.agent_id→agents.idfile_reservations.project_id→projects.idfile_reservations.agent_id→agents.id
---
Environment Variables
| Variable | Default | Description |
|---|---|---|
STORAGE_ROOT | ~/.mcp_agent_mail_git_mailbox_repo | Root for repos + SQLite |
HTTP_PORT | 8765 | Server port |
HTTP_BEARER_TOKEN | — | Static bearer token |
HTTP_JWT_ENABLED | false | Enable JWT validation |
LLM_ENABLED | true | Enable LLM summaries |
LLM_DEFAULT_MODEL | gpt-5-mini | LLM model for summaries |
CONTACT_ENFORCEMENT_ENABLED | true | Enforce contact policy |
INLINE_IMAGE_MAX_BYTES | 65536 | Threshold for inlining WebP |
FILE_RESERVATION_INACTIVITY_SECONDS | 1800 | Staleness threshold |
---
Git-Based Project Identity
Worktree Mode
For git worktrees, Agent Mail can resolve identity from path markers:
resource://identity/{path}Identity Modes
| Mode | Behavior |
|---|---|
strict | Reject invalid agent names |
coerce | Auto-generate if invalid |
always_auto | Always auto-generate names |
Project Adoption
For linking existing repositories to Agent Mail projects:
# During project ensure, specify identity mode
ensure_project(human_key="/abs/path", identity_mode="coerce")Cross-Project Coordination
When agents work across multiple repositories (frontend/backend, monorepo, microservices).
---
Option A: Same Project Key (Simplest)
Use the same project_key for related repos. Agents auto-coordinate.
# Both agents use same project_key
macro_start_session(
human_key="/abs/path/monorepo",
program="codex-cli",
model="YOUR_MODEL"
)---
Option B: Separate Projects with Contact Links
For truly separate projects, establish contact links.
Step 1: Backend Agent Requests Contact
request_contact(
project_key="/abs/path/backend",
from_agent="GreenCastle",
to_agent="BlueLake",
to_project="/abs/path/frontend",
reason="API coordination"
)Step 2: Frontend Agent Accepts
respond_contact(
project_key="/abs/path/frontend",
to_agent="BlueLake",
from_agent="GreenCastle",
accept=true
)Step 3: Cross-Project Messaging
send_message(
project_key="/abs/path/backend",
sender_name="GreenCastle",
to=["BlueLake"],
subject="API contract update",
body_md="Changed /api/users response schema..."
)---
Option C: Product Bus (Multi-Repo Products)
Group related projects under a product for unified inbox/search.
CLI Commands
# Create product
mcp-agent-mail products ensure MyProduct --name "My Product"
# Link projects
mcp-agent-mail products link MyProduct /abs/path/backend
mcp-agent-mail products link MyProduct /abs/path/frontend
# Product-wide search
mcp-agent-mail products search MyProduct "urgent AND deploy" --limit 50
# Product-wide inbox
mcp-agent-mail products inbox MyProduct GreenCastle --urgent-only
# Product-wide thread summary
mcp-agent-mail products summarize-thread MyProduct "bd-123"---
Contact Policies
| Policy | Behavior |
|---|---|
open | Accept any message (no contact required) |
auto (default) | Allow if shared context exists |
contacts_only | Require explicit approval |
block_all | Reject all cross-project messages |
set_contact_policy(project_key, agent_name, "auto")---
Macro: Contact Handshake
One-call setup with optional auto-accept:
macro_contact_handshake(
project_key="/abs/path/backend",
requester="GreenCastle",
target="BlueLake",
to_project="/abs/path/frontend",
auto_accept=true,
welcome_subject="Backend coordination",
welcome_body="Let's coordinate API changes"
)---
Cross-Project File Reservations
File reservations are project-scoped. For shared files:
1. Use same project_key (Option A), or 2. Coordinate via messages before editing shared paths
# In backend project
send_message(
...
subject="Need to edit shared/types.ts",
body_md="Planning changes to shared types. Any conflicts?"
)---
Troubleshooting
| Issue | Fix |
|---|---|
| "CONTACT_BLOCKED" | Run request_contact, wait for respond_contact(accept=true) |
| Can't find agent | Use resource://agents/{project_key} to discover names |
| Messages not arriving | Verify to_project is correct absolute path |
| Contact expired | Re-request; default TTL is 7 days |
Fix Claude Code MCP Configuration
When MCP server setup gets wiped out (fresh install, corruption, updates):
Quick Fix
fix_cc_mcpThis restores both mcp-agent-mail and morph-mcp servers.
Install the Script
# Create the script
cat > ~/.local/bin/fix_cc_mcp << 'SCRIPT'
#!/usr/bin/env bash
set -euo pipefail
MCP_AGENT_MAIL_DIR="${MCP_AGENT_MAIL_DIR:-${HOME}/mcp_agent_mail}"
MCP_URL="${MCP_URL:-http://127.0.0.1:8765/mcp/}"
MORPH_API_KEY="${MORPH_API_KEY:-YOUR_MORPH_API_KEY_HERE}"
SCOPE="${MCP_SCOPE:-user}"
# Check for claude CLI
command -v claude &>/dev/null || { echo "Install Claude Code first"; exit 1; }
# Get bearer token
TOKEN=""
[[ -n "${MCP_AGENT_MAIL_TOKEN:-}" ]] && TOKEN="${MCP_AGENT_MAIL_TOKEN}"
[[ -z "${TOKEN}" && -f "${MCP_AGENT_MAIL_DIR}/.env" ]] && \
TOKEN=$(grep -E '^HTTP_BEARER_TOKEN=' "${MCP_AGENT_MAIL_DIR}/.env" 2>/dev/null | sed 's/^HTTP_BEARER_TOKEN=//' | tr -d '"'"'" | tr -d '[:space:]' || true)
[[ -z "${TOKEN}" && -f "${HOME}/.claude.json" ]] && \
TOKEN=$(grep -o '"Authorization": "Bearer [^"]*"' "${HOME}/.claude.json" 2>/dev/null | head -1 | sed 's/.*Bearer //' | tr -d '"' || true)
[[ -z "${TOKEN}" ]] && { echo "Could not find bearer token"; exit 1; }
# Remove existing, add fresh
claude mcp remove mcp-agent-mail --scope "${SCOPE}" 2>/dev/null || true
claude mcp remove morph-mcp --scope "${SCOPE}" 2>/dev/null || true
claude mcp add mcp-agent-mail "${MCP_URL}" --transport http --header "Authorization: Bearer ${TOKEN}" --scope "${SCOPE}"
claude mcp add morph-mcp -e "MORPH_API_KEY=${MORPH_API_KEY}" -e "ENABLED_TOOLS=warp_grep" --scope "${SCOPE}" -- npx -y @morphllm/morphmcp
claude mcp list
echo "✓ MCP configuration restored"
SCRIPT
chmod +x ~/.local/bin/fix_cc_mcpManual Commands
# Remove existing
claude mcp remove mcp-agent-mail --scope user
claude mcp remove morph-mcp --scope user
# Add mcp-agent-mail (HTTP transport)
claude mcp add mcp-agent-mail "http://127.0.0.1:8765/mcp/" \
--transport http \
--header "Authorization: Bearer <token>" \
--scope user
# Add morph-mcp (stdio transport via npx)
claude mcp add morph-mcp \
-e "MORPH_API_KEY=<key>" \
-e "ENABLED_TOOLS=warp_grep" \
--scope user \
-- npx -y @morphllm/morphmcpToken Discovery
| Priority | Source |
|---|---|
| 1 | MCP_AGENT_MAIL_TOKEN env var |
| 2 | ~/mcp_agent_mail/.env |
| 3 | ~/.claude.json |
Configuration Options
| Variable | Default |
|---|---|
MCP_AGENT_MAIL_TOKEN | (auto-detected) |
MCP_AGENT_MAIL_DIR | ~/mcp_agent_mail |
MCP_URL | http://127.0.0.1:8765/mcp/ |
MORPH_API_KEY | (in script) |
MCP_SCOPE | user |
Troubleshooting
| Problem | Solution |
|---|---|
| "claude CLI not found" | Install Claude Code first |
| "Could not find bearer token" | Run full MCP Agent Mail installer |
| Server "not connected" | Ensure server is running: am |
Full Installer (Alternative)
If you need to update MCP Agent Mail itself:
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/mcp_agent_mail/main/scripts/install.sh" | bash -s -- --yesAgent Mail Installation & Recovery
Table of Contents
---
Quick Install
One-Liner (Recommended)
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/mcp_agent_mail/main/scripts/install.sh?$(date +%s)" | bash -s -- --yesCustom Port
curl -fsSL ... | bash -s -- --port 9000 --yesChange Port After Install
uv run python -m mcp_agent_mail.cli config set-port 9000---
Configuration
Start Server
# Quickest (alias added during install)
am
# Or manually
cd ~/projects/mcp_agent_mail
./scripts/run_server_with_token.shKey Environment Variables
| Variable | Default | Description |
|---|---|---|
STORAGE_ROOT | ~/.mcp_agent_mail_git_mailbox_repo | Root for repos + SQLite |
HTTP_PORT | 8765 | Server port |
HTTP_BEARER_TOKEN | — | Static bearer token |
See ADVANCED.md for full list.
Claude Code MCP Config
Add to ~/.claude.json:
{
"mcpServers": {
"mcp-agent-mail": {
"type": "http",
"url": "http://127.0.0.1:8765/mcp",
"headers": {
"Authorization": "Bearer YOUR_TOKEN"
}
}
}
}---
Disaster Recovery
Create Backup
uv run python -m mcp_agent_mail.cli archive save --label nightlyList Restore Points
uv run python -m mcp_agent_mail.cli archive list --jsonRestore After Disaster
uv run python -m mcp_agent_mail.cli archive restore <file>.zip --force---
Health Checks
Run Diagnostics
uv run python -m mcp_agent_mail.cli doctor checkChecks:
- Stale locks
- Database integrity
- Orphaned records
- FTS sync
- Expired reservations
Preview Repairs
uv run python -m mcp_agent_mail.cli doctor repair --dry-runApply Repairs
# Creates backup first
uv run python -m mcp_agent_mail.cli doctor repairQuick Health Check
am robot health # primary — CLI/direct, works without the HTTP server
curl http://127.0.0.1:8765/health # only if the HTTP MCP server is running (am serve-http)
# {"status": "healthy"}---
Docker
Build
docker build -t mcp-agent-mail .Run
docker run --rm -p 8765:8765 \
-e HTTP_HOST=0.0.0.0 \
-v agent_mail_data:/data \
mcp-agent-mail---
Static Mailbox Export
Export for auditors, stakeholders, or archives:
Interactive Wizard (Recommended)
uv run python -m mcp_agent_mail.cli share wizardManual Export
uv run python -m mcp_agent_mail.cli share export --output ./bundleWith Signing
uv run python -m mcp_agent_mail.cli share export \
--output ./bundle \
--signing-key ./keys/signing.keyPreview Locally
uv run python -m mcp_agent_mail.cli share preview ./bundleExport Features
- Ed25519 cryptographic signing
- Age encryption for confidential distribution
- Scrub presets:
standard(removes secrets) orstrict(redacts bodies) - Deploy to GitHub Pages or Cloudflare Pages via wizard
See RECOVERY.md for full options.
---
Pre-Commit Guard
Install to enforce file reservations at commit time:
install_precommit_guard(project_key="/abs/path", code_repo_path="/abs/path")Quick reference:
- Set
AGENT_NAMEenv var so guard knows who you are - Bypass:
AGENT_MAIL_BYPASS=1 git commit -m "fix" - Uninstall:
uninstall_precommit_guard(code_repo_path="/abs/path")
Features: Composition-safe (preserves existing hooks), rename-aware, NUL-safe, Git wildmatch pathspec.
Doctor & Disaster Recovery
Diagnostics, repair, backup, and restore for Agent Mail.
---
Quick Health Check
am robot health # primary — CLI/direct, works without the HTTP server
curl http://127.0.0.1:8765/health # only if the HTTP MCP server is running (am serve-http)
# → {"status": "healthy"}---
Doctor Commands
Run Diagnostics
# Basic check
uv run python -m mcp_agent_mail.cli doctor check
# Verbose with details
uv run python -m mcp_agent_mail.cli doctor check --verbose
# JSON output for automation
uv run python -m mcp_agent_mail.cli doctor check --json
# Check specific project
uv run python -m mcp_agent_mail.cli doctor check /abs/path/projectChecks performed:
- Stale file reservations (expired TTL)
- Database integrity
- Orphaned records
- FTS index sync
- Git archive consistency
Preview Repairs (Dry Run)
uv run python -m mcp_agent_mail.cli doctor repair --dry-runShows what would be fixed without making changes.
Apply Repairs
# Interactive (prompts for confirmation)
uv run python -m mcp_agent_mail.cli doctor repair
# Auto-confirm (creates backup first)
uv run python -m mcp_agent_mail.cli doctor repair --yes
# With custom backup directory
uv run python -m mcp_agent_mail.cli doctor repair --yes --backup-dir /tmp/backups---
Backup & Restore
Create Backup
# With label
uv run python -m mcp_agent_mail.cli archive save --label nightly
# Default label (timestamp)
uv run python -m mcp_agent_mail.cli archive saveList Backups
uv run python -m mcp_agent_mail.cli doctor backups
# JSON format
uv run python -m mcp_agent_mail.cli doctor backups --jsonRestore from Backup
# Preview what would be restored
uv run python -m mcp_agent_mail.cli doctor restore /path/to/backup.zip --dry-run
# Perform restore
uv run python -m mcp_agent_mail.cli doctor restore /path/to/backup.zip --yes---
Static Mailbox Export
Export mailbox for auditors, stakeholders, or archives.
Interactive Wizard (Recommended)
uv run python -m mcp_agent_mail.cli share wizardGuides you through export options, signing, encryption, and deployment.
Manual Export
# Basic export
uv run python -m mcp_agent_mail.cli share export --output ./bundle
# With cryptographic signing
uv run python -m mcp_agent_mail.cli share export \
--output ./bundle \
--signing-key ./keys/signing.key
# With age encryption
uv run python -m mcp_agent_mail.cli share export \
--output ./bundle \
--age-recipient age1abc...xyz
# Scrub sensitive content
uv run python -m mcp_agent_mail.cli share export \
--output ./bundle \
--scrub-preset strict # or 'standard'Preview Exported Bundle
uv run python -m mcp_agent_mail.cli share preview ./bundle --port 9000 --open-browserVerify Bundle Integrity
uv run python -m mcp_agent_mail.cli share verify ./bundleRefresh Existing Bundle
uv run python -m mcp_agent_mail.cli share update ./bundleDecrypt Age-Encrypted Bundle
uv run python -m mcp_agent_mail.cli share decrypt bundle.zip.age --identity ~/.age/key.txt---
Dangerous Operations
Full Reset (Destructive!)
# Prompts for archive first
uv run python -m mcp_agent_mail.cli clear-and-reset-everything
# Skip prompts (automation)
uv run python -m mcp_agent_mail.cli clear-and-reset-everything --force --no-archiveWARNING: Deletes SQLite database and all storage contents.
---
File Reservation Management
List Reservations
# All reservations
uv run python -m mcp_agent_mail.cli file_reservations list /abs/path/project
# Active only
uv run python -m mcp_agent_mail.cli file_reservations list /abs/path/project --active-only
# Active with limit
uv run python -m mcp_agent_mail.cli file_reservations active /abs/path/project --limit 10Expiring Soon
# Reservations expiring within 30 minutes
uv run python -m mcp_agent_mail.cli file_reservations soon /abs/path/project --minutes 30---
ACK Management
Pending Acknowledgments
uv run python -m mcp_agent_mail.cli acks pending /abs/path/project GreenCastle --limit 10Overdue ACKs
uv run python -m mcp_agent_mail.cli acks overdue /abs/path/project GreenCastle --ttl-minutes 60Remind About Old ACKs
uv run python -m mcp_agent_mail.cli acks remind /abs/path/project GreenCastle --min-age-minutes 30---
Common Issues
| Symptom | Diagnosis | Fix |
|---|---|---|
| Stale reservations accumulating | Agent crashed without releasing | doctor repair --yes |
| FTS search returns wrong results | Index out of sync | doctor repair --yes |
| "database is locked" | Concurrent access issue | Restart server, retry |
| Corrupted git archive | Interrupted write | Restore from backup |
| Server won't start | Port conflict | config set-port 9000 |
MCP Resources Reference
Fast read-only access to Agent Mail data via MCP resources.
---
Inbox & Outbox
Inbox
resource://inbox/{agent}?project=<path>&limit=20&include_bodies=true| Parameter | Required | Default | Description |
|---|---|---|---|
project | Yes | — | Absolute path to project |
limit | No | 20 | Max messages to return |
include_bodies | No | false | Include full message bodies |
since_ts | No | — | ISO-8601 timestamp filter |
urgent_only | No | false | Only high/urgent messages |
Outbox
resource://outbox/{agent}?project=<path>&limit=20Same parameters as inbox.
Combined Mailbox
resource://mailbox/{agent}?project=<path>&limit=20Returns both sent and received messages.
---
Messages & Threads
Single Message
resource://message/{id}?project=<path>Thread
resource://thread/{thread_id}?project=<path>&include_bodies=true| Parameter | Required | Default |
|---|---|---|
project | Yes | — |
include_bodies | No | true |
limit | No | 100 |
---
Agents & Projects
List Agents in Project
resource://agents/{project_key}Returns all registered agents with their current task descriptions.
Project Details
resource://project/{slug}All Projects
resource://projects---
File Reservations
Active Reservations
resource://file_reservations/{slug}?active_only=true| Parameter | Default |
|---|---|
active_only | true |
File Reservation by ID
resource://file_reservation/{id}?project=<path>---
Views (Filtered Queries)
Urgent Unread
resource://views/urgent-unread/{agent}?project=<path>High/urgent messages not yet read.
ACK Required
resource://views/ack-required/{agent}?project=<path>Messages with ack_required=true awaiting acknowledgment.
ACK Overdue
resource://views/ack-overdue/{agent}?project=<path>&ttl_minutes=30ACK-required messages older than TTL without acknowledgment.
---
Tooling Metadata
Tool Directory
resource://tooling/directoryGrouped tool clusters with playbooks and descriptions.
Argument Schemas
resource://tooling/schemasParameter hints for all tools.
Usage Metrics
resource://tooling/metricsCall counts and error rates.
---
Identity (Worktree Mode)
resource://identity/{path}For git worktree deployments, resolves agent identity from path markers.
---
Example Usage
# In your agent code, read resources via MCP
inbox = await mcp.read_resource("resource://inbox/GreenCastle?project=/abs/path&limit=5")
thread = await mcp.read_resource("resource://thread/bd-123?project=/abs/path")
agents = await mcp.read_resource("resource://agents//abs/path/project")---
Notes
- Resources are read-only; use tools for mutations
- All project paths must be absolute
- Resources return JSON by default
- Missing resources return empty arrays/objects, not errors
Agent Mail Tools Reference
Table of Contents
---
Project & Identity
ensure_project
Create/ensure project exists.
ensure_project(human_key="/abs/path/to/project")Returns: {id, slug, human_key, created_at}
register_agent
Register identity in project.
register_agent(
project_key="/abs/path/project",
program="codex-cli",
model="YOUR_MODEL",
name="GreenCastle", # Optional, auto-generates if omitted
task_description="Auth work"
)Agent naming rules:
- MUST be adjective+noun: GreenCastle, BlueLake, RedBear
- NOT descriptive: BackendHarmonizer, DatabaseMigrator (invalid)
- Best practice: Omit
namefor auto-generation
Returns: {id, name, program, model, task_description, inception_ts, last_active_ts}
whois
Get agent profile with recent commits.
whois(
project_key="/abs/path/project",
agent_name="GreenCastle",
include_recent_commits=true,
commit_limit=5
)create_agent_identity
Always create new unique agent (never updates existing).
create_agent_identity(
project_key="/abs/path/project",
program="codex-cli",
model="YOUR_MODEL",
name_hint="GreenCastle" # Optional
)---
Messaging
send_message
Send message to one or more recipients.
send_message(
project_key="/abs/path/project",
sender_name="GreenCastle",
to=["BlueLake"],
subject="API review needed",
body_md="Please check the auth endpoints...",
cc=["RedBear"], # Optional
bcc=["Overseer"], # Optional
thread_id="bd-123", # Optional, for threading
importance="normal", # low|normal|high|urgent
ack_required=true # Request acknowledgment
)reply_message
Reply preserving thread.
reply_message(
project_key="/abs/path/project",
message_id=1234,
sender_name="BlueLake",
body_md="Looks good, one suggestion...",
to=["GreenCastle"], # Optional, defaults to original sender
cc=["RedBear"], # Optional
subject_prefix="Re:" # Default
)fetch_inbox
Get messages for agent.
fetch_inbox(
project_key="/abs/path/project",
agent_name="GreenCastle",
limit=20,
since_ts="2025-01-01T00:00:00Z", # Optional
urgent_only=false,
include_bodies=true
)mark_message_read
Mark message as read.
mark_message_read(
project_key="/abs/path/project",
agent_name="GreenCastle",
message_id=1234
)acknowledge_message
Acknowledge receipt (also marks read).
acknowledge_message(
project_key="/abs/path/project",
agent_name="GreenCastle",
message_id=1234
)search_messages
FTS5 full-text search.
search_messages(
project_key="/abs/path/project",
query='"auth module" AND error',
limit=20
)summarize_thread
Extract key points and actions.
summarize_thread(
project_key="/abs/path/project",
thread_id="bd-123",
include_examples=true,
llm_mode=true
)---
File Reservations
file_reservation_paths
Reserve files before editing.
file_reservation_paths(
project_key="/abs/path/project",
agent_name="GreenCastle",
paths=["src/auth/**/*.ts", "src/middleware/auth.ts"],
ttl_seconds=3600,
exclusive=true,
reason="bd-123"
)Returns: {granted: [...], conflicts: [...]}
Conflicts are advisory — reservations still granted.
release_file_reservations
Release reservations.
release_file_reservations(
project_key="/abs/path/project",
agent_name="GreenCastle",
paths=["src/auth/**"], # Optional, releases all if omitted
file_reservation_ids=[101] # Optional, by ID
)renew_file_reservations
Extend TTL.
renew_file_reservations(
project_key="/abs/path/project",
agent_name="GreenCastle",
extend_seconds=1800
)force_release_file_reservation
Clear stale reservation from another agent.
force_release_file_reservation(
project_key="/abs/path/project",
agent_name="GreenCastle",
file_reservation_id=101,
note="Agent crashed, clearing stale lock",
notify_previous=true
)---
Contact Management
request_contact
Request permission to message another agent.
request_contact(
project_key="/abs/path/project",
from_agent="GreenCastle",
to_agent="BlueLake",
to_project="/abs/path/other", # Optional, for cross-project
reason="API coordination",
ttl_seconds=604800 # 7 days default
)respond_contact
Accept or deny contact request.
respond_contact(
project_key="/abs/path/project",
to_agent="BlueLake",
from_agent="GreenCastle",
accept=true
)list_contacts
List contact links for agent.
list_contacts(
project_key="/abs/path/project",
agent_name="GreenCastle"
)set_contact_policy
Set contact policy.
set_contact_policy(
project_key="/abs/path/project",
agent_name="GreenCastle",
policy="auto" # open|auto|contacts_only|block_all
)---
Macros
macro_start_session
One-call bootstrap.
macro_start_session(
human_key="/abs/path/project",
program="codex-cli",
model="YOUR_MODEL",
task_description="Auth refactor",
file_reservation_paths=["src/auth/**"],
inbox_limit=10
)Returns: {project, agent, file_reservations, inbox}
macro_prepare_thread
Join existing thread with context.
macro_prepare_thread(
project_key="/abs/path/project",
thread_id="bd-123",
program="codex-cli",
model="YOUR_MODEL",
include_examples=true,
inbox_limit=10
)macro_file_reservation_cycle
Reserve, work, auto-release.
macro_file_reservation_cycle(
project_key="/abs/path/project",
agent_name="GreenCastle",
paths=["src/auth/**"],
ttl_seconds=3600,
auto_release=true
)macro_contact_handshake
Contact setup with optional auto-accept.
macro_contact_handshake(
project_key="/abs/path/project",
requester="GreenCastle",
target="BlueLake",
auto_accept=true,
welcome_subject="Coordination request",
welcome_body="Let's sync on API changes"
)---
Guard Tools
install_precommit_guard
Install git pre-commit hook to enforce file reservations.
install_precommit_guard(
project_key="/abs/path/project",
code_repo_path="/abs/path/project"
)uninstall_precommit_guard
Remove pre-commit guard.
uninstall_precommit_guard(code_repo_path="/abs/path/project")---
Health
health_check
Return server readiness status.
health_check()Returns: {status: "healthy"}
Agent Mail Workflow Patterns
Table of Contents
---
Standard Bead Workflow
The canonical workflow for working on a bead with coordination. BR/beads is the durable bus for status, ownership, priority, dependencies, and completion evidence. Agent Mail is the side channel for file reservations, lane notifications, acknowledgements, and handoff messages.
Steps
1. Bootstrap session
macro_start_session(human_key="/abs/path", program="codex-cli", model="YOUR_MODEL")
2. Pick work
br ready --json → select bd-123
3. Reserve files
file_reservation_paths(
project_key="/abs/path",
agent_name="GreenCastle",
paths=["src/auth/**/*.ts"],
reason="bd-123"
)
4. Announce start
send_message(
project_key="/abs/path",
sender_name="GreenCastle",
to=["BlueLake", "RedBear"], # Other active agents
subject="[bd-123] Starting auth refactor",
body_md="Reserving src/auth/**. Expected 2 hours.",
thread_id="bd-123",
ack_required=true
)
5. Work on bead
- Make changes
- Periodically check inbox
- Reply in thread with progress updates
- Keep durable state/evidence on the bead, not only in mail
6. Complete
br update bd-123 --notes "Validation: npm test, CI run 123, commit abc123"
br close bd-123 --reason "Implemented OAuth flow"
release_file_reservations(project_key="/abs/path", agent_name="GreenCastle")
send_message(
...
subject="[bd-123] Completed",
body_md="OAuth flow implemented. Ready for review."
)If the mail thread and BR disagree, fix BR first. Treat the mail thread as context that may be cited from the bead, not as the work record itself.
One-Writer Rule
Before editing any hot path, acquire an exclusive Agent Mail reservation for the exact directory or file set. If the reservation conflicts, do not write there. Message the holder in the bead thread, split the scope, or wait for the lease to expire. This is the lane boundary that keeps parallel workers from corrupting each other's files.
---
Collaborative Review
When you need another agent to review your work.
Requester
# After completing work
send_message(
project_key="/abs/path",
sender_name="GreenCastle",
to=["BlueLake"],
subject="[bd-123] Review request: Auth module",
body_md="""
## What changed
- Implemented OAuth 2.0 flow
- Added token refresh logic
- Updated middleware
## Files to review
- `src/auth/oauth.ts`
- `src/middleware/auth.ts`
## Testing
- Run `npm test -- --grep auth`
""",
thread_id="bd-123",
importance="high",
ack_required=true
)Reviewer
# Acknowledge receipt
acknowledge_message(project_key="/abs/path", agent_name="BlueLake", message_id=1234)
# After review
reply_message(
project_key="/abs/path",
message_id=1234,
sender_name="BlueLake",
body_md="""
## Review complete
**Approved** with minor suggestions:
1. Line 45: Consider using early return pattern
2. Line 78: Add error handling for token expiry
Tests pass. Good to merge.
"""
)---
Context Handoff
When you need to hand off work to another agent.
Outgoing Agent
# Before losing context or ending session
send_message(
project_key="/abs/path",
sender_name="GreenCastle",
to=["BlueLake"],
subject="[bd-123] Handoff: Auth module",
body_md="""
## Current state
- OAuth flow 80% complete
- Token storage implemented
- Refresh logic TODO
## What's left
1. Implement token refresh (see `src/auth/refresh.ts`)
2. Add error handling for expired tokens
3. Update tests
## Key decisions made
- Using JWT for tokens (not opaque)
- 15-minute access token lifetime
- Refresh via httpOnly cookie
## Files touched
- `src/auth/oauth.ts` (main flow)
- `src/auth/storage.ts` (token storage)
- `src/middleware/auth.ts` (middleware)
## Context I had
- User stories in bd-120, bd-121
- API spec in docs/auth-api.md
""",
thread_id="bd-123",
importance="high",
ack_required=true
)
# Transfer file reservations explicitly or let them expire
release_file_reservations(project_key="/abs/path", agent_name="GreenCastle")Incoming Agent
# Prepare for thread
macro_prepare_thread(
project_key="/abs/path",
thread_id="bd-123",
program="codex-cli",
model="YOUR_MODEL"
)
# Claim reservations
file_reservation_paths(
project_key="/abs/path",
agent_name="BlueLake",
paths=["src/auth/**"],
reason="bd-123 handoff"
)
# Acknowledge
reply_message(
project_key="/abs/path",
message_id=1234,
sender_name="BlueLake",
body_md="Received handoff. Resuming from token refresh. Will update thread with progress."
)---
Conflict Resolution
When file reservation conflicts occur.
Detecting Conflict
file_reservation_paths(
project_key="/abs/path",
agent_name="GreenCastle",
paths=["src/api/routes.ts"]
)
# Returns: {granted: [...], conflicts: [{path: "src/api/routes.ts", holders: ["BlueLake"]}]}Resolution Options
Option A: Wait and retry
# Conflict exists, wait for other agent
send_message(
sender_name="GreenCastle",
to=["BlueLake"],
subject="File access: src/api/routes.ts",
body_md="I need to modify routes.ts for bd-123. How long until you're done?"
)
# Wait for reply, then retry reservationOption B: Coordinate scope
send_message(
sender_name="GreenCastle",
to=["BlueLake"],
subject="Coordinate: src/api/routes.ts",
body_md="""
We both need routes.ts:
- I need to add auth routes (lines 50-100)
- What section do you need?
Can we split the file or take turns?
"""
)Option C: Non-exclusive reservation
# Both agents use shared reservation
file_reservation_paths(
project_key="/abs/path",
agent_name="GreenCastle",
paths=["src/api/routes.ts"],
exclusive=false,
reason="shared: auth routes"
)---
Daily Standup Pattern
For longer-running multi-agent projects.
Broadcast Status
send_message(
project_key="/abs/path",
sender_name="GreenCastle",
to=["BlueLake", "RedBear", "YellowFox"],
subject="Standup: GreenCastle",
body_md="""
## Yesterday
- Completed bd-123 (OAuth flow)
- Started bd-124 (Token refresh)
## Today
- Finish bd-124
- Start bd-125 (Auth middleware)
## Blockers
- Waiting on API spec update from BlueLake
## File reservations
- src/auth/** (until ~3pm)
""",
importance="normal"
)Query Active Work
# Via NTM
ntm locks PROJECT --all-agents
# Via Agent Mail
# Use resource://file_reservations/{slug}SELF-TEST — agent-mail
Purpose: Validate the MCP Agent Mail guidance after updates.
Checklist
1. Health check
- Run the MCP Agent Mail
health_check()tool. - Pass criteria: returns status without error.
2. Core tool presence
- Verify tool schema includes:
macro_start_session,file_reservation_paths,send_message,request_contact,release_file_reservations. - Pass criteria: tools listed in schema.
3. Resource reads
resource://agents/{project_key}resource://inbox/{agent}?project=/abs/path&limit=20resource://thread/{thread_id}?project=/abs/path&include_bodies=trueresource://views/ack-required/{agent}?project=/abs/path- Pass criteria: resources resolve (even if empty lists).
4. Beads integration wording
- Confirm Beads Integration section uses
brcommands (notbd).
Recording
Log timestamps and outputs for each check in the bead notes.
{
"name": "agent-mail",
"skill_api_version": 1,
"form": "A",
"quality_score": 0.92,
"sections": [
{ "id": "title", "title": "Using MCP Agent Mail", "type": "intro", "priority": "required" },
{ "id": "boundary", "title": "Coordination Boundary", "type": "overview", "priority": "required" },
{ "id": "when-to-use", "title": "When to Use What", "type": "table", "priority": "required" },
{ "id": "bootstrap", "title": "Session Bootstrap", "type": "procedure", "priority": "required" },
{ "id": "core-ops", "title": "Core Operations", "type": "table", "priority": "required" },
{ "id": "reservations", "title": "File Reservations", "type": "procedure", "priority": "required" },
{ "id": "beads", "title": "Beads Integration", "type": "procedure", "priority": "required" },
{ "id": "troubleshoot", "title": "Quick Troubleshooting", "type": "table", "priority": "standard" },
{ "id": "identity", "title": "Agent Identity", "type": "procedure", "priority": "standard" },
{ "id": "overseer", "title": "Human Overseer", "type": "procedure", "priority": "standard" },
{ "id": "guard", "title": "Pre-Commit Guard", "type": "procedure", "priority": "standard" },
{ "id": "references", "title": "References", "type": "routing", "priority": "required" },
{ "id": "validation", "title": "Validation", "type": "contract", "priority": "required" }
],
"references": [
{ "file": "references/TOOLS.md", "topic": "full MCP tool catalog" },
{ "file": "references/WORKFLOWS.md", "topic": "coordination workflow patterns" },
{ "file": "references/RESOURCES.md", "topic": "MCP resource read endpoints" },
{ "file": "references/CROSS-PROJECT.md", "topic": "cross-project contact setup" },
{ "file": "references/RECOVERY.md", "topic": "doctor diagnostics + recovery" },
{ "file": "references/INSTALL.md", "topic": "installation" },
{ "file": "references/FIX-MCP-CONFIG.md", "topic": "repairing MCP server config" },
{ "file": "references/ADVANCED.md", "topic": "product bus, build slots, internals" }
],
"metadata": {
"tier": "execution",
"stability": "stable",
"dependencies": ["beads-br"],
"hexagonal_role": "supporting",
"context_window": "inherit",
"triggers": [
"agent mail",
"file reservation",
"macro_start_session",
"agent coordination",
"edit lease",
"conflict prevention",
"one writer per hot dir",
"send_message",
"agent inbox",
"handoff to another agent"
],
"token_estimate": {
"minimal": 80,
"overview": 350,
"standard": 1700,
"full": 3200
}
},
"output_contract": "Coordinates multi-agent work through Agent Mail's side channel: registers agent identity (macro_start_session), reserves/releases file paths to enforce one-writer-per-hot-dir, threads notifications/acks by bead id, and installs the pre-commit guard — while BR/beads stays the durable source of truth for work state and closure evidence. Returns: project/agent registration, reservation grants/conflicts, thread ids, and health/doctor status.",
"evidence": {
"sources": [
"skills/agent-mail/SKILL.md (verified: macro_start_session, file_reservation_paths, release_file_reservations, send_message/reply_message, fetch_inbox, search FTS5, install_precommit_guard)",
"MCP Agent Mail server health endpoint http://127.0.0.1:8765/health and resource:// read surfaces",
"doctor check/repair CLI (uv run python -m mcp_agent_mail.cli doctor)"
]
}
}
Related skills
FAQ
When do I need Agent Mail?
It is required when two or more lanes or panes share the repo; with only one active writer you should not register or reserve against yourself.
Is Agent Mail the task queue?
No. BR/beads is the durable source of truth for work queue, status, and evidence; Agent Mail only handles file ownership, edit leases, notifications, and acks.