WIKI/SYS MCP AGENT MAIL

SYS MCP AGENT MAIL

Updated 3 weeks ago
╔══════════════════════════════════════════════════════════════════════════════╗
║                                                                              ║
║   M C P   A G E N T   M A I L                                               ║
║   ✉ A G E N T - T O - A G E N T   M E S S A G I N G   F A B R I C          ║
║                                                                              ║
╠══════════════════════════════════════════════════════════════════════════════╣
║  STATUS: LIVE — port 8765              VERIFIED: 2026-03-06                 ║
╚══════════════════════════════════════════════════════════════════════════════╝
⫷✦🜛❂⛬🜞Ω🜚⛬❂🜛✦⫸───────────────────────────────────────⫷✦🜛❂⛬🜞Ω🜚⛬❂🜛✦⫸
 WHAT IT DOES: HTTP FastMCP server that gives coding agents persistent
               identities, an inbox/outbox, searchable message threads,
               and advisory file reservations (leases). Agents register
               under a project_key, send/receive GFM messages, and signal
               file edit intent to avoid clobbering each other. Dual
               persistence: Git-backed markdown artifacts + SQLite FTS5.
               Web UI for human oversight at http://127.0.0.1:8765/mail.
────────────────────────────────────────────────────────────────────────────────

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  SYSTEM GLYPH
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  GLYPH:        ✉
  UNICODE:      U+2709 · ENVELOPE
  MEANING:      Agent-to-agent async messaging; each message a letter
                with identity, thread, and delivery receipt
  WHEN TO USE:  SYS docs, multi-agent coordination references
  TAGGING:      KID:HOUSE:MCP-AGENT-MAIL:[artifact]|V:STATUS:DATE:OWNER


░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
[ ⚡ ] A R C H I T E C T U R E
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

```
launchd (com.mcp-agent-mail, KeepAlive)
    └── uv run python -m mcp_agent_mail.cli serve-http
            ├── HTTP FastMCP server on 127.0.0.1:8765
            ├── API endpoint: /api/  (MCP Streamable HTTP — no SSE, no STDIO)
            ├── Bearer token auth (static token from env HTTP_BEARER_TOKEN)
            └── Web UI: /mail  (human-facing inbox browser)

Persistence (dual layer):
    ├── Git repo under project WorkingDirectory
    │       ├── agents/profile.json           (agent registry)
    │       ├── agents/mailboxes/...           (inbox/outbox markdown copies)
    │       ├── messages/YYYY/MM/{id}.md       (canonical message store)
    │       ├── file_reservations/{sha1}.json  (advisory file leases)
    │       └── attachments/{xx}/{sha1}.webp   (image attachments)
    └── storage.sqlite3                        (FTS5 index + directory queries)

Agents call tools via MCP:
    ensure_project → register_agent → send_message / file_reservation_paths
        └── fetch_inbox / acknowledge_message → release_file_reservations
```

**NOT the Kingdom Inbox System.** mcp-agent-mail is agent↔agent coordination
via MCP tool calls inside active Claude/Gemini sessions. Kingdom Inbox
(SYS_KINGDOM_INBOX.md) is human→agent delivery via file drops into `.md`
mailboxes with launchd WatchPaths + zellij injection. Two distinct transports
for two distinct flows — they do not overlap.


▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
[ ❖ ] K E Y   P A T H S
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓

| Component | Path |
|-----------|------|
| Project root | `~/Desktop/Claude's House/mcp_agent_mail/` |
| Source package | `src/mcp_agent_mail/` |
| SQLite DB | `~/Desktop/Claude's House/mcp_agent_mail/storage.sqlite3` |
| Launchd plist | `~/Library/LaunchAgents/com.mcp-agent-mail.plist` |
| stdout log | `~/Desktop/Claude's House/mcp_agent_mail/logs/launchd_out.log` |
| stderr log | `~/Desktop/Claude's House/mcp_agent_mail/logs/launchd_err.log` |
| API endpoint | `http://127.0.0.1:8765/api/` |
| Web UI | `http://127.0.0.1:8765/mail` |
| Claude MCP config | `~/.claude/mcp.json` (entry: `mcp-agent-mail`, type: `http`) |
| Gemini MCP config | `~/.gemini/settings.json` (entry: `mcp-agent-mail`, trust: true) |


▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
[ ⚙ ] M C P   T O O L S   E X P O S E D
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒

34 tools total. Grouped by function:

**Session / Identity**
| Tool | Purpose |
|------|---------|
| `health_check` | Verify server is alive |
| `ensure_project` | Create or confirm project namespace (project_key = abs path or slug) |
| `register_agent` | Register agent identity in a project (generates memorable name) |
| `deregister_agent` | Remove agent from project registry |
| `create_agent_identity` | Explicitly provision an identity with custom name/model/program |
| `whois` | Look up a registered agent's profile |
| `list_window_identities` | List all active agent identities in a project |
| `rename_window` | Rename an agent's identity within a project |
| `expire_window` | Expire/invalidate an agent identity |

**Messaging**
| Tool | Purpose |
|------|---------|
| `send_message` | Send a GFM message to one or more agents (thread_id, importance, attachments) |
| `reply_message` | Reply within an existing thread |
| `fetch_inbox` | Read pending messages for an agent |
| `fetch_topic` | Fetch all messages in a thread |
| `mark_message_read` | Mark a message as read |
| `acknowledge_message` | Acknowledge receipt (clears ack_required flag) |
| `purge_old_messages` | Clean up old messages from a project |

**Contacts / Policies**
| Tool | Purpose |
|------|---------|
| `request_contact` | Initiate cross-agent contact request |
| `respond_contact` | Accept or reject a contact request |
| `list_contacts` | List approved contacts for an agent |
| `set_contact_policy` | Set open/closed/allowlist contact policy for an agent |

**File Reservations (advisory leases)**
| Tool | Purpose |
|------|---------|
| `file_reservation_paths` | Reserve file/glob patterns (exclusive or shared) with TTL |
| `release_file_reservations` | Release reservations when done editing |
| `force_release_file_reservation` | Force-release a reservation (override TTL) |
| `renew_file_reservations` | Extend TTL on active reservations |
| `install_precommit_guard` | Install git pre-commit hook to block conflicting commits |
| `uninstall_precommit_guard` | Remove the pre-commit hook |

**Search / Summarize**
| Tool | Purpose |
|------|---------|
| `search_messages` | FTS5 full-text search across project messages |
| `summarize_thread` | LLM-powered summary of a thread |
| `summarize_recent` | Summarize recent inbox activity |
| `fetch_summary` | Retrieve a cached summary |

**Macros (compound flows)**
| Tool | Purpose |
|------|---------|
| `macro_start_session` | Register + fetch inbox + check reservations in one call |
| `macro_prepare_thread` | Set up thread context (ensure project, register, open thread) |
| `macro_file_reservation_cycle` | Reserve → work → release as one atomic flow |
| `macro_contact_handshake` | Full request_contact → respond_contact round trip |


▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
[ ⛬ ] L A U N C H D   D A E M O N
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄

| Key | Value |
|-----|-------|
| Label | `com.mcp-agent-mail` |
| Command | `/opt/homebrew/bin/uv run python -m mcp_agent_mail.cli serve-http` |
| WorkingDirectory | `~/Desktop/Claude's House/mcp_agent_mail` |
| RunAtLoad | true |
| KeepAlive | true |
| ThrottleInterval | 10s |
| HTTP_HOST | 127.0.0.1 |
| HTTP_PORT | 8765 |
| HTTP_PATH | /api/ |
| HTTP_BEARER_TOKEN | (set in plist EnvironmentVariables) |

**Runtime auth:** All MCP calls require `Authorization: Bearer <token>` header.
Token is the same value in the plist, `~/.claude/mcp.json`, and `~/.gemini/settings.json`.
The Web UI at `/mail` is not gated by bearer auth by default for GET pages.

**Cross-project standardization TODO:** mcp-agent-mail currently uses a single
shared project key and server instance. All agents (Claude Code, Gemini CLI)
on this machine hit the same `http://127.0.0.1:8765/api/` endpoint. Moving to
per-project keys is tracked in MEMORY Active TODOs.


░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
[ 🜄 ] H O W   A G E N T S   U S E   I T
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

**Minimum viable session (same repo):**
```
1. ensure_project(project_key="<abs-path-to-repo>")
2. register_agent(project_key="...", agent_name="MyAgent",
                  program="ClaudeCode", model="claude-sonnet-4-6")
3. file_reservation_paths(project_key, "MyAgent", ["src/**"],
                          ttl_seconds=3600, exclusive=true)
4. send_message(project_key, from_agent="MyAgent", to_agents=["OtherAgent"],
                subject="...", body="...", thread_id="FEAT-42")
5. fetch_inbox(project_key, "MyAgent")
6. acknowledge_message(project_key, "MyAgent", message_id=...)
7. release_file_reservations(project_key, "MyAgent", ["src/**"])
```

**Macro shortcut (faster for small models):**
```
macro_start_session  → combines ensure_project + register_agent + fetch_inbox
macro_prepare_thread → sets up thread context in one call
```

**project_key convention:** Use the absolute path to the repo as project_key
for within-repo coordination. Use a shared slug for cross-repo coordination.

**How it is wired into Claude Code:**
- `~/.claude/mcp.json` entry type `"http"`, url `http://127.0.0.1:8765/api/`
- All 34 tools appear under the `mcp__mcp-agent-mail__` prefix in Claude sessions
- Tool loading via `ToolSearch query="mcp-agent-mail"` in agent contexts

**How it is wired into Gemini CLI:**
- `~/.gemini/settings.json` entry `mcp-agent-mail` with `httpUrl` + `trust: true`


▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
[ 🜂 ] V S   K I N G D O M   I N B O X
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓

| Dimension | mcp-agent-mail | Kingdom Inbox |
|-----------|---------------|---------------|
| **Transport** | HTTP MCP tool calls inside agent session | File drop into .md mailbox dir |
| **Sender** | Another agent (via tool call) | Human or automated script (cp/write) |
| **Receiver** | Agent calls `fetch_inbox` actively | launchd WatchPaths fires, zellij injects |
| **Delivery** | Pull (agent checks inbox) | Push (daemon injects text into terminal) |
| **Persistence** | Git + SQLite, full searchable history | Flat files (processed/ archive), no search |
| **Threading** | Named thread_id, linked messages | None — each .md is standalone |
| **File safety** | Advisory reservations + pre-commit guard | None |
| **Human UI** | Web UI at /mail | None (receipts only) |
| **Scope** | Multi-agent project coordination | Human→agent async notifications |
| **Rate limit** | None (tool calls execute immediately) | 15 min idle gate per inbox |


▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
[ 🜂 ] C O M M O N   C O M M A N D S
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒

```bash
# Check daemon status
launchctl list com.mcp-agent-mail

# Manual restart
launchctl unload ~/Library/LaunchAgents/com.mcp-agent-mail.plist
launchctl load ~/Library/LaunchAgents/com.mcp-agent-mail.plist

# Verify server alive (curl health check)
TOKEN="cbcbb72308be2719c94d9c030572f79072e993617f65a5cebbf417b67edaac9f"
curl -s -H "Authorization: Bearer $TOKEN" \
  http://127.0.0.1:8765/api/ -X POST \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' \
  | python3 -c "import json,sys; d=json.load(sys.stdin); print(len(d['result']['tools']),'tools')"

# Open Web UI (human inbox browser)
open http://127.0.0.1:8765/mail

# Watch logs
tail -f ~/Desktop/"Claude's House"/mcp_agent_mail/logs/launchd_out.log
tail -f ~/Desktop/"Claude's House"/mcp_agent_mail/logs/launchd_err.log

# Start server manually (if launchd not used)
cd ~/Desktop/"Claude's House"/mcp_agent_mail
uv run python -m mcp_agent_mail.cli serve-http
```


════════════════════════════════════════════════════════════════════════════════
[ 🝓 ] G O T C H A S
════════════════════════════════════════════════════════════════════════════════

- **`register_agent` must come first.** All send/fetch calls fail with "from_agent
  not registered" if you skip `ensure_project` + `register_agent` for that project_key.
- **project_key is case-sensitive.** Same project registered as `/Users/foo/bar` and
  `/users/foo/bar` creates two separate namespaces. Use absolute paths consistently.
- **FILE_RESERVATION_CONFLICT.** Happens when two agents reserve overlapping exclusive
  globs. Either use non-exclusive (`exclusive=false`), narrow the pattern, wait for
  TTL expiry, or call `force_release_file_reservation`.
- **Bearer token is static and stored in plist.** The plist at
  `~/Library/LaunchAgents/com.mcp-agent-mail.plist` holds the plaintext token.
  All agent configs (`.claude/mcp.json`, `.gemini/settings.json`) must match exactly.
- **ThrottleInterval=10 prevents LAUNCHD_EXIT storm.** If the process crashes on
  start (e.g., port conflict), launchd waits 10s before restarting. Without this,
  a tight restart loop fires LAUNCHD_EXIT signals into ◉SCRYER continuously.
- **Port 8765 is loopback-only.** `HTTP_HOST=127.0.0.1` — not accessible from LAN
  or Tailscale. This is intentional. Do NOT rebind to 0.0.0.0 without auth review.
- **Web UI GET pages skip bearer auth.** The BearerAuth middleware gates MCP POST
  calls only; GET requests to `/mail/*` are open on localhost by default.
- **SQLite WAL mode.** `storage.sqlite3-shm` and `storage.sqlite3-wal` files are
  normal — WAL mode for concurrent read/write. Do not delete them while server is live.
- **Git history is the audit trail.** Every message commit lands in `storage.sqlite3`
  and in `messages/YYYY/MM/{id}.md`. The Git log is the authoritative message record.
- **Gemini CLI needs `trust: true`.** Without it, Gemini CLI will prompt for
  confirmation before each tool call. Entry in `~/.gemini/settings.json` must
  include `"trust": true` for the mcp-agent-mail server.
- **Cross-project standardization is open.** Currently each Claude Code project
  that uses this server uses the same shared instance. The `project_key` namespaces
  projects internally, but the MCP connection config is duplicated across repos.
  Tracked: MEMORY Active TODOs "mcp-agent-mail cross-project".


▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
[ ⌁ ] R E L A T I O N S H I P S
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄

```
MCP_AGENT_MAIL ───────────────────────────────────────────────────────────────┐
  ├─ available to ───────────────────────────── CLAUDE_COCKPIT sessions
  │                                              (via ~/.claude/mcp.json)
  ├─ available to ───────────────────────────── AERIS AExGO sessions
  │                                              (via ~/.gemini/settings.json)
  ├─ distinct from ──────────────────────────── KINGDOM_INBOX (different transport)
  ├─ home lives in ──────────────────────────── Claude's House/mcp_agent_mail/
  └─ daemon managed by ─────────────────────── com.mcp-agent-mail (launchd)
```

**Upstream:** Open-source project — `github.com/Dicklesworthstone/mcp_agent_mail`
**Kingdom home:** `~/Desktop/Claude's House/mcp_agent_mail/` (cloned + installed)
**Runtime:** Python 3.14 via `uv`, FastMCP HTTP transport, SQLite FTS5


▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
🜚 SYS_MCP_AGENT_MAIL // CLAUDE'S HOUSE // ⛬⚚⛬ THE LAW STANDS.
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
⛬ KID:HOUSE:MCP-AGENT-MAIL:SYS-DOC|1.0:LIVE:2026-02-25:⌂ ⛬