Skip to content

CLI daemon: keep stdio backends warm across isolated CLI invocations #84

@avelino

Description

@avelino

Problem

mcp serve already does smart resource management — shared backends, lazy init, adaptive idle shutdown, kill_on_drop — but only for clients that stay connected to the proxy (Claude Code, Cursor, Windsurf, etc.). Users running the CLI directly from the terminal get none of that.

Every mcp <server> <tool> ... invocation is a fresh process lifecycle:

  1. Spawn stdio backend (npx -y slack-mcp-server@latest ...).
  2. Wait for initialization (handshake, tool discovery).
  3. Send one tools/call.
  4. Tear everything down.

For stdio backends that are slow to boot — Node/npx packages, Python servers with heavy imports, chrome-devtools/mobile-mcp that hold device sessions — this is pure latency tax on every call, and discards state that is expensive to rebuild (browser tabs, auth handshakes, warm caches inside the server). A script that calls the same server 10 times pays the startup cost 10 times.

It also makes some backends effectively unusable from the CLI: anything that only becomes meaningful after the first call (opened browser, connected device, resolved context) is a cold MCP every time.

Desired outcome

A per-user background daemon that:

  • Keeps warm stdio backends alive between isolated CLI invocations, so mcp slack list_channels followed 2s later by mcp slack send_message reuses the same child process.
  • Participates in the same lifecycle rules mcp serve already has (lazy init, adaptive idle shutdown, zero orphans on restart/crash).
  • Is observable and controllable — start, stop, restart, status, list of managed backends.
  • Is opt-in per server (or per user), so ephemeral one-off calls don't pay for a daemon they don't need.
  • Coexists with mcp serve: if the proxy is already running a backend, the CLI should reuse that instead of spawning a second copy.

Out of scope

  • Exact CLI surface (mcp daemon start|stop|status|...), IPC mechanism (unix socket vs domain socket vs named pipe on Windows), and interaction with mcp serve — to be decided in design.
  • Per-backend lifecycle policy syntax in servers.json (keep-alive vs ephemeral).
  • HTTP backends (not affected — daemon is specifically for stdio).

Related

Prior art

Metadata

Metadata

Assignees

No one assigned

    Labels

    cliCLI commands, flags, and UXenhancementNew feature or improvementperformanceLatency, throughput, resource usageproxyServe/proxy mode (mcp serve)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions