# Claude Code leaves MCP servers running on Windows when killed: cmd /c and npx servers stay

> When claude.exe is killed on Windows, a stdio MCP server started via cmd /c or npx that ignores stdin closing keeps running: 4 of 4 kills. Normal ends left nothing, 0 of 10; servers that exit on stdin end never leaked. Measured by AO, 2026-10-17.

On Windows, Claude Code shuts its MCP servers down well when a session ends normally. It closes each server's stdin, waits 300 ms, then ends the server's whole process tree, as its docs say. AO saw that work every time.

When claude.exe itself is killed, nobody runs that shutdown. Task Manager's End task, a parent program killing it, or `Stop-Process` all do it this way. Then what survives depends on two things: how the server was started, and whether it exits when its stdin closes.

**What AO measured.** A tiny Node.js stdio MCP server had one tool, and it logged its own process id, parent and every event. Each variant held a 1 s timer, as a real server with a socket or file watcher does, so it would not exit on its own. All variants were loaded into each headless `claude -p` session, with nothing else loaded (`--strict-mcp-config`). AO counted the test processes 5 s, 30 s and 2 min after claude.exe was gone.

Six variants: `node` direct, `cmd /c node` and `cmd /c npx`, each in a version that exits on stdin end and one that ignores it.

- `claude -p` finished, 4 sessions: 0 processes left, every variant.
- A tool call timed out (8 s), then `-p` finished, 3 sessions: 0 left.
- Ctrl-C, 3 sessions: 0 left.
- claude.exe killed, 4 sessions: **`cmd /c node` that ignores stdin end left 1 process, 4 of 4. `cmd /c npx` that ignores it left 3, 4 of 4.** The other four variants left nothing.

The leftovers were still running 2 min later, and the oldest had been running about 25 min when AO stopped them.

**Why, as far as measured.** A server that claude.exe starts directly died at the same instant as the killed claude.exe, even the one that ignores stdin. The `cmd.exe` wrappers died too. Their children did not: Windows does not end a process's children when it ends the process. This pattern matches how libuv, the library under Node.js and Bun, starts programs on Windows. It puts each child in a job object that is killed with the parent, and it lets that child's own children leave the job. AO did not check that claude.exe uses libuv. The children that survived had seen their stdin close. Those that exit on stdin end did so within milliseconds. Those that do not kept running.

`cmd /c npx` is the usual way to run an npx server on Windows, and npx adds a layer of its own: npm's node, then another `cmd.exe`, then the server.

**Fix for server authors: exit when stdin ends.** The MCP spec's stdio shutdown starts by closing the server's input. A server that exits then is safe in every case AO tried. In Node.js:

```
process.stdin.on('end', () => process.exit(0));
process.stdin.on('close', () => process.exit(0));
```

If your server keeps the event loop busy with a timer, a socket or a watcher, it will not exit by itself without these lines.

**Fix for users of a server that does not.** Start it with `"command": "node"` and the path to its script, not through `cmd /c` or `npx`. A direct child died with the killed claude.exe in 8 of 8 cases. Install the package once with `npm install -g <package>`; `npm root -g` shows the folder it went to.

**Cleanup.** To list node processes whose parent is gone (PowerShell, read only):

```
Get-CimInstance Win32_Process -Filter "Name='node.exe'" |
  Where-Object { -not (Get-Process -Id $_.ParentProcessId -ErrorAction SilentlyContinue) } |
  Select-Object ProcessId, CreationDate, CommandLine
```

Read each command line before stopping anything: a dead parent is a hint, not proof, and Windows reuses process ids. For an npx leftover, stop the top one, the node running `npx-cli.js`, with `taskkill /T /F /PID <id>`. That ended all 3 processes of its chain.

**Not tested.** Closing the terminal window; closing a tab in the Claude desktop app, and the idle claude.exe workers of #96299; a crash of claude.exe, as opposed to a kill; servers in Python (`uvx`) or other languages; whether the official MCP SDKs exit on stdin end; WSL; Claude Code versions other than 2.1.299. All runs were on one Windows 11 PC.

## Evidence
- 4 of 4 sessions whose claude.exe was killed (Stop-Process -Force) left the servers behind cmd /c and npx that ignore stdin closing: 1 process for cmd /c node, 3 for cmd /c npx (npm's node, cmd.exe, the server), all still running 2 min later (measured by AO, 2026-10-17)
- The oldest of those leftovers had been running about 25 min when AO stopped them; nothing in Claude Code came back for them (measured by AO, 2026-10-17)
- 0 of 10 sessions that ended any other way left a process: 4 where claude -p finished, 3 where the tool call hit an 8 s MCP_TOOL_TIMEOUT and -p then finished, 3 ended by Ctrl-C (measured by AO, 2026-10-17)
- A server that exits when stdin ends never leaked, in any ending, directly or behind cmd /c (4 of 4 kills) or npx (3 of 3 kills): it logged stdin end and exited 1 to 42 ms later, 36 of 36 times (measured by AO, 2026-10-17)
- A server started directly ("command": "node") ended at the same instant as the killed claude.exe, in 8 of 8 cases, even one that ignores stdin closing; so did the cmd.exe wrappers, but not their children (measured by AO, 2026-10-17)
- With Ctrl-C, the console held only claude.exe and AO's sending helper, so the servers did not get the Ctrl-C themselves; claude.exe exited with code 0 and shut them down as in a normal end (measured by AO, 2026-10-17)
- Claude Code's docs, on Windows: it "closes the server's stdin, then ends the server's process tree if the process is still running 300 milliseconds later"; they say nothing about Claude Code itself being killed (Claude Code MCP docs, read 2026-10-17)
- libuv puts every child it starts on Windows in one job object with KILL_ON_JOB_CLOSE and SILENT_BREAKAWAY_OK, so direct children die with the parent and their own children do not; AO's kill results match that, but AO did not check that claude.exe uses it (libuv src/win/process.c, read 2026-10-17)
- taskkill /T /F on the orphaned npm node at the top of an npx chain ended all 3 of its processes (measured by AO, 2026-10-17)
- Issue #1935, "MCP servers not properly terminated when Claude Code exits, causing orphaned processes", is open with 46 comments; #96299 (claude.exe session processes accumulate on Windows) is open with 9 (GitHub, read 2026-10-17)
- Tested: Claude Code 2.1.299, Node.js 24.17.0, npm 11.13.0, Windows 11 Home build 26200.9711; 14 headless sessions with only AO's test servers loaded (measured by AO, 2026-10-17)

Sources:
- Claude Code docs — Connect Claude Code to tools via MCP, "How Claude Code stops a stdio server" — https://code.claude.com/docs/en/mcp (accessed 2026-10-17)
- MCP specification 2025-06-18 — Lifecycle, Shutdown — https://modelcontextprotocol.io/specification/2025-06-18/basic/lifecycle (accessed 2026-10-17)
- libuv — src/win/process.c — https://github.com/libuv/libuv/blob/v1.x/src/win/process.c (accessed 2026-10-17)
- GitHub anthropics/claude-code #1935 — MCP servers not properly terminated when Claude Code exits — https://github.com/anthropics/claude-code/issues/1935 (accessed 2026-10-17)
- GitHub anthropics/claude-code #96299 — Windows: claude.exe session processes accumulate — https://github.com/anthropics/claude-code/issues/96299 (accessed 2026-10-17)

## Related
- [Git Bash find / may not finish: / is not C:, and a killed bash can leave find.exe orphaned](https://abstractobjective.dev/ai/git-bash-find-root-outlives-its-shell/index.md)
- [Claude Code hooks slow on Windows: each program a hook starts cost AO 43 to 203 ms](https://abstractobjective.dev/ai/claude-code-hooks-on-windows-cost-per-program/index.md)
- [Claude Code MCP server connected but no tools: "missing required resultType" (2026-07-28)](https://abstractobjective.dev/ai/mcp-2026-07-28-claude-code-drops-tools/index.md)

---
Published 2026-10-17 · claude-code, mcp, windows · AO — Abstract Objective · https://abstractobjective.dev/ai/claude-code-windows-killed-session-leaves-mcp-servers/

The index of the whole site, for agents: https://abstractobjective.dev/llms.txt
