Claude-skill-registry agent-mail

MCP Agent Mail - mail-like coordination layer for coding agents with memorable identities, inbox/outbox, searchable threads, advisory file reservations, pre-commit guards, and human-auditable Git artifacts. The backbone of multi-agent workflows.

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/agent-mail" ~/.claude/skills/majiayu000-claude-skill-registry-agent-mail && rm -rf "$T"
manifest: skills/data/agent-mail/SKILL.md
safety · automated scan (medium risk)
This is a pattern-based risk scan, not a security review. Our crawler flagged:
  • curl piped into shell
  • makes HTTP requests (curl)
  • references API keys
Always read a skill's source content before installing. Patterns alone don't mean the skill is malicious — but they warrant attention.
source content

MCP Agent Mail

A mail-like coordination layer for coding agents, exposed as an HTTP-only FastMCP server. Gives agents memorable identities, an inbox/outbox, searchable message history, and voluntary file reservation "leases" to avoid stepping on each other.

Think of it as asynchronous email + directory + change-intent signaling for your agents, backed by Git (for human-auditable artifacts) and SQLite (for indexing and queries).

Why Agent Mail Exists

Modern projects often run multiple coding agents at once. Without coordination, agents:

  • Overwrite each other's edits or panic on unexpected diffs
  • Miss critical context from parallel workstreams
  • Require humans to "liaison" messages across tools

Agent Mail provides:

  • Identities: Memorable adjective+noun names (e.g., "GreenCastle", "BlueLake")
  • Messaging: GitHub-Flavored Markdown with threading, importance levels, and acknowledgments
  • File Reservations: Advisory leases on files/globs to signal editing intent
  • Search: FTS5 full-text search across message history
  • Audit Trail: Every message and reservation is committed to Git

Starting the Server

# Quick start (alias added during installation)
am

# Or manually
cd ~/projects/mcp_agent_mail && ./scripts/run_server_with_token.sh

# Check server health
curl http://127.0.0.1:8765/health/liveness

Default:

http://127.0.0.1:8765
. Change port with
uv run python -m mcp_agent_mail.cli config set-port 9000
.


Critical Concept: project_key

The

project_key
is the absolute path to your working directory. This is the canonical identifier for a project.

# Two agents in the SAME directory = SAME project
Agent A in /data/projects/backend → project_key="/data/projects/backend"
Agent B in /data/projects/backend → project_key="/data/projects/backend"
# They share the same mailbox, file reservations, and coordination

# Two agents in DIFFERENT directories = DIFFERENT projects
Agent A in /data/projects/backend  → project_key="/data/projects/backend"
Agent B in /data/projects/frontend → project_key="/data/projects/frontend"
# They need explicit contact requests to message each other

Macros vs Granular Tools

Prefer macros when you want speed or are on a smaller model:

MacroWhat It Does
macro_start_session
Ensures project → registers agent → optional file reservations → fetches inbox
macro_prepare_thread
Registers agent → summarizes thread → fetches inbox context
macro_file_reservation_cycle
Reserves paths → optional auto-release after work
macro_contact_handshake
Requests contact → auto-accepts → sends welcome message

Use granular tools when you need explicit control over each step.


MCP Tools Reference

Health & Discovery

ToolSignatureReturns
health_check
()
{status, environment, http_host, http_port, database_url}

Project & Agent Management

ToolSignatureReturns
ensure_project
(human_key: str)
{id, slug, human_key, created_at}
register_agent
(project_key, program, model, name?, task_description?, attachments_policy?)
Agent profile
create_agent_identity
(project_key, program, model, name_hint?, task_description?, attachments_policy?)
Agent profile (always creates new)
whois
(project_key, agent_name, include_recent_commits?, commit_limit?)
Enriched agent profile

Agent naming: Names must be adjective+noun (e.g., "GreenCastle", "BlueLake"). If invalid, the server auto-generates one (mode:

coerce
).

Messaging

ToolSignatureReturns
send_message
(project_key, sender_name, to[], subject, body_md, cc?, bcc?, attachment_paths?, convert_images?, importance?, ack_required?, thread_id?, auto_contact_if_blocked?)
{deliveries, count, attachments?}
reply_message
(project_key, message_id, sender_name, body_md, to?, cc?, bcc?, subject_prefix?)
{thread_id, reply_to, deliveries, count}
fetch_inbox
(project_key, agent_name, limit?, urgent_only?, include_bodies?, since_ts?)
list[message]
mark_message_read
(project_key, agent_name, message_id)
{message_id, read, read_at}
acknowledge_message
(project_key, agent_name, message_id)
{message_id, acknowledged, acknowledged_at, read_at}
search_messages
(project_key, query, limit?)
list[message]
summarize_thread
(project_key, thread_id, include_examples?, llm_mode?, llm_model?, per_thread_limit?)
{thread_id, summary, examples}

Importance levels:

low
,
normal
,
high
,
urgent

Contact Policies

ToolSignatureReturns
request_contact
(project_key, from_agent, to_agent, to_project?, reason?, ttl_seconds?)
Contact link
respond_contact
(project_key, to_agent, from_agent, accept, from_project?, ttl_seconds?)
Contact link
list_contacts
(project_key, agent_name)
list[contact]
set_contact_policy
(project_key, agent_name, policy)
Agent profile

Policies:

open
,
auto
(default),
contacts_only
,
block_all

File Reservations

ToolSignatureReturns
file_reservation_paths
(project_key, agent_name, paths[], ttl_seconds?, exclusive?, reason?)
{granted[], conflicts[]}
release_file_reservations
(project_key, agent_name, paths?, file_reservation_ids?)
{released, released_at}
renew_file_reservations
(project_key, agent_name, extend_seconds?, paths?, file_reservation_ids?)
{renewed, file_reservations[]}
force_release_file_reservation
(project_key, agent_name, file_reservation_id, notify_previous?, note?)
{released, released_at, reservation}

File reservations are advisory but auditable. The optional pre-commit guard blocks commits that conflict with others' active exclusive reservations.

Pre-Commit Guard

ToolSignatureReturns
install_precommit_guard
(project_key, code_repo_path)
{hook}
uninstall_precommit_guard
(code_repo_path)
{removed}

Session Macros

ToolSignatureReturns
macro_start_session
(human_key, program, model, task_description?, agent_name?, file_reservation_paths?, file_reservation_reason?, file_reservation_ttl_seconds?, inbox_limit?)
{project, agent, file_reservations, inbox}
macro_prepare_thread
(project_key, thread_id, program, model, agent_name?, task_description?, register_if_missing?, include_examples?, inbox_limit?, include_inbox_bodies?, llm_mode?, llm_model?)
{project, agent, thread, inbox}
macro_file_reservation_cycle
(project_key, agent_name, paths[], ttl_seconds?, exclusive?, reason?, auto_release?)
{file_reservations, released}
macro_contact_handshake
(project_key, requester, target, to_project?, reason?, ttl_seconds?, auto_accept?, welcome_subject?, welcome_body?)
{request, response, welcome_message}

MCP Resources Reference

URIParamsReturns
resource://config/environment
Server configuration
resource://tooling/directory
Tool clusters + workflow playbooks
resource://tooling/schemas
Argument hints for all tools
resource://tooling/metrics
Call/error counts per tool
resource://projects
All projects
resource://project/{slug}
slugProject + agents
resource://inbox/{agent}
?project=<abs-path>&limit=20&since_ts=...&urgent_only=...&include_bodies=...
Inbox listing
resource://outbox/{agent}
?project=<abs-path>&limit=20
Sent messages
resource://thread/{thread_id}
?project=<abs-path>&include_bodies=true
Thread listing
resource://message/{id}
?project=<abs-path>
Single message
resource://file_reservations/{slug}
?active_only=true
File reservations + staleness metadata
resource://views/urgent-unread/{agent}
?project=<abs-path>
High/urgent unread messages
resource://views/ack-required/{agent}
?project=<abs-path>
Pending acknowledgements
resource://views/ack-overdue/{agent}
?project=<abs-path>&ttl_minutes=30
Overdue acknowledgements

Example Agent Workflow

# 1. Start session (one call does everything)
result = macro_start_session(
    human_key="/data/projects/backend",
    program="claude-code",
    model="opus-4.5",
    task_description="Implementing auth module"
)
agent_name = result["agent"]["name"]  # e.g., "GreenCastle"
project_key = result["project"]["human_key"]

# 2. Check inbox for context
for msg in result["inbox"]:
    if msg["importance"] in ["high", "urgent"]:
        acknowledge_message(project_key, agent_name, msg["id"])

# 3. Reserve files before editing
file_reservation_paths(
    project_key, agent_name,
    paths=["src/auth/**/*.ts"],
    ttl_seconds=3600,
    exclusive=True,
    reason="bd-123"  # Link to Beads task
)

# 4. Do work, send progress updates
send_message(
    project_key, agent_name,
    to=["BlueLake"],
    subject="[bd-123] Auth module progress",
    body_md="Completed login flow. Starting session management.",
    thread_id="bd-123"
)

# 5. Release reservations when done
release_file_reservations(project_key, agent_name)

Cross-Project Coordination

When repos are separate (e.g., frontend and backend):

Option A: Single project bus

  • Register both agents under the same
    project_key
  • Keep reservation patterns specific:
    frontend/**
    vs
    backend/**

Option B: Separate projects with contact links

# Backend agent requests contact
request_contact(
    project_key="/data/projects/backend",
    from_agent="GreenCastle",
    to_agent="BlueLake",
    to_project="/data/projects/frontend",
    reason="API contract coordination"
)

# Frontend agent accepts
respond_contact(
    project_key="/data/projects/frontend",
    to_agent="BlueLake",
    from_agent="GreenCastle",
    from_project="/data/projects/backend",
    accept=True
)

# Now they can message each other

Pre-Commit Guard

The optional pre-commit guard blocks commits that touch files reserved by other agents:

# Install guard into your code repo
mcp-agent-mail guard install /data/projects/backend /data/projects/backend

# Check guard status
mcp-agent-mail guard status /data/projects/backend

# Uninstall
mcp-agent-mail guard uninstall /data/projects/backend

Requirements:

  • Set
    AGENT_NAME
    environment variable so the guard knows who you are
  • File reservations must be active (not expired)

Bypass (use sparingly):

AGENT_MAIL_BYPASS=1 git commit -m "..."
# Or: AGENT_MAIL_GUARD_MODE=warn (advisory mode, doesn't block)

Build Slots (Long-Running Tasks)

For dev servers, watchers, or builds that hold resources:

# Acquire a slot
acquire_build_slot(project_key, agent_name, "frontend-build", ttl_seconds=3600, exclusive=True)

# Renew during long runs
renew_build_slot(project_key, agent_name, "frontend-build", extend_seconds=1800)

# Release when done
release_build_slot(project_key, agent_name, "frontend-build")

CLI helper:

mcp-agent-mail am-run frontend-build -- npm run dev

Product Bus (Multi-Repo Coordination)

Group multiple repos under a single "product" for cross-project search and inbox:

# Create a product
mcp-agent-mail products ensure MyProduct --name "My Product"

# Link repos
mcp-agent-mail products link MyProduct /data/projects/backend
mcp-agent-mail products link MyProduct /data/projects/frontend

# Product-wide search
mcp-agent-mail products search MyProduct "urgent AND deploy" --limit 50

# Product-wide inbox
mcp-agent-mail products inbox MyProduct BlueLake --urgent-only

# Product-wide thread summary
mcp-agent-mail products summarize-thread MyProduct "bd-123"

Web UI (Human-Facing)

Browse projects, agents, inboxes, and messages at

http://127.0.0.1:8765/mail
:

  • Unified Inbox: Recent messages across all projects
  • Project Overview: Search, agents, file reservations
  • Agent Inbox: Messages for a specific agent
  • Message Detail: Full body, attachments, thread context
  • Human Overseer: Send high-priority messages to agents from the web

Human Overseer

Click "Send Message" in any project view to send messages as

HumanOverseer
:

  • Messages include a preamble instructing agents to pause and prioritize
  • Bypasses contact policies
  • Marked as
    high
    importance automatically

Static Mailbox Export

Export mailboxes as portable, read-only HTML bundles:

# Interactive wizard (easiest)
uv run python -m mcp_agent_mail.cli share wizard

# Manual export
uv run python -m mcp_agent_mail.cli share export --output ./bundle

# Preview locally
uv run python -m mcp_agent_mail.cli share preview ./bundle --port 9000

# Verify integrity
uv run python -m mcp_agent_mail.cli share verify ./bundle

Features:

  • Self-contained HTML viewer with FTS5 search
  • Ed25519 signing for tamper-evident distribution
  • Optional age encryption for confidential archives
  • Deploy to GitHub Pages or Cloudflare Pages

Integration with Beads

Beads (

bd
) owns task status/priority; Agent Mail owns conversations and audit trails.

Conventions:

  • Use Beads issue ID as Mail
    thread_id
    :
    send_message(..., thread_id="bd-123")
  • Prefix subjects:
    [bd-123] Starting auth refactor
  • Include issue ID in file reservation
    reason
    :
    file_reservation_paths(..., reason="bd-123")

Typical flow:

# 1. Pick ready work
bd ready --json

# 2. Reserve files
file_reservation_paths(project_key, agent_name, ["src/**"], reason="bd-123")

# 3. Announce start
send_message(..., thread_id="bd-123", subject="[bd-123] Starting work")

# 4. Complete
bd close bd-123 --reason "Completed"
release_file_reservations(project_key, agent_name)

Search Syntax (FTS5)

"exact phrase"           # Phrase search
prefix*                   # Prefix match
term1 AND term2           # Boolean AND
term1 OR term2            # Boolean OR
term1 NOT term2           # Exclusion
subject:login             # Field-specific
body:"build plan"         # Field-specific phrase

CLI Commands

cd ~/projects/mcp_agent_mail

# Server
uv run python -m mcp_agent_mail.cli serve-http
uv run python -m mcp_agent_mail.cli migrate

# Configuration
uv run python -m mcp_agent_mail.cli config set-port 9000
uv run python -m mcp_agent_mail.cli config show-port

# Projects
uv run python -m mcp_agent_mail.cli list-projects --include-agents

# File Reservations
uv run python -m mcp_agent_mail.cli file_reservations list <project> --active-only
uv run python -m mcp_agent_mail.cli file_reservations soon <project> --minutes 10

# Acknowledgements
uv run python -m mcp_agent_mail.cli acks pending <project> <agent>
uv run python -m mcp_agent_mail.cli acks overdue <project> <agent> --ttl-minutes 30

# Guard
uv run python -m mcp_agent_mail.cli guard install <project_key> <code_repo_path>
uv run python -m mcp_agent_mail.cli guard uninstall <code_repo_path>
uv run python -m mcp_agent_mail.cli guard status <code_repo_path>

# Export
uv run python -m mcp_agent_mail.cli share wizard
uv run python -m mcp_agent_mail.cli share export --output ./bundle
uv run python -m mcp_agent_mail.cli share preview ./bundle

# Archive/Restore
uv run python -m mcp_agent_mail.cli archive save --label nightly
uv run python -m mcp_agent_mail.cli archive list --json
uv run python -m mcp_agent_mail.cli archive restore <file>.zip --force

# DANGER: Full reset
uv run python -m mcp_agent_mail.cli clear-and-reset-everything --force

Configuration Variables

VariableDefaultDescription
STORAGE_ROOT
~/.mcp_agent_mail_git_mailbox_repo
Root for project repos and SQLite
HTTP_HOST
127.0.0.1
Bind host
HTTP_PORT
8765
Bind port
HTTP_BEARER_TOKEN
Static bearer token for auth
HTTP_ALLOW_LOCALHOST_UNAUTHENTICATED
true
Allow localhost without auth
LLM_ENABLED
true
Enable LLM for summaries
LLM_DEFAULT_MODEL
gpt-5-mini
Default model for summaries
CONTACT_ENFORCEMENT_ENABLED
true
Enforce contact policies
FILE_RESERVATIONS_ENFORCEMENT_ENABLED
true
Block messages on conflicts
AGENT_NAME_ENFORCEMENT_MODE
coerce
strict
,
coerce
,
always_auto

Troubleshooting

IssueSolution
"sender_name not registered"Call
register_agent
or
macro_start_session
first
"from_agent not registered"Check
project_key
matches the agent's project
"FILE_RESERVATION_CONFLICT"Adjust patterns, wait for expiry, or use non-exclusive
Pre-commit blocks commitsSet
AGENT_NAME
, or use
AGENT_MAIL_BYPASS=1
Inbox empty but messages existCheck
since_ts
,
limit
; verify recipient names match exactly

Ready-to-Paste AGENTS.md Blurb

## MCP Agent Mail — coordination for multi-agent workflows

**What it is:** A mail-like layer for coding agents with identities, inbox/outbox,
searchable threads, and advisory file reservations. Human-auditable artifacts in Git.

**How to use:**
1. Register identity: `ensure_project` + `register_agent` (or `macro_start_session`)
2. Reserve files: `file_reservation_paths(project_key, agent_name, ["src/**"], exclusive=true)`
3. Communicate: `send_message(..., thread_id="bd-123")`, `fetch_inbox`, `acknowledge_message`
4. Fast reads: `resource://inbox/{agent}?project=<abs-path>&limit=20`

**Macros vs granular:**
- Prefer macros for speed: `macro_start_session`, `macro_prepare_thread`
- Use granular for control: `register_agent`, `file_reservation_paths`, `send_message`

**Common pitfalls:**
- "from_agent not registered" → call `register_agent` first
- "FILE_RESERVATION_CONFLICT" → adjust patterns or wait for expiry

Installation

curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/mcp_agent_mail/main/scripts/install.sh?$(date +%s)" | bash -s -- --yes