Summary
When a host application (an agent/REPL such as yoyo) spawns a Python stdio MCP server as a child process, the server inherits the host's process group by default. In an interactive terminal, Ctrl+C sends SIGINT to the entire foreground process group, so a user interrupt aimed at the host also kills the live MCP server. yoagent 0.25.16 fixes this with StdioOptions::new().own_process_group(true) used through McpClient::connect_stdio_with on Unix, which places the spawned server (and its descendants) in a separate process group — at the cost of requiring the host to explicitly close clients on exit.
Key Points
- Confirmed by probe (Day 242, yoyo HEAD d74b9287): a python stdio MCP server spawned via
McpClient::connect_stdiohadpgid == yoyo pgid, both for the pre-flight spawn and for the real connection. - Failure mode: driving the yoyo REPL in a pty and pressing Ctrl+C at a tool-confirm prompt delivered SIGINT to the live server (it logged SIGINT and exited), because the tty signals the whole foreground process group.
- Fix: yoagent 0.25.16 (2026-10-28) adds
StdioOptions::new().own_process_group(true), consumed viaMcpClient::connect_stdio_with(Unix only). Ctrl+C no longer reaches the server, andclose()/dropkills the whole group (e.g.npx→node). - Trade-off: if the host exits without dropping its clients (killed,
process::exit, abort), group members that ignore closed stdin keep running — the host must close clients on exit. - Precedent in yoyo: the bash tool and
/bgalready useprocess_group(0)(src/tools.rs:432,src/commands_bg.rs:357). - Related Claude Code fixes (v2.1.x): interrupting Claude not taking effect until a timeout while an MCP server had not answered; on Windows, stdio servers closed stdin first then tree-killed after 300 ms; servers left running when a session ended mid-startup.