@mrrlin-dev/mcp 0.2.6 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -0
- package/dist/bin.cjs +3748 -389
- package/dist/prompts/report-issue.md +33 -191
- package/package.json +11 -7
- package/scripts/postinstall-restart.cjs +103 -0
package/README.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# `@mrrlin-dev/mcp` — Mrrlin Director Bridge
|
|
2
|
+
|
|
3
|
+
CLI that runs the local Director bridge under PM2 and forwards chat turns to a locally-spawned Codex `app-server`. Installed globally on operator boxes via `pnpm install -g @mrrlin-dev/mcp`.
|
|
4
|
+
|
|
5
|
+
## Self-update & process hygiene
|
|
6
|
+
|
|
7
|
+
The bridge auto-picks up new `@mrrlin-dev/mcp` versions after `pnpm install -g`. No manual `pm2 restart` is required.
|
|
8
|
+
|
|
9
|
+
### How it works
|
|
10
|
+
|
|
11
|
+
- **L1 (self-update loop):** every 15 minutes (env-tunable) the bridge hashes its own `bin.cjs` and, on change, drains the current Codex turn cleanly and exits via `bridgeShutdown`. PM2 restarts. New code loads.
|
|
12
|
+
- **L2 (postinstall nudge):** `pnpm install -g @mrrlin-dev/mcp@latest` triggers a `SIGUSR2` to every running PM2 bridge, collapsing the L1 wait to seconds.
|
|
13
|
+
- **L3 (in-chat update offer):** every 6 hours the bridge checks `https://registry.npmjs.org/@mrrlin-dev/mcp/latest`. When a newer version is published, on your next chat turn the Director asks: *"Бачу що bridge на X, на npm уже Y — оновити зараз?"*. Say "yes" → Director runs `pnpm install -g @mrrlin-dev/mcp@latest` itself. 48h cooldown if you decline.
|
|
14
|
+
- **L4 (process hygiene):** the bridge refuses to start a second instance on the same port and warns about orphan `mrrlin-mcp director-bridge` processes at startup.
|
|
15
|
+
|
|
16
|
+
### Env tuning
|
|
17
|
+
|
|
18
|
+
| Env var | Default | Purpose |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| `MRRLIN_DIRECTOR_BRIDGE_SELF_UPDATE` | (unset = on) | Set `0` to disable L1 (and silence L2 SIGUSR2 effect). |
|
|
21
|
+
| `MRRLIN_DIRECTOR_BRIDGE_SELF_UPDATE_INTERVAL_MS` | `900000` (15 min) | L1 hash-check interval. |
|
|
22
|
+
| `MRRLIN_DIRECTOR_BRIDGE_REGISTRY_POLL_INTERVAL_MS` | `21600000` (6 h) | L3.1 npm registry poll interval. |
|
|
23
|
+
| `MRRLIN_DIRECTOR_BRIDGE_UPDATE_COOLDOWN_MS` | `172800000` (48 h) | L3.2 in-chat update-offer cooldown. |
|
|
24
|
+
| `MRRLIN_MCP_POSTINSTALL_SKIP` | unset | Set `1` to skip the postinstall SIGUSR2 nudge. |
|
|
25
|
+
| `CI` | unset | Set `1` to skip the postinstall nudge in CI. |
|
|
26
|
+
|
|
27
|
+
### PM2 ecosystem (automatic via `mrrlin-mcp install-service`)
|
|
28
|
+
|
|
29
|
+
`mrrlin-mcp install-service` writes `~/.mrrlin/ecosystem.config.cjs` automatically. The generated config already includes `kill_timeout: 10000` so the bridge has 10s to drain cleanly before PM2 SIGKILLs. Reference shape:
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
module.exports = {
|
|
33
|
+
apps: [{
|
|
34
|
+
name: "mrrlin-bridge",
|
|
35
|
+
script: "mrrlin-mcp",
|
|
36
|
+
args: "director-bridge",
|
|
37
|
+
interpreter: "none",
|
|
38
|
+
cwd: "<repo cwd>",
|
|
39
|
+
autorestart: true,
|
|
40
|
+
max_restarts: 10,
|
|
41
|
+
restart_delay: 3000,
|
|
42
|
+
kill_timeout: 10000,
|
|
43
|
+
env: { /* ... */ },
|
|
44
|
+
}],
|
|
45
|
+
};
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Verifying the self-update path is wired
|
|
49
|
+
|
|
50
|
+
Tail the bridge logs after a fresh start:
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
pm2 logs mrrlin-bridge --lines 50 | grep "bridge.self_update.startup"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Expect a JSON-fielded line including `version`, `binSha`, `selfUpdateEnabled`, `intervalMs`. Any non-default tuning shows up here.
|
|
57
|
+
|
|
58
|
+
### One-time cleanup for zombie processes
|
|
59
|
+
|
|
60
|
+
If you see multiple `mrrlin-mcp director-bridge` processes accumulating (`pgrep -f "mrrlin-mcp director-bridge"` returns > 1 PID), run once:
|
|
61
|
+
|
|
62
|
+
```sh
|
|
63
|
+
pm2 stop mrrlin-bridge
|
|
64
|
+
pkill -f "mrrlin-mcp director-bridge" || true
|
|
65
|
+
sleep 2
|
|
66
|
+
pm2 start ~/.mrrlin/ecosystem.config.cjs
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
This is only needed for the legacy population (bridges started before this self-update mechanism shipped). New installs won't produce zombies thanks to L1's `bridgeShutdown` exit path.
|
|
70
|
+
|
|
71
|
+
### Update offer UX (L3) — what the operator sees
|
|
72
|
+
|
|
73
|
+
When a newer `@mrrlin-dev/mcp` is published and your bridge polls (within 6h):
|
|
74
|
+
|
|
75
|
+
1. On your next chat turn, the Director weaves a yes/no question in: *"Бачу що bridge на X, на npm уже Y — оновити зараз? (запущу `pnpm install -g @mrrlin-dev/mcp@latest`)"*
|
|
76
|
+
2. You reply "yes" / "так" / "ага" → Director runs the install via its shell tool, reports stdout + exit code in chat.
|
|
77
|
+
3. L1 picks up the new `bin.cjs` (or L2 SIGUSR2 nudges it sooner) → drain-on-quiet → PM2 restart → web reconnects.
|
|
78
|
+
4. You reply "later" → Director acknowledges and drops it for 48h.
|
|
79
|
+
5. If the install fails (sudo, registry pin, network) → Director shows the error verbatim plus the manual command.
|
|
80
|
+
|
|
81
|
+
The Director **never installs without explicit confirmation**.
|