Files
ClaudeMailbox/plugin/commands/mailbox-doctor.md
Mika Kuns 42237149a1
Some checks failed
CI (Node) / build-test (push) Successful in 9s
Release (Node) / release (push) Failing after 1s
Release / release (push) Successful in 7s
feat: stdio MCP wrapper + Windows Run-key autostart fallback (v1.0.1)
Two production-readiness fixes so colleagues can install cleanly:

1. Plugin's MCP server now spawns `claude-mailbox mcp-stdio`, a small
   stdio MCP wrapper that proxies tool calls to the daemon's REST API.
   Claude Code does not support env-var substitution in HTTP MCP `url`
   fields (issue #46889), so the wrapper is the only way to make the
   daemon URL configurable per machine via CLAUDE_MAILBOX_URL.

2. Windows `install-autostart` now falls back from `schtasks /Create`
   to an HKCU\Software\Microsoft\Windows\CurrentVersion\Run entry
   when Group Policy blocks the Scheduled Task path. Both modes are
   per-user, no admin, persist across logoffs. The chosen mode is
   recorded in ~/.claude-mailbox/autostart-mode so status/start/stop/
   uninstall-autostart pick the right cleanup path.

Also bumps the npm version to 1.0.1 to align with the published 1.0.0
plus this patch.
2026-05-19 13:43:55 +02:00

5.7 KiB

description, allowed-tools
description allowed-tools
Diagnose and auto-fix the Claude-Mailbox setup (binary install, port-conflict detection, daemon autostart, smoke test, optional base-prefix). Bash, Read, Edit, Write

You are running the Claude-Mailbox doctor. Walk through these checks in order. After each step, print a one-line / with the action you took. End with a summary block.

Use Bash only for claude-mailbox subcommands, npm, where/which, and HTTP probes. Use Read/Edit/Write for .claude/settings.json and mailbox.json. Never run sudo automatically — if elevation is needed, stop and ask.

Step 1 — daemon binary on PATH

Run: claude-mailbox --version

  • Exit 0 → ✓ record the version. Continue.

  • Command not found → binary missing. Install path:

    Platform Command
    Windows npm install -g @kuns/claude-mailbox (no admin)
    macOS / Linux npm install -g @kuns/claude-mailbox (may fail with EACCES — never run sudo automatically; ask the user)

    Prerequisite: npm config get @kuns:registry must point at https://git.kuns.dev/api/packages/releases/npm/. If not:

    npm config set @kuns:registry=https://git.kuns.dev/api/packages/releases/npm/
    

    After install, re-run claude-mailbox --version. If it still fails, stop and report.

Step 2 — port-conflict check (before autostart!)

Default port is 47822. Probe whether anything is already on it:

curl -sf http://127.0.0.1:47822/health
  • Returns a JSON body with "status":"ok" and a version field that matches claude-mailbox --version → it's already our daemon, ✓ skip to Step 4.
  • Returns 200 with "status":"ok" but a different version → it's an older claude-mailbox; treat as running, ✓.
  • Returns non-200, non-JSON, or any other foreign responseport conflict. Some other process owns 47822.
  • Connection refused → port is free, ✓ continue to Step 3.

If port conflict detected:

  1. Tell the user which process holds the port (Windows: Get-NetTCPConnection -LocalPort 47822 | Select-Object OwningProcess, then Get-Process -Id <pid>; macOS/Linux: lsof -i :47822).
  2. Pick a free port. Default suggestion: 47900. Verify it's free: curl -sf http://127.0.0.1:47900/health should fail with connection refused.
  3. Read ~/.claude-mailbox/mailbox.json (create empty {} if missing) and merge {"port": <chosen>}. Write back.
  4. Also write the override into .claude/settings.json env so the plugin's hooks find the right URL:
    "env": { "CLAUDE_MAILBOX_URL": "http://127.0.0.1:<chosen>" }
    
    Merge into existing env, preserving other keys.
  5. Mark restart_needed = true.

Step 3 — daemon autostart and running state

Run: claude-mailbox status

  • Running → ✓ continue.
  • Stoppedclaude-mailbox start, re-check.
  • NotInstalledclaude-mailbox install-autostart, then claude-mailbox start, re-check.

Behavior on install-autostart: The CLI tries a Scheduled Task first (schtasks /RL LIMITED, no admin). If Windows Group Policy returns "Access is denied", it falls back transparently to an HKCU\Software\Microsoft\Windows\CurrentVersion\Run registry entry plus a hidden node serve process — same per-user persistence, no admin needed. The chosen mechanism is recorded in ~/.claude-mailbox/autostart-mode and respected by status/start/stop/uninstall-autostart.

If install-autostart still fails after both attempts (very rare — would mean both schtasks and reg add are blocked), stop and report what status and start printed.

Step 4 — health probe

Hit http://127.0.0.1:<port>/health (use the configured port, not necessarily 47822). Expect a JSON body with "status":"ok" AND a version matching claude-mailbox --version. If unreachable or version mismatch, stop and report.

Step 5 — mailbox identity (base prefix)

No prompt by default. Each Claude Code session gets a unique mailbox name auto-derived from its session_id (e.g., claude-a8b3c1d2).

Read .claude/settings.json and look for env.CLAUDE_MAILBOX_NAME.

  • If set → ✓ "Mailbox prefix is <X>." (real name will be <X>-<short_session_id>).
  • If unset → ✓ "Mailbox name will be auto-derived (claude-<short_session_id>)."

Ask once: "Want to flavor your mailbox names with a memorable prefix (e.g., backend, frontend)? (yes / no / <name>)"

On yes/explicit name: merge env.CLAUDE_MAILBOX_NAME = <name> into .claude/settings.json, preserving other keys. Mark restart_needed = true.

Step 6 — smoke test

Use two ephemeral names — we don't need the real session name here:

claude-mailbox send  --from doctor-probe-a --to doctor-probe-b --body "ping from doctor"
claude-mailbox check --name doctor-probe-b

(If the port was changed in Step 2, pass --url http://127.0.0.1:<port> to both.)

The check output must be a JSON array with one message: from: doctor-probe-a, body matches. ✓ on success, ✗ otherwise.

Step 7 — summary

Claude-Mailbox doctor
  binary:        <version>
  daemon:        Running    (port: <port>, what you did if anything)
  health:        ok
  port conflict: none | resolved (moved from 47822 to <port>)
  base prefix:   <name from settings, or "auto-derived (anonymous)">
  smoke test:    passed | failed
  restart hint:  yes if restart_needed, otherwise no

End with one of:

  • All ✓ and no restart needed → "Setup is healthy. Your mailbox name this session will be revealed by the SessionStart hook on next session start."
  • All ✓ and restart needed → "Restart Claude Code (or open a new session) so the SessionStart hook picks up the new env values."
  • Anything ✗ → "Setup incomplete: ."