# agentmail — bootstrap guide for setup LLMs You are reading this because the user wants to wire **agentmail** into the project you're currently in. Your job is to take this project from "the daemon is scaffolded" to "both agents can coordinate through it." This is a one-shot bootstrap task. After this, the running agents will read the per-project instructions you wrote into their session prompt — they will not re-read this file. The canonical URL of this file is: ## What agentmail is, in one paragraph agentmail is a local, pull-only message bus between two CLI coding agents (typically Claude Code and OpenAI Codex). Each agent gets five MCP tools (`inbox`, `wait`, `pull`, `send`, `status`). The human watches a terminal dashboard and (in MANUAL mode) gates every inbound message. The design constraint is **context discipline**: no message ever enters an agent's context without an explicit tool call. The full project lives at . ## Step 0 — Confirm the daemon is scaffolded Before you do anything else, verify `./.mail/config.json` exists at the project root. If it does not, the user has not run `agentmail init` yet. Stop and ask them to run it before continuing — without `.mail/config.json` you do not know which port this project's daemon binds to and the MCP wiring will be wrong. When `.mail/config.json` exists, read it. The two fields you care about: - `port` — the daemon's loopback port. Each project picks a unique one. - The absolute path of the `.mail/` directory itself — both MCP clients need it as `AGENTMAIL_DIR` so the spawned MCP server resolves the right daemon. ## Step 1 — Wire the MCP servers into Claude and Codex Each agent CLI has its own MCP config format. Write **only** the agent configs the user actually uses — if there is no `.codex/` directory and the user only runs Claude, skip the Codex block, and vice versa. Ask if you are not sure. ### Claude Code → `.mcp.json` at the project root Create or merge into `./.mcp.json`. Replace `` with the absolute path to this project's `.mail/` directory. ```json { "mcpServers": { "agentmail": { "command": "agentmail", "args": ["mcp", "--as", "claude"], "env": { "AGENTMAIL_DIR": "" } } } } ``` If `.mcp.json` already exists with other servers, add the `agentmail` entry inside the existing `mcpServers` object — do not overwrite the file. ### Codex → `.codex/config.toml` at the project root Create or merge into `./.codex/config.toml`. Replace `` with the absolute path to this project's `.mail/`. ```toml [mcp_servers.agentmail] command = "agentmail" args = ["mcp", "--as", "codex"] startup_timeout_sec = 30 [mcp_servers.agentmail.env] AGENTMAIL_DIR = "" ``` The `startup_timeout_sec = 30` is intentional — Codex's default 10s is tight when other MCP servers start in parallel. If either config file already exists, merge — do not overwrite. ## Step 2 — Tell each agent how to coordinate Append (or merge) an `## agentmail coordination` section into the project's per-agent instruction files at the project root. Canonical names: - `CLAUDE.md` — read by Claude Code - `AGENTS.md` — read by Codex (and some other tools) - `.codex/AGENTS.md` — Codex-specific overrides, takes precedence over `AGENTS.md` **Default role assignment: Claude implements, Codex plans + reviews.** This is the convention most agentmail users run. If unsure, ask the user once, then proceed. Use the snippets in [Step 4](#step-4--the-snippets) below verbatim, edited only to reflect which role each agent plays. Do not invent your own phrasings — these snippets are tuned for context cost. ## Step 3 — The MCP tool surface (verbatim — do not paraphrase loosely) | Tool | Input | Returns | When to call | | -------- | ------------------------------ | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `inbox` | (none) | Headers list (id, from, ts, title, type). No bodies. | When you want a quick non-blocking check of what's queued for you. Cheap on context. | | `wait` | `timeoutSec?` (default 1800) | Same headers as `inbox`, or `"timeout"`. | When you have nothing useful to do until the peer responds. Blocks until an inbox message is visible or the timeout elapses. Returns immediately if your inbox is non-empty. | | `pull` | `id` (from `inbox`) | The full message body and any reviewer edits/notes. | The only path a body enters your context. Call deliberately, after `inbox` shows a header worth reading. | | `send` | `type`, `title`, `body`, `to?` | Acknowledgement with the new message id and status. | When you need to hand work to the other agent or post a `note` to the human. Defaults `to` to the peer (the agent who is not you). | | `status` | `text` (max 200 chars) | `"ok"` — the text is never echoed back. | To set a short "what I'm working on" string for the human's dashboard. Write-only. | The MCP server registers the tools under those exact names. In Claude Code you may see them surface as `mcp__agentmail__inbox` and so on — that is the host's namespacing, not a different tool name. Valid `type` values for `send`: - `prompt` — a task delegated to the recipient (typically planner → implementer) - `report-back` — a completion report (typically implementer → planner) - `blockers` — a mid-flight question or blocker the recipient must resolve - `review-finding` — a reviewer asks for changes - `green-light` — a reviewer approves the work - `commit-pr-prompt` — "create commits and a PR" instruction - `note` — anything else, including messages to the human (`to: "user"`) `to` values: `"claude"`, `"codex"`, `"user"`. You cannot send to yourself. ### Hard rules to bake into both roles - **Never** start work without `pull`. Headers alone are not the prompt. - **Never** poll `inbox` in a loop. Use `wait` — it's one blocking call instead of many context-spending ones. - **`wait` is the default blocking primitive.** Prefer it over `inbox` even at session start — it returns immediately if the inbox is non-empty. - **`status` is human-visible only.** It is not peer communication and never round-trips back into agent context — don't use it to "signal" the other agent. - **Never** send to yourself; the server rejects it. - **Never** assume the peer saw your message immediately. In MANUAL mode the human gates inbound — you have no visibility into when (or if) they release it. Block on `wait` and trust the wake. - **Never** wrap `pull` output in commentary back to the bus. If the planner sent you a prompt, work on it — don't echo the prompt back as a `note`. ## Step 4 — The snippets ### Snippet to merge into the implementer agent's file ```markdown ## agentmail coordination You share this project with another AI coding agent via the `agentmail` MCP server. Your role is **implementer**: you receive prompts, do the work, and report back for review. Coordinate exclusively through the agentmail MCP tools (`inbox`, `wait`, `pull`, `send`, `status`) — do not ask the user to relay messages. **At the start of every session**, call `wait` once. It returns immediately if your inbox already has queued messages, so this avoids the extra round trip of calling `inbox` first. If headers come back, `pull` the most recent `prompt` or `review-finding` and start there. Otherwise the call blocks until work arrives. You must still `pull` before acting on any message body — headers alone are not the prompt. **Loop:** 1. `pull ` the inbound prompt. 2. Do the work. 3. `status ""` for any non-trivial milestone (optional). 4. `send report-back` with a complete summary of what changed and any open questions. The reviewer cannot see your terminal — your report-back is the entire signal. 5. `wait` for the reviewer's response. 6. If `review-finding`, address the points and goto 4. If `green-light`, carry out any final instructions (e.g. `commit-pr-prompt`). **Never** poll `inbox` in a loop — `wait` is the blocking primitive. **Never** send to yourself. Default `to` (the peer) is correct in almost every case. ``` ### Snippet to merge into the planner/reviewer agent's file ```markdown ## agentmail coordination You share this project with another AI coding agent via the `agentmail` MCP server. Your role is **planner and reviewer**: you formulate prompts with the user, delegate to the implementer, and review what comes back. Coordinate exclusively through the agentmail MCP tools (`inbox`, `wait`, `pull`, `send`, `status`). **At the start of every session**, call `inbox` once. If there are unread `report-back` or `blockers` messages, prioritise them. **Loop:** 1. Work with the user to define the next task. 2. `send prompt` to the implementer with a self-contained brief. 3. `wait` for the response. 4. `pull ` the `report-back` or `blockers`. 5. Review: - Issues → `send review-finding` with specifics, goto 3. - Approved → `send green-light`, optionally a `commit-pr-prompt`. - Blockers → resolve with the user, then `send` back with guidance. **Never** poll `inbox` in a loop — use `wait`. **Never** send a `prompt` without the context the implementer needs to act on it alone; the implementer cannot see your conversation with the user. ``` ## Step 5 — Verification After editing, do a final read-through of every file you changed and confirm: 1. `.mcp.json` (if you wrote one) parses as JSON, has an `agentmail` server entry, and the `AGENTMAIL_DIR` is the absolute path to this project's `.mail/`. 2. `.codex/config.toml` (if you wrote one) has a single `[mcp_servers.agentmail]` block with the matching `AGENTMAIL_DIR`. 3. The `## agentmail coordination` section exists exactly once in each instruction file you touched. 4. The role (implementer vs planner) matches what the user intends. 5. No tool name is misspelled (it's `inbox`, `wait`, `pull`, `send`, `status` — all lowercase, no prefix). 6. You have not removed or reordered unrelated sections. Report back to the user with a one-line summary per file you changed, plus a reminder: **restart any open Claude or Codex sessions** so the agent CLIs re-read the MCP config and the new instruction files. ## What you should NOT do - Do not invent new MCP tools or new `type` values. The five tools and seven types above are the entire surface. - Do not write instructions that ask the agent to call `inbox` on a timer. The whole point of `wait` is to avoid that pattern. - Do not document `status` as a way to communicate with the peer. It is for the human's TUI only and is never visible to the peer agent. - Do not write CLAUDE.md / AGENTS.md content that contradicts the project's existing conventions. If you see existing content that conflicts (e.g. a rule that says "never use MCP tools without asking the user"), surface the conflict to the user before changing anything. - Do not add a section longer than the snippets above. Verbose project instructions waste tokens on every session start.