Uninstall Mac apps — leftovers and all.
A free, open-source, native macOS app uninstaller — inspired by FreeMacSoft's AppCleaner.
Dragging an app to the Trash leaves gigabytes of junk behind in ~/Library.
AppCleaner finds all of an application's related files and removes them
together with the app, safely, via the Trash.
Built with Swift + SwiftUI. No dependencies, no telemetry, no nonsense.
- Drag & drop an app onto the window (or onto the Dock icon) to scan it
- Browse & search every app installed in
/Applicationsand~/Applications - Thorough leftover detection across the user and system domains:
Application Support(including vendor subfolders likeGoogle/Chrome)ContainersandGroup ContainersCaches,HTTPStorages,WebKit,CookiesPreferences(includingByHost)Saved Application State,Autosave InformationLogs,DiagnosticReports,CrashReporterLaunchAgentsandLaunchDaemons(matched by file name and plist contents)Application Scripts- Package receipts in
/private/var/db/receipts
- Matches by bundle identifier, app name, and executable name — conservatively, to avoid false positives
- Shows the size of every item, grouped by category, all checked by default
- Warns when the app is still running and lets you quit it first
- Deletes by moving to the Trash (recoverable); root-owned files can optionally be removed with an administrator prompt
- A built-in safety net refuses to touch anything outside
~/Library,/Library,/Applications,~/Applicationsand receipt files - Bonus: a CLI mode for scripting —
AppCleaner --scan /Applications/Foo.appprints everything it would find, without deleting anything
Download the latest AppCleaner-<version>.zip from the
releases page, unzip it and
drag AppCleaner.app to /Applications. Each release lists the archive's
SHA-256 checksum and the exact build commit; verify what you're running with
AppCleaner --version.
Or build from source (macOS 13+, Xcode command line tools):
git clone https://github.com/popyapp/app_cleaner.git
cd app_cleaner
make app # builds build/AppCleaner.app
open build # then drag AppCleaner.app to /ApplicationsOr during development:
swift run AppCleaner # run the GUI
swift run AppCleaner --scan /Applications/Foo.app # dry-run scan from the terminal- Everything is moved to the Trash first — nothing is permanently deleted unless you explicitly confirm the administrator fallback for root-owned files.
- The scanner only ever suggests files matching the app's bundle identifier or full name; short/generic names are excluded from name matching.
- The remover refuses paths outside the known Library/Applications locations.
Still: review the list before clicking Remove. It's your disk.
AppCleaner doubles as an MCP server: run the
binary with the --mcp flag and it speaks JSON-RPC over stdio, so any
MCP-capable AI agent (Claude Code, Claude Desktop, Cursor, ...) can list, scan
and uninstall applications directly — no GUI needed, no extra dependencies.
Claude Code:
claude mcp add appcleaner -- /Applications/AppCleaner.app/Contents/MacOS/AppCleaner --mcpAny other MCP client, via the standard stdio server config:
{
"mcpServers": {
"appcleaner": {
"command": "/Applications/AppCleaner.app/Contents/MacOS/AppCleaner",
"args": ["--mcp"]
}
}
}Then just ask your agent: "uninstall MacDown and all its leftovers" or "which of my installed apps has the largest leftovers?".
| Tool | Arguments | Description |
|---|---|---|
list_apps |
— | List installed apps (name, bundle id, version, path) |
scan_app |
app |
Read-only: report every related file with category, size and whether removal needs elevated access |
uninstall_app |
app, confirm |
Move the app bundle and all leftovers to the Trash |
remove_paths |
app, paths, confirm |
Remove a subset of an app's files (e.g. only caches) |
The app argument accepts a path to a .app bundle, a bundle identifier, or
an app name (fuzzy-matched; ambiguous names are rejected with the candidate
list). Results are returned as structured JSON, including per-item
size_bytes, category and needs_admin.
On top of the general safety guarantees above:
- Destructive tools require an explicit
confirm: trueargument — a bare call returns an instructive error instead of deleting anything remove_pathsonly accepts paths the scanner itself reported for that app; arbitrary paths are refused, so a confused agent cannot delete unrelated filesuninstall_apprefuses to run while the target app is running- The app bundle is trashed last and kept if any leftover was blocked, so a re-scan can finish the job after permissions are fixed
- Everything still goes to the Trash, so any mistake is recoverable
- If macOS privacy protection (TCC) blocks an item, the response includes a hint explaining the Full Disk Access fix instead of a bare failure
macOS protects app sandbox containers (~/Library/Containers,
~/Library/Group Containers) with privacy controls (TCC). Not even
administrator rights can bypass this — sudo rm fails with
"Operation not permitted".
To let AppCleaner remove those items:
- Open System Settings → Privacy & Security → Full Disk Access
- Add (or enable) AppCleaner
- Relaunch AppCleaner and remove the items again
AppCleaner detects this itself: it shows a banner when a scan finds protected containers, and if a removal is blocked it offers to open the right settings pane. When some leftovers are blocked, the app bundle is deliberately kept so you can re-scan and finish the job afterwards.