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.
114 lines
5.7 KiB
Markdown
114 lines
5.7 KiB
Markdown
---
|
|
description: Diagnose and auto-fix the Claude-Mailbox setup (binary install, port-conflict detection, daemon autostart, smoke test, optional base-prefix).
|
|
allowed-tools: 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 response** → **port 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:
|
|
```json
|
|
"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.
|
|
- `Stopped` → `claude-mailbox start`, re-check.
|
|
- `NotInstalled` → `claude-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: <first failure>."
|