Windows: MCP server processes not terminated when scheduled/cron sessions end

Resolved 💬 3 comments Opened Mar 27, 2026 by MikeHigman Closed Apr 27, 2026

Windows: MCP server processes not terminated when scheduled/cron sessions end

Description

On Windows, when Claude Code sessions spawned by scheduled tasks (cron jobs via the scheduled-tasks MCP) complete, the parent claude.exe --output-format stream process does not exit. This keeps all MCP server child processes alive as zombies, consuming CPU and memory indefinitely.

Environment

  • OS: Windows 11 Home 10.0.26200
  • Claude Code: 2.1.78
  • MCP servers configured: hardened-google-workspace (Python/uv), clickup (Node.js), shopify-dev-mcp (Node.js), sequential-thinking (Node.js via npx)

Steps to Reproduce

  1. Configure MCP servers in .mcp.json (both Python and Node.js based)
  2. Create a scheduled task via the scheduled-tasks MCP (e.g., email triage running 3x daily)
  3. Let the scheduled task run and complete successfully
  4. Check running processes afterward

Expected Behavior

When a scheduled Claude Code session completes its task, the claude.exe --output-format stream process should exit cleanly and terminate all child MCP server processes.

Actual Behavior

The claude.exe --output-format stream process remains alive after the session completes. All MCP server child processes (spawned via cmd.exe intermediaries) continue running. Each session leaves behind ~10 orphaned processes:

  • 3x cmd.exe (MCP launchers)
  • 3-4x node.exe (Node.js MCP servers)
  • 1-2x python.exe (Python MCP servers)
  • 1x conhost.exe

With 3 cron runs per day, this accumulates ~30 zombie processes daily until the machine is rebooted or processes are manually killed.

Process Tree Evidence

Active interactive session has bash.exe children (the shell used for tool execution). Zombie cron sessions retain only their MCP server processes -- the bash shells exit when the task completes, but the parent claude.exe and its MCP children do not.

# Zombie session (cron-spawned, task completed):
claude.exe --output-format stream  (PID 25664, still running)
  -> conhost.exe
  -> cmd.exe (clickup MCP launcher)
     -> node.exe (clickup-mcp-server)
  -> cmd.exe (sequential-thinking launcher)
     -> node.exe (npx)
        -> cmd.exe -> node.exe (actual server)
  -> cmd.exe (shopify-dev-mcp launcher)
     -> node.exe (shopify-dev-mcp)

# Active interactive session (for comparison):
claude.exe --output-format stream  (PID 35256, actively in use)
  -> bash.exe (tool execution shell)  <-- this is missing from zombies
  -> [same MCP server tree as above]

Impact

Each orphaned Python MCP process consumes ~6% CPU. Node.js processes are lighter but still accumulate. On a machine with 16GB RAM running multiple daily cron jobs, this causes noticeable performance degradation within hours.

Workaround

I created a PowerShell scheduled task that runs every 30 minutes, detects zombie claude.exe sessions (those with no bash.exe descendants and older than 10 minutes), and kills them along with their entire process tree. Happy to share if others hit this.

Suggestion

On Windows, Claude Code should either:

  1. Use Windows Job Objects to group the session process and its MCP children, so they terminate together
  2. Explicitly kill child processes on session exit
  3. Set MCP server processes to terminate when their stdin pipe closes (which would happen naturally when the parent exits)

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗