Files
ClaudeMailbox/plugin
Mika Kuns 462d6561e1 feat(plugin): per-session mailbox identity + mailbox-update command
The hook now derives a unique mailbox name from the session_id supplied
on hook stdin, so two parallel Claude Code sessions in the same project
get distinct mailboxes (e.g. `claude-a8b3c1d2`, `claude-d4e5f6a7`)
instead of colliding on a shared env value. An optional
CLAUDE_MAILBOX_NAME base prefix flavors the names as `<base>-<sid>`.

Adds:
- `claude-mailbox session-announce` subcommand for the new SessionStart
  hook, which prints the current session's mailbox name to context
- `/claude-mailbox:mailbox-update` slash command for `npm update` +
  daemon restart
- stdin parsing helpers (parseHookStdin, deriveSessionName) with unit
  tests; the doctor no longer needs a mandatory name prompt
2026-05-19 11:39:14 +02:00
..

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
/plugin install claude-mailbox@claude-mailbox
/claude-mailbox:mailbox-doctor

The doctor walks the rest:

  1. installs the claude-mailbox binary via npm install -g @kuns/claude-mailbox if missing (asks first)
  2. registers the daemon for autostart and starts it if needed
  3. health-probes http://127.0.0.1:47822/health
  4. optionally lets you set a base prefix (e.g., backend) — without one, mailbox names are anonymous (claude-XXXXXXXX)
  5. runs a self → self smoke test

Restart Claude Code only if step 4 wrote a new prefix. After that, every prompt auto-pulls unread messages.

Mailbox identity (the important bit)

Each Claude Code session gets its own mailbox name, derived from the session's UUID:

Configuration Resulting mailbox name
No CLAUDE_MAILBOX_NAME set claude-a8b3c1d2 (first 8 hex chars of session_id)
CLAUDE_MAILBOX_NAME=backend in .claude/settings.json env backend-a8b3c1d2

So if you open two Claude Code sessions in the same project, they'll be e.g. backend-a8b3c1d2 and backend-d4e5f6a7 — distinct, addressable, no manual setup.

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 Prints "Claude-Mailbox: this session is mailbox \X`"` so Claude knows its own identity.
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.

Cost: one local HTTP round-trip per prompt + Node coldstart (~100ms on Windows).

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.

Sending a message to a peer session

From inside Claude Code, use the MCP tool (the daemon already exposes mcp__mailbox__*). From any shell:

claude-mailbox list                                  # find the recipient's mailbox name
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