MCP Agent Mail
Superseded by mcp_agent_mail_rust. This Python version is no longer maintained; use the Rust version for new installs.
"It's like gmail for your coding agents!"
A mail-like coordination layer for coding agents, exposed as an HTTP-only FastMCP server. It 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).
Status: Under active development. The design is captured in detail in docs/planning/project_idea_and_guide.md (start with the original prompt at the top of that file).
Why this exists
Modern projects often run multiple coding agents at once (backend, frontend, scripts, infra). Without a shared coordination fabric, agents:
- Overwrite each other's edits or panic on unexpected diffs
- Miss critical context from parallel workstreams
- Require humans to "liaison" messages across tools and teams
- Register a temporary-but-persistent identity (e.g., GreenCastle)
- Send/receive GitHub-Flavored Markdown messages with images
- Search, summarize, and thread conversations
- Declare advisory file reservations (leases) on files/globs to signal intent
- Inspect a directory of active agents, programs/models, and activity
From Idea Spark to Shipping Swarm
If a blank repo feels daunting, follow the field-tested workflow we documented in docs/planning/project_idea_and_guide.md (“Appendix: From Blank Repo to Coordinated Swarm”):
- Ideate fast: Write a scrappy email-style blurb about the problem, desired UX, and any must-have stack picks (≈15 minutes).
- Promote it to a plan: Feed that blurb to GPT-5 Pro (and optionally Grok4 Heavy / Opus 4.1) until you get a granular Markdown plan, then iterate on the plan file while it’s still cheap to change. The Markdown Web Browser sample plan shows the level of detail to aim for.
- Codify the rules: Clone a tuned
AGENTS.md, add any tech-specific best-practice guides, and let Codex scaffold the repo plus Beads tasks straight from the plan. - Spin up the swarm: Launch multiple Codex panes (or any agent mix), register each identity with Agent Mail, and have them acknowledge
AGENTS.md, the plan document, and the Beads backlog before touching code. - Keep everyone fed: Reuse the canned instruction cadence from the tweet thread or, better yet, let the commercial Companion app’s Message Stacks broadcast those prompts automatically so you never hand-feed panes again.
Productivity Math & Automation Loop
One disciplined hour of GPT-5 Codex—when it isn’t waiting on human prompts—often produces 10–20 “human hours” of work because the agents reason and type at machine speed. Agent Mail multiplies that advantage in two layers:
- Base OSS server: Git-backed mailboxes, advisory file reservations, Typer CLI helpers, and searchable archives keep independent agents aligned without babysitting. Every instruction, lease, and attachment is auditable.
- Companion stack (commercial): The iOS app + host automation can provision, pair, and steer heterogeneous fleets (Claude Code, Codex, Gemini CLI, Factory Droid, etc.) from your phone using customizable Message Stacks, Human Overseer broadcasts, Beads awareness, and plan editing tools—no manual tmux choreography required. The automation closes the loop by scheduling prompts, honoring Limited Mode, and enforcing Double-Arm confirmations for destructive work.
TLDR Quickstart
One-line installer
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/mcp_agent_mail/main/scripts/install.sh?$(date +%s)" | bash -s -- --yes
What this does:
- Installs uv if missing and updates your PATH for this session
- Installs jq if missing (needed for safe config merging; auto-detects your package manager)
- Creates a Python 3.14 virtual environment and installs dependencies with uv
- Runs the auto-detect integration to wire up supported agent tools
- Starts the MCP HTTP server on port 8765 and prints a masked bearer token
- Creates helper scripts under
scripts/(includingrun_server_with_token.sh) - Adds an
amshell alias to your.zshrcor.bashrcfor quick server startup (just typeamin a new terminal!) - Installs Beads Rust (
br), a Rust reimplementation of the Beads task tracker, and creates abdshell alias pointing tobrfor backwards compatibility. This replaces any existingbd(Go) installation. Pass--skip-beadsto opt out. See beads_rust for details on CLI differences. - Installs/updates the Beads Viewer
bvTUI for interactive task browsing and AI-friendly robot commands (pass--skip-bvto opt out) - Prints a short on-exit summary of each setup step so you immediately know what changed
--dir , --project-dir , --no-start, --start-only, --port , or --token .
Already have Beads or Beads Viewer installed? Append --skip-beads and/or --skip-bv to bypass automatic installation.
Important: Beads Rust (br) Replaces Beads Go (bd)
The installer automatically replaces bd (the original Go-based Beads CLI) with br (Beads Rust):
bris the actively maintained version. Beads Rust is a complete reimplementation with ongoing development, while the original Go version is no longer actively maintained.
- Existing
bdusers get automatic aliasing. The installer creates a shell alias so thatbdcommands continue to work by redirecting tobr. Your existing workflows and muscle memory are preserved.
- A migration skill is installed for agents. AI coding agents receive a
bd-br-migrationskill that helps them adapt to any CLI differences between the two implementations.
- Same data format, compatible workflows. Both implementations use the same
.beads/issues.jsonlformat, so your existing Beads data remains fully compatible.
--skip-beads to the installer. See the beads_rust repository for detailed documentation on CLI differences.
Starting the server in the future
After installation, you can start the MCP Agent Mail server from anywhere by simply typing:
am
That's it! The am alias (added to your .zshrc or .bashrc during installation) automatically:
- Changes to the MCP Agent Mail directory
- Runs the server startup script (which uses
uv runto handle the virtual environment) - Loads your saved bearer token from
.envand starts the HTTP server
source ~/.zshrc (or source ~/.bashrc) to load the alias.
Port conflicts? Use --port to specify a different port (default: 8765):
Install with custom port:
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/mcp_agent_mail/main/scripts/install.sh?$(date +%s)" | bash -s -- --port 9000 --yes
Or use the CLI command after installation: uv run python -m mcp_agent_mail.cli config set-port 9000
### If you want to do it yourself
Clone the repo, set up and install with uv in a python 3.14 venv (install uv if you don't have it already), and then run scripts/automatically_detect_all_installed_coding_agents_and_install_mcp_agent_mail_in_all.sh. This will automatically set things up for your various installed coding agent tools and start the MCP server on port 8765. If you want to run the MCP server again in the future, simply run scripts/run_server_with_token.sh:
Install uv (if you don't have it already):
bash
curl -LsSf https://astral.sh/uv/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"
Clone the repo
git clone https://github.com/Dicklesworthstone/mcp_agent_mail cd mcp_agent_mailCreate a Python 3.14 virtual environment and install dependencies
Note: If you have an older uv version, run uv self update first
uv python install 3.14
uv venv -p 3.14
source .venv/bin/activate
uv sync
Detect installed coding agents, integrate, and start the MCP server on port 8765
scripts/automatically_detect_all_installed_coding_agents_and_install_mcp_agent_mail_in_all.shLater, to run the MCP server again with the same token
scripts/run_server_with_token.shNow, simply launch Codex-CLI or Claude Code or other agent tools in other consoles; they should have the mail tool available. See below for a ready-made chunk of text you can add to the end of your existing AGENTS.md or CLAUDE.md files to help your agents better utilize the new tools.
Change port after installation
uv run python -m mcp_agent_mail.cli config set-port 9000## Ready-Made Blurb to Add to Your AGENTS.md or CLAUDE.md Files:
<!-- BEGIN_AGENT_MAIL_SNIPPET -->
MCP Agent Mail: coordination for multi-agent workflows
What it is
- A mail-like layer that lets coding agents coordinate asynchronously via MCP tools and resources.
- Provides identities, inbox/outbox, searchable threads, and advisory file reservations, with human-auditable artifacts in Git.
- Prevents agents from stepping on each other with explicit file reservations (leases) for files/globs.
- Keeps communication out of your token budget by storing messages in a per-project archive.
- Offers quick reads (
resource://inbox/...,resource://thread/...) and macros that bundle common flows.
ensure_project, then register_agent using this repo's absolute path as project_key.
- Reserve files before you edit: file_reservation_paths(project_key, agent_name, ["src/**"], ttl_seconds=3600, exclusive=true) to signal intent and avoid conflict.
- Communicate with threads: use send_message(..., thread_id="FEAT-123"); check inbox with fetch_inbox and acknowledge with acknowledge_message.
- Read fast: resource://inbox/{Agent}?project=&limit=20&agent_token= or resource://thread/{id}?project=&agent=&agent_token=&include_bodies=true unless the current MCP session already authenticated as that agent.
- Tip: set AGENT_NAME in your environment so the pre-commit guard can block commits that conflict with others' active exclusive file reservations.
2) Across different repos in one project (e.g., Next.js frontend + FastAPI backend)
- Option A (single project bus): register both sides under the same project_key (shared key/path). Keep reservation patterns specific (e.g., frontend/ vs backend/).
- Option B (separate projects): each repo has its own project_key; use macro_contact_handshake or request_contact/respond_contact to link agents, then message directly. Keep a shared thread_id (e.g., ticket key) across repos for clean summaries/audits.
Macros vs granular tools
- Prefer macros when you want speed or are on a smaller model:
macro_start_session,macro_prepare_thread,macro_file_reservation_cycle,macro_contact_handshake. - Use granular tools when you need control:
register_agent,file_reservation_paths,send_message,fetch_inbox,acknowledge_message.
- "from_agent not registered": always
register_agentin the correctproject_keyfirst. - "FILE_RESERVATION_CONFLICT": adjust patterns, wait for expiry, or use a non-exclusive reservation when appropriate.
- Auth errors: if JWT+JWKS is enabled, include a bearer token with a
kidthat matches server JWKS; static bearer is used only when JWT is disabled.
<!-- END_AGENT_MAIL_SNIPPET -->
Integrating with Beads (dependency-aware task planning)
Beads is a lightweight task planner that complements Agent Mail by keeping status and dependencies in one place while Mail handles messaging, file reservations, and audit trails.
Note on implementations: The MCP Agent Mail installer installs Beads Rust (br), a Rust reimplementation, and creates a bd alias for backwards compatibility. The original Go implementation is at steveyegge/beads. Both share the same data format (.beads/issues.jsonl) but have some CLI differences. Use --skip-beads during installation if you prefer to manage this yourself.
Highlights:
- Beads owns task prioritization; Agent Mail carries the conversations and artifacts.
- Shared identifiers (e.g.,
bd-123) keep Beads issues, Mail threads, and commits aligned.
- The
br CLI (aliased as bd) provides similar functionality to the original with some enhancements.
Copy/paste blurb for agent-facing docs (leave as-is for reuse):
<!-- BEGIN_BEADS_SNIPPET -->
Integrating with Beads (dependency-aware task planning)
Beads provides a lightweight, dependency-aware issue database and a CLI (bd) for selecting "ready work," setting priorities, and tracking status. It complements MCP Agent Mail's messaging, audit trail, and file-reservation signals. Project: steveyegge/beads
Recommended conventions
- Single source of truth: Use Beads for task status/priority/dependencies; use Agent Mail for conversation, decisions, and attachments (audit).
- Shared identifiers: Use the Beads issue id (e.g.,
bd-123) as the Mailthread_idand prefix message subjects with[bd-123]. - Reservations: When starting a
bd-###task, callfile_reservation_paths(...)for the affected paths; include the issue id in thereasonand release on completion.
bd ready --json → choose one item (highest priority, no blockers)
2) Reserve edit surface (Mail)
- file_reservation_paths(project_key, agent_name, ["src/**"], ttl_seconds=3600, exclusive=true, reason="bd-123")
3) Announce start (Mail)
- send_message(..., thread_id="bd-123", subject="[bd-123] Start: ", ack_required=true)
4) Work and update
- Reply in-thread with progress and attach artifacts/images; keep the discussion in one thread per issue id
5) Complete and release
- bd close bd-123 --reason "Completed" (Beads is status authority)
- release_file_reservations(project_key, agent_name, paths=["src/**"])
- Final Mail reply: [bd-123] Completed with summary and links
Mapping cheat-sheet
- Mail
thread_id↔bd-### - Mail subject:
[bd-###] … - File reservation
reason:bd-### - Commit messages (optional): include
bd-###for traceability
- On
bd update --status blocked, send a high-importance Mail message in threadbd-###describing the blocker. - On Mail "ACK overdue" for a critical decision, add a Beads label (e.g.,
needs-ack) or bump priority to surface it inbd ready.
- Don't create or manage tasks in Mail; treat Beads as the single task queue.
- Always include
bd-###in messagethread_idto avoid ID drift across tools.
<!-- END_BEADS_SNIPPET -->
Prefer automation? Run uv run python -m mcp_agent_mail.cli docs insert-blurbs to scan your code directories for AGENTS.md/CLAUDE.md files and append the latest Agent Mail + Beads snippets with per-project confirmation. The installer also offers to launch this helper right after setup so you can take care of onboarding docs immediately.
Beads Viewer (bv) — AI-Friendly Task Analysis
The Beads Viewer (bv) is a fast terminal UI for Beads projects that also provides robot flags designed specifically for AI agent integration. Project: Dicklesworthstone/beads_viewer
Why bv for Agents?
While bd (Beads CLI) handles task CRUD operations, bv provides precomputed graph analytics that help agents make intelligent prioritization decisions:
- PageRank scores: Identify high-impact tasks that unblock the most downstream work
- Critical path analysis: Find the longest dependency chain to completion
- Cycle detection: Spot circular dependencies before they cause deadlocks
- Parallel track planning: Determine which tasks can run concurrently
Instead of agents parsing .beads/issues.jsonl directly or attempting to compute graph metrics (risking hallucinated results), they can call bv's deterministic robot flags and get JSON output they can trust. Legacy .beads/beads.jsonl is deprecated in this repo.
Robot Flags for AI Integration
| Flag | Output | Agent Use Case |
|------|--------|----------------|
| bv --robot-help | All AI-facing commands | Discovery / capability check |
| bv --robot-insights | PageRank, betweenness, HITS, critical path, cycles | Quick triage: "What's most impactful?" |
| bv --robot-plan | Parallel tracks, items per track, unblocks lists | Execution planning: "What can run in parallel?" |
| bv --robot-priority | Priority recommendations with reasoning + confidence | Task selection: "What should I work on next?" |
| bv --robot-recipes | Available filter presets (actionable, blocked, etc.) | Workflow setup: "Show me ready work" |
| bv --robot-diff --diff-since <ref> | Changes since commit/date, new/closed items, cycles | Progress tracking: "What changed?" |
Example: Agent Task Selection Workflow
bash
1. Get priority recommendations with reasoning
bv --robot-priorityReturns JSON with ranked tasks, impact scores, and confidence levels
2. Check what completing a task would unblock
bv --robot-planReturns parallel tracks showing dependency chains
3. After completing work, check what changed
bv --robot-diff --diff-since "1 hour ago"Returns new items, closed items, cycle changes
### When to Use bv vs bd
| Tool | Best For |
|------|----------|
| bd | Creating, updating, closing tasks; bd ready for simple "what's next" |
| bv | Graph analysis, impact assessment, parallel planning, change tracking |
Rule of thumb: Use bd for task operations, use bv for task intelligence.
Integration with Agent Mail
Combine bv insights with Agent Mail coordination:
- Agent A runs
bv --robot-priority → identifies bd-42 as highest-impact
- Agent A reserves files:
file_reservation_paths(..., reason="bd-42")
- Agent A announces:
send_message(..., thread_id="bd-42", subject="[bd-42] Starting high-impact refactor")
- Other agents see the reservation and Mail announcement, pick different tasks
- Agent A completes, runs
bv --robot-diff to report downstream unblocks
This creates a feedback loop where graph intelligence drives coordination.
Core ideas (at a glance)
- FastMCP server over Streamable HTTP (primary transport; no SSE). A STDIO transport (
serve-stdio) is also available for direct CLI integration.
- Dual persistence model:
- Human-readable markdown in a per-project Git repo for every canonical message and per-recipient inbox/outbox copy
- SQLite with FTS5 for fast search, directory queries, and file reservations/leases
- "Directory/LDAP" style queries for agents; memorable adjective+noun names
- Advisory file reservations for editing surfaces; optional pre-commit guard
- Resource layer for convenient reads (e.g.,
resource://inbox/{agent})
Typical use cases
- Multiple agents splitting a large refactor across services while staying in sync
- Frontend and backend teams of agents coordinating thread-by-thread
- Protecting critical migrations with exclusive file reservations and a pre-commit guard
- Searching and summarizing long technical discussions as threads evolve
- Discovering and linking related projects (e.g., frontend/backend) through AI-powered suggestions
Workflow FAQ
Do I still need the tmux broadcast script to “feed” every Codex pane?
No. The historical zsh loop from the tweet thread is still handy if you are running the OSS stack by itself, but the AgentMail Companion system now automates that cadence with Message Stacks. Once the companion host services are installed, you queue presets (builder loop, reviewer sweep, test focus, etc.) from the iOS app or CLI and the automation fans those instructions out to every enrolled agent—without touching tmux.
Architecture
mermaid
graph LR
A[Agents]
S[Server]
G[Git repo]
Q[SQLite FTS5]
A -->|HTTP tools/resources| S S -->|writes/reads| G S -->|indexes/queries| Q
subgraph GitTree["Git tree"] GI1[agents/profile.json] GI2[agents/mailboxes/...] GI3[messages/YYYY/\nMM/\nid.md] GI4[file_reservations/\nsha1.json] GA[attachments/xx/\nsha1.webp] end
G --- GI1 G --- GI2 G --- GI3 G --- GI4 G --- GA
## Web UI (human-facing mail viewer)
The server ships a lightweight, server-rendered Web UI for humans. It lets you browse projects, agents, inboxes, single messages, attachments, file reservations, and perform full-text search with FTS5 when available (with an automatic LIKE fallback).
- Where it lives: built into the HTTP server in
mcp_agent_mail.http under the /mail path.
- Who it's for: humans reviewing activity; agents should continue to use the MCP tools/resources API.
Launching the Web UI
Recommended (simple):
bash
scripts/run_server_with_token.sh
then open http://127.0.0.1:8765/mail
Advanced (manual commands):bash
uv run python -m mcp_agent_mail.http --host 127.0.0.1 --port 8765
or:
uv run uvicorn mcp_agent_mail.http:create_app --factory --host 127.0.0.1 --port 8765Auth notes:
- GET pages in the UI are not gated by the RBAC middleware (it classifies POSTed MCP calls only), but if you set a bearer token the separate BearerAuth middleware protects all routes by default.
- For local dev, set
HTTP_ALLOW_LOCALHOST_UNAUTHENTICATED=true (and optionally HTTP_BEARER_TOKEN), so localhost can load the UI without headers.
- Health endpoints are always open at
/health/*.
Routes and what you can do
/mail (Unified inbox + Projects + Related Projects Discovery)
- Shows a unified, reverse-chronological inbox of recent messages across all projects with excerpts, relative timestamps, sender/recipients, and project badges.
- Below the inbox, lists all projects (slug, human name, created time) with sibling suggestions.
- Suggests likely sibling projects when two slugs appear to be parts of the same product (e.g., backend vs. frontend). Suggestions are ranked with heuristics and, when LLM_ENABLED=true, an LLM pass across key docs (README.md, AGENTS.md, etc.).
- Humans can Confirm Link or Dismiss suggestions from the dashboard. Confirmed siblings become highlighted badges but do not automatically authorize cross-project messaging; agents must still establish AgentLink approvals via request_contact/respond_contact.
/mail/projects (Projects index)
- Dedicated projects list view; click a project to drill in.
/mail/{project} (Project overview + search + agents)
- Rich search form with filters:
- Scope: subject/body/both, Order: relevance or time, optional "boost subject".
- Query tokens: supports subject:foo, body:"multi word", quoted phrases, and bare terms.
- Uses FTS5 bm25 scoring when available; otherwise falls back to SQL LIKE on subject/body with your chosen scope.
- Results show subject, sender, created time, thread id, and a highlighted snippet when using FTS.
- Agents panel shows registered agents for the project with a link to each inbox.
- Quick links to File Reservations and Attachments for the project header.
/mail/{project}/inbox/{agent} (Inbox for one agent)
- Reverse-chronological list with subject, sender, created time, importance badge, thread id.
- Pagination (?page=N&limit=M).
/mail/{project}/message/{id} (Message detail)
- Shows subject, sender, created time, importance, recipients (To/Cc/Bcc), thread messages.
- Body rendering:
- If the server pre-converted markdown to HTML, it's sanitized with Bleach (limited tags/attributes, safe CSS via CSSSanitizer) and then displayed.
- Otherwise markdown is rendered client-side with Marked + Prism for code highlighting.
- Attachments are referenced from the message frontmatter (WebP files or inline data URIs).
/mail/{project}/search?q=... (Dedicated search page)
- Same query syntax as the project overview search, with a token "pill" UI for assembling/removing filters.
/mail/{project}/file_reservations (File Reservations list)
- Displays active and historical file reservations (exclusive/shared, path pattern, timestamps, released/expired state).
/mail/{project}/attachments (Messages with attachments)
- Lists messages that contain any attachments, with subject and created time.
/mail/unified-inbox (Cross-project activity)
- Shows recent messages across all projects with thread counts and sender/recipients.
Human Overseer: Sending Messages to Agents
Sometimes a human operator needs to guide or redirect agents directly, whether to handle an urgent issue, provide clarification, or adjust priorities. The Human Overseer feature provides a web-based message composer that lets humans send high-priority messages to any combination of agents in a project.
Access: Click the prominent "Send Message" button (with the Overseer badge) in the header of any project view (/mail/{project}), or navigate directly to /mail/{project}/overseer/compose.
What Makes Overseer Messages Special
- Automatic Preamble: Every message includes a formatted preamble that clearly identifies it as coming from a human operator and instructs agents to:
- Pause current work temporarily
- Prioritize the human's request over existing tasks
- Resume original plans afterward (unless modified by the instructions)
- High Priority: All overseer messages are automatically marked as high importance, ensuring they stand out in agent inboxes.
- Policy Bypass: Overseer messages bypass normal contact policies, so humans can always reach any agent regardless of their contact settings.
- Special Sender Identity: Messages come from a special agent named "HumanOverseer" (automatically created per project) with:
- Program: WebUI
- Model: Human
- Contact Policy: open
The Message Preamble
Every overseer message begins with this preamble (automatically prepended):
🚨 MESSAGE FROM HUMAN OVERSEER 🚨
This message is from a human operator overseeing this project. Please prioritize the instructions below over your current tasks.
You should:
- Temporarily pause your current work
- Complete the request described below
- Resume your original plans afterward (unless modified by these instructions)
[Your message body follows here]
#### Using the Composer
The composer interface provides:
- Recipient Selection: Checkbox grid of all registered agents (with "Select All" / "Clear" shortcuts)
- Subject Line: Required, shown in agent inboxes
- Message Body: GitHub-flavored Markdown editor with preview
- Thread ID (optional): Continue an existing conversation or start a new one
- Preamble Preview: See exactly how your message will appear to agents
Example Use Cases
Urgent Issue:
Subject: Urgent: Stop migration and revert changes
The database migration in PR #453 is causing data corruption in staging.
Please:
- Immediately stop any migration-related work
- Revert commits from the last 2 hours
- Wait for my review before resuming
Priority Adjustment:
Subject: New Priority: Security Vulnerability
A critical security vulnerability was just disclosed in our auth library.
Drop your current tasks and:
- Update
auth-libto version 2.4.1 immediately - Review all usages in src/auth/
- Run the full security test suite
- Report status in thread #892
Clarification:
Subject: Clarification on API design approach
I see you're debating REST vs. GraphQL in thread #234.
Go with REST for now because:
- Our frontend team has more REST experience
- GraphQL adds complexity we don't need yet
- We can always add GraphQL later if needed
#### How Agents See Overseer Messages
When agents check their inbox (via fetch_inbox or resource://inbox/{name}), overseer messages appear like any other message but with:
- Sender:
HumanOverseer
- Importance:
high (displayed prominently)
- Body: Starts with the overseer preamble, followed by the human's message
- Visual cues: In the Web UI, these messages may have special highlighting (future enhancement)
Agents can reply to overseer messages just like any other message, continuing the conversation thread.
Technical Details
- Storage: Overseer messages are stored identically to agent-to-agent messages (Git + SQLite)
- Git History: Fully auditable; message appears in
messages/YYYY/MM/{id}.md with commit history
- Thread Continuity: Can be part of existing threads or start new ones
- No Authentication Bypass: The overseer compose form still requires proper HTTP server authentication (if enabled)
Design Philosophy
The Human Overseer feature is designed to be:
- Explicit: Agents clearly know when guidance comes from a human vs. another agent
- Respectful: Instructions acknowledge agents have existing work and shouldn't just "drop everything" permanently
- Temporary: Agents are told to resume original plans once the human's request is complete
- Flexible: Humans can override this guidance directly in their message body
This creates a clear hierarchy (human → agents) while maintaining the collaborative, respectful tone of the agent communication system.
Related Projects Discovery
The Projects index (/mail) features an AI-powered discovery system that intelligently suggests which projects should be linked together, such as frontend + backend or related microservices.
How Discovery Works
1. Smart Analysis
The system uses multiple signals to identify relationships:
- Pattern matching: Compares project names and paths (e.g., "my-app-frontend" ↔ "my-app-backend")
- AI understanding (when
LLM_ENABLED=true): Reads README.md, AGENTS.md, and other docs to understand each project's purpose and detect natural relationships
- Confidence scoring: Ranks suggestions from 0-100% with clear rationales
2. Beautiful Suggestions
Related projects appear as polished cards on your dashboard with:
- 🎯 Visual confidence indicators showing match strength
- 💬 AI-generated rationales explaining the relationship
- ✅ Confirm Link - accept the suggestion
- ✖️ Dismiss - hide irrelevant matches
3. Quick Navigation
Once confirmed, both projects display interactive badges for instant navigation between related codebases.
Why Suggestions, Not Auto-Linking?
> TL;DR: We keep you in control. Discovery helps you find relationships; explicit approvals control who can actually communicate.
Agent Mail uses agent-centric messaging: every message follows explicit permission chains:
Send Message → Find Recipient → Check AgentLink Approval → Deliver
This design ensures:
- Security: No accidental cross-project message delivery
- Transparency: You always know who can talk to whom
- Audit trails: All communication paths are explicitly approved
Why not auto-link with AI?
If we let an LLM automatically authorize messaging between projects, we'd be:
- ❌ Bypassing contact policies without human oversight
- ❌ Risking message misdelivery to unintended recipients
- ❌ Creating invisible routing paths that are hard to audit
- ❌ Potentially linking ambiguously-named projects incorrectly
Instead, we give you discovery + control:
- ✅ AI suggests likely relationships (safe, read-only analysis)
- ✅ You confirm what makes sense (one click)
- ✅ Agents still use
request_contact / respond_contact for actual messaging permissions
- ✅ Clear separation: discovery ≠ authorization
The Complete Workflow
- System suggests: "These projects look related" (AI analysis)
- You confirm: "Yes, link them" (updates UI badges)
- Agents request: request_contact(from_agent, to_agent, to_project)
- You approve: respond_contact(accept=true)
- Messages flow: Agents can now communicate across projects
Think of it like LinkedIn: The system suggests connections, but only you decide who gets to send messages.
Search syntax (UI)
The UI shares the same parsing as the API's _parse_fts_query:
- Field filters:
subject:login, body:"api key"
- Phrase search:
"build plan"
- Combine terms:
login AND security (FTS)
- Fallback LIKE: scope determines whether subject, body, or both are searched
Prerequisites to see data
The UI reads from the same SQLite + Git artifacts as the MCP tools. To populate content:
1) Ensure a project exists (via tool call or CLI):
- Ensure/create project: ensure_project(human_key)
2) Register one or more agents: register_agent(project_key, program, model, name?)
3) Send messages: send_message(...) (attachments and inline images are supported; images may be converted to WebP).
Once messages exist, visit /mail, click your project, then open an agent inbox or search.
Implementation and dependencies
- Templates live in
src/mcp_agent_mail/templates/ and are rendered by Jinja2.
- Markdown is converted with
markdown2 on the server where possible; HTML is sanitized with Bleach (with CSS sanitizer when available).
- Tailwind CSS, Lucide icons, Alpine.js, Marked, and Prism are loaded via CDN in
base.html for a modern look without a frontend build step.
- All rendering is server-side; there's no SPA router. Pages degrade cleanly without JavaScript.
Security considerations
- HTML sanitization: Only a conservative set of tags/attributes are allowed; CSS is filtered. Links are limited to http/https/mailto/data.
- Auth: Use bearer token or JWT when exposing beyond localhost. For local dev, enable localhost bypass as noted above.
- Rate limiting (optional): Token-bucket limiter can be enabled; UI GET requests are light and unaffected by POST limits.
Troubleshooting the UI
- Blank page or 401 on localhost: Either unset
HTTP_BEARER_TOKEN or set HTTP_ALLOW_LOCALHOST_UNAUTHENTICATED=true.
- No projects listed: Create one with
ensure_project.
- Empty inbox: Verify recipient names match exactly and messages were sent to that agent.
- Search returns nothing: Try simpler terms or the LIKE fallback (toggle scope/body).
Static Mailbox Export (Share & Distribute Archives)
The share command group exports a project’s mailbox into a portable, read‑only bundle that anyone can review in a browser. It’s designed for auditors, stakeholders, or teammates who need to browse threads, search history, or prove delivery timelines without spinning up the full MCP Agent Mail stack.
Why export to static bundles?
Compliance and audit trails: Deliver immutable snapshots of project communication to auditors or compliance officers. The static bundle includes cryptographic signatures for tamper-evident distribution.
Stakeholder review: Share conversation history with product managers, executives, or external consultants who don't need write access. They can browse messages, search threads, and view attachments in their browser without authentication.
Offline access: Create portable archives for air-gapped environments, disaster recovery backups, or situations where internet connectivity is unreliable.
Long-term archival: Preserve project communication in a format that will remain readable decades from now. Static HTML requires no database server, no runtime dependencies, and survives software obsolescence better than proprietary formats.
Secure distribution: Encrypt bundles with age for confidential projects. Only recipients with the private key can decrypt and view the contents.
What's included in an export
Each bundle contains:
- Self-contained: Everything ships in a single directory (HTML, CSS/JS, SQLite snapshot, attachments). Drop it on a static host or open it locally.
- Rich reader UI: Gmail-style inbox with project filters, search, and full-thread rendering—each message is shown with its metadata and Markdown body, just like in the live web UI.
- Fast search & filters: FTS-backed search and precomputed per-message summaries keep scrolling and filtering responsive even with large archives.
- Verifiable integrity: SHA-256 hashes for every asset plus optional Ed25519 signing make authenticity and tampering checks straightforward.
- Chunk-friendly archives: Large databases can be chunked for httpvfs streaming; a companion
chunks.sha256 file lists digests for each chunk so clients can trust streamed blobs without recomputing hashes.
- One-click hosting: The interactive wizard can publish straight to GitHub Pages or Cloudflare Pages, or you can serve the bundle locally with the CLI preview command.
Disaster Recovery Archives (archive commands)
Use the archive subcommands when you need a restorable snapshot (not just a read-only share bundle). Each ZIP under ./archived_mailbox_states/ includes:
- A SQLite snapshot processed by the same cleanup pipeline as
share, but using the archive scrub preset so ack/read state, recipients, attachments, and message bodies remain untouched.
- A byte-for-byte copy of the storage Git repo (
STORAGE_ROOT), preserving markdown artifacts, attachments, and hook scripts.
Quick ref
bash
Save current state (defaults to the lossless preset)
uv run python -m mcp_agent_mail.cli archive save --label nightlyList available restore points (JSON is handy for scripts)
uv run python -m mcp_agent_mail.cli archive list --jsonRestore after a disaster (backs up any existing DB/storage before overwriting)
uv run python -m mcp_agent_mail.cli archive restore archived_mailbox_states/During restore the CLI:
- Extracts the ZIP into a temp directory.
- Moves any existing
storage.sqlite3, WAL/SHM siblings, and STORAGE_ROOT into timestamped .backup-<ts> folders so nothing is lost.
- Copies the snapshot back to the configured database path and rebuilds the storage repo from the archive contents.
Every archive writes a metadata.json manifest describing the projects captured, scrub preset, and a friendly reminder of the exact archive restore … command to run later.
Reset safety net
clear-and-reset-everything now offers to create one of these archives before deleting anything. By default it prompts interactively; pass --archive/--no-archive to force a choice, and pair with --force --no-archive for non-interactive automation. When an archive is created successfully, the CLI prints both the path and the restore command so you can undo the reset later.
Mailbox Health: am doctor
The doctor command group provides comprehensive diagnostics and repair capabilities for maintaining mailbox health. It emphasizes data safety—creating backups before any destructive operation and using semi-automatic repair to prevent accidental data loss.
Why am doctor?
Over time, mailbox state can drift:
- Stale locks: Process crashes leave behind
.archive.lock or .commit.lock files that block operations
- Orphaned records: Agents get deleted but their message recipients remain in the database
- FTS index desync: Full-text search index falls out of sync with actual messages
- Expired file reservations: Reservations expire but aren't cleaned up
- WAL files: SQLite WAL/SHM files accumulate (normal during operation, but worth monitoring)
The doctor commands detect these issues and offer safe, automatic repair.
Diagnostic checks
Run comprehensive diagnostics on your mailbox:
bash
Check all projects
uv run python -m mcp_agent_mail.cli doctor checkCheck with verbose output
uv run python -m mcp_agent_mail.cli doctor check --verboseJSON output for automation
uv run python -m mcp_agent_mail.cli doctor check --jsonWhat it checks:
| Check | Status | Description |
|-------|--------|-------------|
| Locks | OK/WARN | Detects stale archive and commit locks from crashed processes |
| Database | OK/ERROR | Runs PRAGMA integrity_check for SQLite corruption |
| Orphaned Records | OK/WARN | Finds message recipients without corresponding agents |
| FTS Index | OK/WARN | Compares message count vs FTS index entries |
| File Reservations | OK/INFO | Counts expired reservations pending cleanup |
| WAL Files | OK/INFO | Reports presence of SQLite WAL/SHM files |
Example output:
MCP Agent Mail Doctor - Diagnostic Report
==================================================
Check Status Details ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Locks OK No stale locks found Database OK Database integrity check passed Orphaned OK No orphaned records found FTS Index OK FTS index synchronized (1,234 messages) File Res. INFO 4 expired reservation(s) pending cleanup WAL Files OK No orphan WAL/SHM files
All checks passed!
### Semi-automatic repair
The repair command uses a semi-automatic approach:
- Safe repairs (locks, expired reservations) are applied automatically
- Data-affecting repairs (orphan cleanup) require confirmation
- A backup is created before any changes
bashPreview what would be repaired (dry-run)
uv run python -m mcp_agent_mail.cli doctor repair --dry-runRun repairs with prompts for data changes
uv run python -m mcp_agent_mail.cli doctor repairAuto-confirm all repairs (for automation)
uv run python -m mcp_agent_mail.cli doctor repair --yesSpecify custom backup location
uv run python -m mcp_agent_mail.cli doctor repair --backup-dir /path/to/backupsRepair workflow:
- Create backup — Git bundle + SQLite copy created before any changes
- Safe repairs (auto-applied):
- Heal stale locks (removes orphaned .archive.lock, .commit.lock files)
- Release expired file reservations (marks released_ts in database)
- Data repairs (require confirmation):
- Delete orphaned message recipients
- Rebuild FTS index (if needed)
Backup management
Doctor creates timestamped backups before repairs. You can also manage backups directly:
bash
List all available backups
uv run python -m mcp_agent_mail.cli doctor backupsJSON output for scripting
uv run python -m mcp_agent_mail.cli doctor backups --jsonBackup contents:
Each backup includes:
database.sqlite3 — Complete SQLite database copy
database.sqlite3-wal, database.sqlite3-shm — WAL files if present
archive.bundle or {project}.bundle — Git bundle of the archive repository
manifest.json — Metadata: when created, why, what's included, restore instructions
Directory structure:
{storage_root}/backups/
2026-01-06T12-30-45_doctor-repair/
manifest.json
database.sqlite3
archive.bundle
### Restore from backup
If something goes wrong, restore from any backup:
bash
Preview what would be restored
uv run python -m mcp_agent_mail.cli doctor restore /path/to/backup --dry-runRestore (prompts for confirmation)
uv run python -m mcp_agent_mail.cli doctor restore /path/to/backupSkip confirmation prompt
uv run python -m mcp_agent_mail.cli doctor restore /path/to/backup --yesRestore process:
- Validates backup manifest exists and is readable
- Shows backup metadata (creation time, reason, contents)
- Creates a pre-restore backup of current state (safety net)
- Restores SQLite database from backup
- Restores Git archive from bundle
- Reports any errors encountered
Safety features:
- Current database saved as
*.sqlite3.pre-restore before overwrite
- Current archive saved as
*.pre-restore directory before overwrite
- Errors during restore are captured and reported
Best practices
- Run diagnostics regularly:
am doctor check is fast and non-destructive
- Review before repair: Use
--dry-run first to see what would change
- Keep backups: Don't delete old backups until you've verified the system is healthy
- Automate checks: Include
am doctor check --json in your CI/monitoring for early warning
Quick Start: Interactive Deployment Wizard
The easiest way to export and deploy is the interactive wizard, which supports both GitHub Pages and Cloudflare Pages:
bash
Via CLI (recommended)
uv run python -m mcp_agent_mail.cli share wizardOr run the script directly
./scripts/share_to_github_pages.py#### What the wizard does
The wizard provides a fully automated end-to-end deployment experience:
- Session resumption: Detects interrupted sessions and offers to resume exactly where you left off, avoiding re-export
- Configuration management: Remembers your last settings and offers to reuse them, saving time on repeated exports
- Deployment target selection: Choose between GitHub Pages, Cloudflare Pages, or local export
- Automatic CLI installation: Detects and installs missing tools (
gh for GitHub, wrangler for Cloudflare)
- Guided authentication: Step-by-step browser login flows for GitHub and Cloudflare
- Smart project selection:
- Shows all available projects in a formatted table
- Supports multiple selection modes: all, single number (1), lists (1,3,5), or ranges (1-3, 2-5,8)
- Remembers your previous selection for quick re-export
- Redaction configuration: Choose between
standard (scrub secrets like API keys/tokens, keep agent names) or strict (redact all message bodies)
- Cryptographic signing: Optional Ed25519 signing with automatic key generation or reuse of existing keys. Generated keys are written to
~/.mcp-agent-mail/signing-keys/ (mode 0700, never to the cwd) so they cannot be accidentally git add -f'd into a repository
- Pre-flight validation: Checks that GitHub repo names are available before starting the export
- Deployment summary: Shows what will be deployed (project count, bundle size, target, signing status) and asks for confirmation
- Export and preview: Exports the bundle and launches an interactive preview server with automatic port detection (tries 9000-9100)
- Interactive preview controls:
- Press 'r' to force browser refresh (manual cache bust)
- Press 'd' to skip preview and deploy immediately
- Press 'q' to quit preview server
- Automatic viewer asset refresh: Always ensures latest HTML/JS/CSS from source tree are used, even when reusing bundles
- Real-time deployment: Streams git and deployment output in real-time so you can follow the progress
- Automatic deployment: Creates repos, enables Pages, pushes code, and gives you the live URL
Session resumption (new in latest version)
If you interrupt the wizard (close terminal, Ctrl+C during preview, etc.), it saves your progress to ~/.mcp-agent-mail/wizard-session/. When you run the wizard again:
Incomplete session detected
Projects: 3 selected
Stage: preview
Workspace: ~/.mcp-agent-mail/wizard-session/bundle
Resume where you left off? (Y/n):
What gets saved:
- Selected projects and scrub preset
- Deployment configuration (target, repo name, etc.)
- Signing key preferences and paths
- Exported bundle (in session workspace)
- Current stage (preview, deploy)
Resume scenarios:
- Closed terminal during preview: Resume → Skip re-export → Launch preview immediately
- Changed your mind after export: Resume → "Reuse bundle?" → Preview or re-export
- Want to deploy later: Resume → Press 'd' in preview → Deploy without re-exporting
- Made viewer code changes: Resume → Assets auto-refresh from source tree
After successful deployment, the session state is automatically cleared. Sessions also clear if they become invalid (workspace deleted, projects removed, etc.).
Configuration persistence
The wizard saves your configuration to ~/.mcp-agent-mail/wizard-config.json after each successful deployment. On subsequent runs, it will show:
Previous Configuration Found
Projects: 3 selected
Redaction: standard
Target: github-new
Use these settings again? (Y/n): ```
This allows rapid re-deployment with the same settings. The saved configuration includes:
- Selected project indices (validates against current project list)
- Redaction preset
- Deployment target and parameters (repo name, privacy, project name)
- Signing prefer