Wire a fifth pull hook so peer messages also surface between todo items, not only at user prompts and subagent stops. While here, extend the manual `install-hook` CLI so it patches the full plugin hook set (SessionStart/UserPromptSubmit/SubagentStop/TaskCompleted/ SessionEnd) instead of only UserPromptSubmit, mirroring what the plugin's hooks.json registers. Mailbox name is auto-derived from stdin, so --name is no longer required. Also corrects stale docs that claimed SessionStart auto-bootstraps the watcher — push delivery has been opt-in since the mailbox-collaborate skill landed.
claude-mailbox plugin
Lets Claude Code pull unread messages from a local claude-mailbox daemon before every prompt and inject them into the conversation context. Each Claude session gets a unique mailbox identity auto-derived from its session id, so two sessions in the same project never collide.
Setup (three prompts, all inside Claude Code)
/plugin marketplace add https://git.kuns.dev/releases/ClaudeMailbox.git
/plugin install claude-mailbox@claude-mailbox
/claude-mailbox:mailbox-doctor
The doctor walks the rest:
- installs the
claude-mailboxbinary vianpm install -g @kuns/claude-mailboxif missing (asks first) - registers the daemon for autostart and starts it if needed
- health-probes
http://127.0.0.1:37849/health - runs a self → self smoke test
After that, every prompt auto-pulls unread messages.
Mailbox identity (the important bit)
Each Claude Code session gets its own mailbox name, automatically derived as <project>-<session-short>:
| Where the session runs | Resulting mailbox name |
|---|---|
| Inside a git repo | <repo-basename>-a8b3c1d2 (e.g. claude-mailbox-a8b3c1d2) |
| Outside a git repo | <cwd-basename>-a8b3c1d2 |
| No cwd in stdin (rare) | claude-a8b3c1d2 |
So if you open two Claude Code sessions in the same project, they'll share the project prefix but differ in the session-short — e.g. claude-mailbox-a8b3c1d2 and claude-mailbox-d4e5f6a7. No env-var, no manual prefix step.
If a session focuses on a sub-area (frontend, backend, …), Claude can call mcp__mailbox__rename(current_name="…", new_name="claude-mailbox-frontend-a8b3c1d2") to tag itself; pending messages are transferred. Peers using the old name re-discover via list_mailboxes.
The SessionStart hook announces the current session's mailbox name in the conversation context on startup. Peers discover each other via claude-mailbox list or the mcp__mailbox__list_mailboxes MCP tool.
What the hooks do
| Hook | Command | Effect |
|---|---|---|
SessionStart |
claude-mailbox session-announce |
Registers the session with the daemon, then prints (a) this session's mailbox name, (b) the exact from / name args to pass to MCP tools, and (c) a list of other mailboxes active in the last hour — so Claude knows who's around without needing to call list_mailboxes first. |
UserPromptSubmit |
claude-mailbox check --hook |
Pulls unread messages for the session's mailbox and injects them as context. Silent on empty inbox; emits a one-line setup hint when the daemon is unreachable. |
SubagentStop |
claude-mailbox check --hook |
Same as UserPromptSubmit, but fires when a subagent finishes. Lets the parent see peer messages that arrived during a long-running subagent run, instead of waiting until the next user prompt. |
TaskCompleted |
claude-mailbox check --hook |
Fires whenever Claude marks a TaskCreate task completed — gives peers mid-run injection points between todo items without needing the opt-in watcher. |
SessionEnd |
claude-mailbox session-end |
Deletes this session's auto-derived mailbox if it's empty (no pending messages). Renamed mailboxes are preserved. |
Cost: one local HTTP round-trip per fire + Node coldstart (~100ms on Windows).
Push delivery (real-time mid-turn wakeup via claude-mailbox watch --block) is opt-in. Invoke the mailbox-collaborate skill or the /collaborate slash command when you want peers to wake the session mid-task. Without it, the four pull hooks above are the always-on delivery path.
MCP tools
The plugin ships a .mcp.json that spawns a stdio MCP wrapper (claude-mailbox mcp-stdio) so the daemon URL is configurable per machine via the CLAUDE_MAILBOX_URL env var (Claude Code doesn't yet support env substitution in HTTP MCP URLs — see issue #46889). The wrapper proxies tool calls to the daemon's REST API.
Each MCP tool takes the caller's mailbox name as an explicit argument (from the SessionStart announcement):
| Tool | Required args | Purpose |
|---|---|---|
mcp__mailbox__send |
from, to, body |
Send a message to another mailbox. |
mcp__mailbox__check_inbox |
name |
Pull all undelivered messages for your mailbox (marks delivered). |
mcp__mailbox__peek_inbox |
name |
Non-consuming count of pending messages. |
mcp__mailbox__list_mailboxes |
name |
Discover known mailboxes and pendingForYou counts. |
mcp__mailbox__rename |
current_name, new_name |
Rename your own mailbox (e.g. add an area tag). Pending messages are transferred. Use the new name afterward. |
The SessionStart announcement spells out the exact args to pass, so Claude picks them up automatically.
Slash commands
| Command | What it does |
|---|---|
/claude-mailbox:mailbox-doctor |
Diagnose + auto-fix the full setup. |
/claude-mailbox:mailbox-status |
Read-only health check. No changes. |
/claude-mailbox:mailbox-update |
Update the daemon to the latest npm version and restart it. |
Coordinating two Claude Code sessions
- Open two Claude Code sessions in the same (or different) project.
- Each session's SessionStart hook registers itself with the daemon and prints both its own mailbox name and the list of currently active peers into context.
- In session A you can simply say: "I started a second session, coordinate with it." Because the peer's mailbox name is already in context, Claude can call
mcp__mailbox__send(from="<my-name>", to="<peer-name>", body="...")straight away — no manuallist_mailboxesstep needed. - Session B's
UserPromptSubmithook pulls the message on its next prompt and injects it as context.
You can also send from any shell:
claude-mailbox list
claude-mailbox send --from probe --to backend-a8b3c1d2 --body "hi"
Uninstall
/plugin uninstall claude-mailbox@claude-mailbox
npm uninstall -g @kuns/claude-mailbox
claude-mailbox uninstall-autostart # if you registered it