Check existing issues
Describe the bug
Summary
mppx --mcp starts an MCP stdio server, but the process exits before any MCP request can be handled. The root cause is a premature process.exit(0) in dist/bin.js:
// dist/bin.js
#!/usr/bin/env node
import cli from './cli/cli.js';
cli.serve().then(() => process.exit(0));
Under --mcp, cli.serve() eventually awaits server.connect(transport) on StdioServerTransport. StdioServerTransport.start() just registers stdin listeners and resolves synchronously — it does not keep the promise pending for the lifetime of the connection. So cli.serve() resolves on the next microtask, process.exit(0) fires, and the server dies before any initialize request can be read from stdin.
Environment
Link to Minimal Reproducible Example
https://github.com/woven-record-media/mppx-mcp-repro/blob/main/bug1-exit-race.mjs
Steps To Reproduce
Reproduction
printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"t","version":"0"}}}' \
| npx --yes mppx --mcp
Expected: a JSON-RPC response to initialize on stdout.
Actual: the process exits silently with code 0, no response written.
Any MCP client registering npx mppx --mcp as a stdio server sees the subprocess disappear immediately after spawn. In Claude Code, /mcp shows the server as failed/disconnected.
Package Version
[email protected]
Anything else?
Fix
Remove the .then(() => process.exit(0)). Node's stdin listeners keep the event loop alive naturally; the process terminates cleanly when stdin closes. A CLI invocation (non-MCP) still exits promptly because those commands don't register long-lived listeners.
-cli.serve().then(() => process.exit(0));
+await cli.serve();
or equivalently, just:
Verified locally: a wrapper script that imports cli/cli.js directly and calls cli.serve() without the exit handler makes MCP mode reachable (the initialize request round-trips). But see Issue — the server still doesn't work end-to-end because CLI command handlers write their output with console.log instead of returning it through the runtime.
Check existing issues
Describe the bug
Summary
mppx --mcpstarts an MCP stdio server, but the process exits before any MCP request can be handled. The root cause is a prematureprocess.exit(0)indist/bin.js:Under
--mcp,cli.serve()eventually awaitsserver.connect(transport)onStdioServerTransport.StdioServerTransport.start()just registers stdin listeners and resolves synchronously — it does not keep the promise pending for the lifetime of the connection. Socli.serve()resolves on the next microtask,process.exit(0)fires, and the server dies before anyinitializerequest can be read from stdin.Environment
[email protected]Link to Minimal Reproducible Example
https://github.com/woven-record-media/mppx-mcp-repro/blob/main/bug1-exit-race.mjs
Steps To Reproduce
Reproduction
Expected: a JSON-RPC response to
initializeon stdout.Actual: the process exits silently with code 0, no response written.
Any MCP client registering
npx mppx --mcpas a stdio server sees the subprocess disappear immediately after spawn. In Claude Code,/mcpshows the server as failed/disconnected.Package Version
[email protected]
Anything else?
Fix
Remove the
.then(() => process.exit(0)). Node's stdin listeners keep the event loop alive naturally; the process terminates cleanly when stdin closes. A CLI invocation (non-MCP) still exits promptly because those commands don't register long-lived listeners.or equivalently, just:
Verified locally: a wrapper script that imports
cli/cli.jsdirectly and callscli.serve()without the exit handler makes MCP mode reachable (theinitializerequest round-trips). But see Issue — the server still doesn't work end-to-end because CLI command handlers write their output withconsole.loginstead of returning it through the runtime.