Command Palette

Search for a command to run...

UnylyUnyly
Весь каталог

Claude Code Janitor

БесплатноНе проверен

Reaps orphaned Claude Code processes on macOS.

GitHubEmbed

Описание

Reaps orphaned Claude Code processes on macOS.

README

Claude Code Janitor

License: MIT Platform: macOS Ask DeepWiki

A small macOS launchd-scheduled script that reaps orphaned Claude Code processes: the CLI itself, its subagents, and any MCP servers it spawned that didn't shut down cleanly. Safe to run alongside Claude Desktop, Cursor, Codex, and other tools that spawn MCP servers.

Built by a Claude Code user who got tired of finding 13 zombie MCP processes hogging memory after closing a terminal tab. If you run Claude Code regularly and notice your fans spinning hours after you stopped using it, this is for you.

What It Does

Claude Code spawns subagents and MCP server processes. When you close a terminal tab or a session crashes, those children get reparented to launchd (PPID=1) and keep running. In our measurements each one held roughly 44 MB, varying with which MCP servers you use. Multiply by a few days of heavy use and you have a real memory leak.

This script runs every 2 hours, finds those orphans, and kills them. It will not touch:

  • Active Claude Code sessions you are currently running
  • Processes spawned by Claude Desktop, Cursor, Codex, or any other tool
  • Anything that still has a live terminal or pipe attached

It uses four overlapping safety checks (detailed below) so it only kills processes that are 100% orphans of Claude Code specifically.

Quick Start

git clone https://github.com/drewburchfield/claude-code-janitor.git
cd claude-code-janitor
./install.sh

That copies the script to ~/.local/bin/, installs a launchd agent that runs every 2 hours, and starts it immediately.

To remove later:

./install.sh uninstall

How It Works

A process is killed only if it meets all four of these:

Check What it confirms
PPID == 1 The original session is gone. On macOS, launchd is PID 1 and adopts orphaned processes.
CLAUDE_CODE_ENTRYPOINT in env The process was spawned by Claude Code CLI, not Claude Desktop or any other tool.
At least one fd shows (revoked) in lsof The controlling terminal or pipe is gone.
Running ORPHAN_MIN_HOURS+ hours (default 6) Don't touch processes from sessions that just started.

The env var check is the key safety floor. Claude Code injects CLAUDE_CODE_ENTRYPOINT into every subprocess it spawns (subagents, MCP servers, tool executions). Claude Desktop, Cursor, Codex, and other MCP-using tools do not set this variable as of May 2026. If Claude Desktop's behavior ever changes upstream and it begins setting CLAUDE_CODE_ENTRYPOINT, this assumption breaks and the script could start matching Desktop's MCP children. Re-verify before relying on this with new releases of Claude Desktop.

The script also re-verifies the env marker immediately before sending kill -9, to close the small PID-reuse race window between candidate identification and the kill itself.

Configuration

Set these environment variables in your shell profile to tune behavior. All are optional.

Variable Default What it controls
ORPHAN_MIN_HOURS 6 Minimum runtime before a process is eligible. Lower this if you start many short sessions and want faster cleanup.
ORPHAN_WHITELIST (none) Regex matched against the process command line only (not env). Matches are never killed, even if otherwise eligible. Use to protect a specific Claude-spawned process you intentionally keep running.
DRY_RUN 0 Set to 1 to print what would be killed without killing. Same code path as a real run, so the preview never drifts from actual behavior.

Example: faster cleanup for short-session workflows.

export ORPHAN_MIN_HOURS=1

Compatibility

  • macOS (Apple Silicon and Intel)
  • Bash 3.2+ (the version that ships with macOS)
  • Claude Code CLI installed via npm, brew, or the official installer

Not tested on Linux. Likely porting concerns: the etime field formatting from ps (locale-sensitive on some distros), the BSD-specific (revoked) string in lsof output (Linux lsof reports closed terminals differently), and the default destination of logger (syslog vs. journald).

Troubleshooting

Verify the launch agent is loaded:

launchctl list | grep kill-orphan-claude

Check what the last run did:

log show --predicate 'eventMessage contains "kill-orphan-claude"' --last 1d

Every run emits a single heartbeat line at the end with scanned, killed, and refused counts. If you see the heartbeat but killed=0 for days while you know orphans exist, jump to the next section.

Suspect the script is running but not finding orphans:

The detection relies on ps eww -o command= showing the environment block of each candidate process. On stricter macOS configurations (hardened runtime, certain code-signing states, or processes owned by another user), ps can return the command line without the env, and the script will silently treat those processes as not Claude orphans. To check whether this is happening:

# Pick any PPID=1 process you suspect is a Claude orphan
ps eww -o command= -p <pid> | tr ' ' '\n' | grep -E "^CLAUDE_|^ANTHROPIC"

If that returns nothing for a process you know was spawned by Claude Code, ps cannot read its environment from your shell context. The script will not be able to identify it as an orphan either.

See what the script would kill right now without killing anything:

DRY_RUN=1 ~/.local/bin/kill-orphan-claude.sh

This applies the same four safety checks as a real run and prints what would have been killed. Always matches actual behavior because it's the same script.

Run manually:

~/.local/bin/kill-orphan-claude.sh

Heard EPERM in the logs?

The script logs REFUSED to kill PID X (EPERM, candidate logic let through a process we can't kill) if kill -9 ever returns "Operation not permitted." This should never happen for a process you own. If you see it, something let a non-Drew, non-Claude process through the candidate logic. Open an issue with the log line.

Manual Cleanup

If you want to reap right now without waiting for the scheduled run:

# Preview first
DRY_RUN=1 ~/.local/bin/kill-orphan-claude.sh

# Then actually kill
~/.local/bin/kill-orphan-claude.sh

Background

The orphaned process problem in Claude Code has been tracked across several upstream issues:

  • #22612 MCP servers not cleaned up when sessions end
  • #33947 MCP server and subagent processes not cleaned up on session end, observed PPID=1 accumulation on macOS (a heavy user reports ~107 unsigned node processes orphaned in a single workday)
  • #40667 MCP server processes leak on host after subagent/session termination

Per-orphan memory varies with which MCP servers you use. In our measurements ~44 MB is typical.

Development

The project is two files plus a launchd plist:

scripts/kill-orphan-claude.sh                   # The reaper
launchagents/com.user.kill-orphan-claude.plist  # Runs it every 2 hours
install.sh                                      # Copies them into place

To test changes:

# Edit scripts/kill-orphan-claude.sh
DRY_RUN=1 bash scripts/kill-orphan-claude.sh    # Preview without killing
./install.sh                                    # Reinstall and reload the agent

License

MIT

from github.com/drewburchfield/claude-code-janitor

Установка Claude Code Janitor

У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.

▸ github.com/drewburchfield/claude-code-janitor

FAQ

Claude Code Janitor MCP бесплатный?

Да, Claude Code Janitor MCP бесплатный — установка в пару кликов через Unyly без оплаты.

Нужен ли API-ключ для Claude Code Janitor?

Нет, Claude Code Janitor работает без API-ключей и переменных окружения.

Claude Code Janitor — hosted или self-hosted?

Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.

Как установить Claude Code Janitor в Claude Desktop, Claude Code или Cursor?

Открой Claude Code Janitor на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.

Похожие MCP

Compare Claude Code Janitor with

Не уверен что выбрать?

Найди свой стек за 60 секунд

Автор?

Embed-бейдж для README

Похожее

Все в категории development