2d783a15eb
Every stdio MCP server was wrapped in its own CPython watchdog that polled getppid() every 2s to notice an ungraceful Hermes exit (kill -9, OOM, crash, force-quit), since macOS has no PR_SET_PDEATHSIG. That is a whole interpreter per server for a job that does nothing until the moment Hermes dies: 10.1 MB physical footprint each, measured on macOS/arm64. Replace the fleet of pollers with a single supervisor per Hermes process holding the read end of a pipe only Hermes writes to. Death detection becomes EOF on that pipe -- exact and instant, rather than up to a poll interval late. Hermes sends `register <pgid>` / `unregister <pgid>` as servers come and go; on EOF the supervisor killpg's whatever is still registered, which is exactly the set whose teardown never ran. A clean shutdown unregisters as it goes, so EOF then finds nothing to kill. Servers are now spawned unwrapped. The MCP SDK already starts each stdio child in its own session, so the pgid recorded for killpg is the server's own group and the existing cleanup paths reach it unchanged. That also deletes the signal-forwarding layer the wrapper needed: wrapping had put the real server in a different session from the pgid being tracked, so a graceful killpg would have hit only the wrapper. Measured on a 5-gateway host: 10 watchdogs (~98 MB) -> 5 supervisors (~49 MB). One supervisor costs about what one watchdog did (9.9 vs 10.1 MB), so the win is (servers_per_process - 1) x ~10 MB, and a process with no stdio servers now spawns nothing at all. The supervisor reads length-capped lines rather than iterating the stream: a writer that never sends a newline would otherwise grow it without bound, which it must not be vulnerable to when it is the last defense against leaked servers. Found by feeding it /dev/zero, where it reached 15 GB. Verified beyond unit coverage: a real stdio MCP server connects and its tools are discovered on the unwrapped path; with a live Hermes holding a real connection, kill -9 reaped the server, its grandchild (in the server's group, the mcp-remote `node` case), and the supervisor exited on its own. The reap tests were sabotage-checked in both directions -- a no-op reaper fails all three, while the test pinning that a cleanly unregistered server survives keeps passing -- and each wiring half fails independently when removed. (cherry picked from commit a252d4ce7ff1722f687635fdbf0cff79f538c3f1)