How to find and kill orphaned Claude Code processes on a Mac

When a Claude Code session ends, the processes it started do not always end with it. Subagents, MCP servers and dev servers can keep running for hours, each holding memory and sometimes a port. This guide shows how to find those leftovers on macOS, check that they really are leftovers, and stop them without hitting anything you still need.

What an orphaned process is

Every process on macOS has a parent. When the parent exits first, the child is not stopped. It is handed to launchd, the process with pid 1, and keeps running. That child is now an orphan: nothing that knows about it is still alive, so nothing will stop it.

With Claude Code this happens more than you would expect. Closing a terminal tab instead of exiting the session, a crash, or quitting the Claude desktop app can all leave processes behind. It is a well-reported problem; see for example Claude Code issues #21305 (memory growing past 10 GB on macOS), #33947 (MCP servers and subagents not cleaned up on session end) and #19201 (processes left after quitting the desktop app).

What usually gets left behind

  • Subagent sessions. Extra claude processes started for parallel work. The cc-reaper project measures these at roughly 180 to 300 MB each.
  • MCP servers. Usually node, npx, uvx or python processes. Each session starts its own set, so they add up quickly.
  • Dev servers and watchers the agent started in the background: vite, next dev, storybook, test runners in watch mode. These often hold a port.
  • Browser automation. Headless Chrome or Chrome for Testing started by a browser MCP server.

Step 1: list everything Claude Code is running

Open Terminal and run:

ps -axo pid,ppid,pgid,etime,rss,%cpu,command | grep -iE '[c]laude|[m]cp'

The columns are the process id, its parent's id, its process group, how long it has been running, its resident memory in kilobytes, its CPU use, and the full command. The square brackets in the pattern stop grep from matching itself.

Step 2: narrow it down to orphans

Orphans have a parent id of 1. Filter for those:

ps -axo pid,ppid,etime,rss,command | awk '$2 == 1' | grep -iE '[c]laude|[m]cp|[n]ode|[v]ite'

A parent id of 1 is not proof on its own. On macOS every app you open and every background service also has launchd as its parent. Only treat a process as a leftover when the command clearly belongs to an agent session and it has outlived the session that started it.

Step 3: check what a process is before you stop it

For each candidate, three quick checks tell you whether it is safe to stop:

# When it started
ps -o lstart= -p <PID>

# Which folder it works in (the project it belongs to)
lsof -a -d cwd -p <PID>

# Which ports it is listening on
lsof -nP -a -p <PID> -iTCP -sTCP:LISTEN

If it started with a session you have already closed, works in that session's project, and is not serving anything you are using, it is a leftover.

Step 4: stop it, and its children

Ask it to exit first, then force it if it is still there a few seconds later:

kill <PID>
sleep 3
kill -9 <PID> 2>/dev/null

An MCP server or dev server often has children of its own. Check with pgrep -lP <PID>. If it has any, stopping only the top process orphans them in turn. Use the approach in how to kill a whole process tree on macOS instead.

Keeping it from happening again

  • End sessions with /exit rather than closing the terminal window. Closing the terminal is one of the documented ways processes get orphaned (issue #21287).
  • Disable MCP servers you do not use in a project. Every enabled server runs once per session, so trimming the list cuts the leftovers too. claude mcp list shows what is configured.
  • Add a cleanup hook. Claude Code can run a command when a session stops; the open-source cc-reaper project ships one, plus a LaunchAgent that sweeps orphans on a schedule.
  • Check now and then, especially after a crash, a forced quit or a long day of parallel sessions. If you would rather see it at a glance, our comparison of cleanup tools covers the options.

How Agents Monitor handles orphans

Agents Monitor follows each agent's process tree while it runs, so when the agent exits it already knows which processes were its children. Those trees are marked Orphaned in the sidebar. One confirmed click on Clean stops them, and it only ever touches leftovers of agents that have already exited.

If you want it hands-off, opt-in auto-kill waits until an orphaned tree sits idle, then counts down for at least 10 seconds before stopping it. You can cancel any countdown, and anything running in your terminal's foreground is skipped.