macOS only

Your entire iCloud,
from the terminal.

icloudcli reads your on-device data directly — Photos, Messages, Contacts, Notes, Reminders, Calendar, and Safari. No API token, no login, no cloud round-trip. Find storage hogs, search every conversation and note, audit your reminders, and pipe it all to jq or any AI agent with --agent JSON.

Quick Install

curl -fsSL https://icloudcli.com/install.sh | sh

Open Source · Apache-2.0

What you can do with icloudcli

Every command runs locally against your on-device databases — no network, no app launch. Pipe to jq or use --agent to wire it into any AI workflow.

Find your heaviest files
Every row includes the UUID — copy it straight into photos delete to free space without ever opening Photos.app.
Live
$ icloud-pp-cli photos top --limit 5
 
# Type Size Date Filename UUID
1 video 9.78 GB 2025-06-19 IMG_2898.MOV 6799AE02-EE45-4469-8AC9-1443582A828E
2 video 4.13 GB 2025-06-28 IMG_2901.MOV C625E37E-F406-435E-B274-67088D9ABF5E
3 video 3.96 GB 2026-05-01 IMG_3668.MOV 4D1C6E68-861D-4512-B09E-5E3D81571A1D
4 video 2.47 GB 2025-01-15 IMG_1262.MOV 02CB886E-51C1-4ED1-81E1-25F1EB275B0D
5 photo 0.84 GB 2024-08-03 RAW_2024-08-03.dng 1A2B3C4D-5E6F-7890-ABCD-EF1234567890
Delete by UUID — no Photos.app needed
Grab UUIDs from photos top, pass them to photos delete. Always a dry run until you add --confirm. Items stay in Recently Deleted for 30 days — fully recoverable.
Live
$ icloud-pp-cli photos delete \ 6799AE02-EE45-4469-8AC9-1443582A828E \ C625E37E-F406-435E-B274-67088D9ABF5E
 
2025-06-19 IMG_2898.MOV 9.78 GB
2025-06-28 Screen Recording 2025-06-28 at 4.30.51 PM.mov 4.13 GB
 
Dry run — 2 item(s) would be moved to Recently Deleted.
Add --confirm to proceed.
 
$ icloud-pp-cli photos delete --confirm \ 6799AE02-EE45-4469-8AC9-1443582A828E \ C625E37E-F406-435E-B274-67088D9ABF5E
 
✓ moved to Recently Deleted: IMG_2898.MOV
✓ moved to Recently Deleted: Screen Recording 2025-06-28 at 4.30.51 PM.mov
 
Done — 2 moved, 0 failed.
Open Photos.app → Recently Deleted → Empty to permanently free space.
Export originals from iCloud to a local folder
Downloads originals via Photos.app — even items stored only in iCloud (Optimize Mac Storage). Pipe UUIDs from any read command, or use --sensitive to batch-export nudity-flagged content (requires --confirm). Each file is renamed to its UUID for easy downstream scripting.
Live
$ icloud-pp-cli photos top --type video --limit 3 --json \ | jq -r '.[].uuid' \ | xargs icloud-pp-cli photos download --output ~/Desktop/export
 
Exporting 3 item(s) to /Users/matias/Desktop/export
 
→ IMG_2898.MOV 9.78 GB
→ IMG_2901.MOV 4.13 GB
→ IMG_3668.MOV 3.96 GB
 
[1/3] IMG_2898.MOV … ✓ → 6799AE02-EE45-4469-8AC9-1443582A828E.mov
[2/3] IMG_2901.MOV … ✓ → C625E37E-F406-435E-B274-67088D9ABF5E.mov
[3/3] IMG_3668.MOV … ✓ → 4D1C6E68-861D-4512-B09E-5E3D81571A1D.mov
 
Done — 3 exported, 0 failed.
Files saved to: /Users/matias/Desktop/export
Pick the right iCloud storage plan
Know your actual library size before upgrading. One number tells you whether you need 200 GB or 2 TB.
Live
$ icloud-pp-cli photos stats --agent | jq '{ items: .total_items, size_gb: .total_size_gb }'
{
"items": 129464,
"size_gb": 794.31
}
 
→ You need the 2 TB plan.
Find which years are eating the most space
Spot the year that ballooned your library — usually the year you got a new iPhone.
Live
$ icloud-pp-cli photos storage --agent | jq '.by_year | sort_by(-.size_gb) | .[0:5]'
[
{ "label": "2025", "count": 20438, "size_gb": 187.26 },
{ "label": "2024", "count": 18153, "size_gb": 151.17 },
{ "label": "2021", "count": 14559, "size_gb": 123.23 },
{ "label": "2022", "count": 15587, "size_gb": 115.47 },
{ "label": "2020", "count": 17957, "size_gb": 96.28 }
]
Find large videos from a specific time period
Narrow by year and month to target a trip or event. Combine with jq to filter by a size threshold.
Live
$ icloud-pp-cli photos videos --year 2024 --month 8 --agent \ | jq '[.[] | select(.size_gb > 0.5)]'
[
{
"rank": 1, "filename": "IMG_5820.MOV", "size_gb": 1.84,
"date": "2024-08-17", "uuid": "A1B2C3D4-E5F6-7890-ABCD-EF1234567890"
},
{
"rank": 2, "filename": "IMG_5741.MOV", "size_gb": 0.76,
"date": "2024-08-12", "uuid": "B2C3D4E5-F6A7-8901-BCDE-F12345678901"
}
]
Search by location
Find photos and videos shot near a coordinate — a bounding-box radius search straight over the GPS data in Photos.sqlite. Add --has-gps for everything with a location.
Live
$ icloud-pp-cli photos search --near 25.79,-80.13 --radius 5 --type video
 
# Type Size Date Filename UUID
1 video 0.04 GB 2025-07-08 IMG_3528.MOV 8F2A…
2 video 0.02 GB 2025-06-19 IMG_3401.MOV 1C7B…
3 video 0.01 GB 2025-05-30 IMG_3310.MOV A904…
Search by person
Find photos featuring a named person from your People album — read from on-device face detection, with no Photos.app launch. Pipe the UUIDs straight to download.
Live
$ icloud-pp-cli photos search --person "Mom" --year 2024 --json \ | jq -r '.[].uuid' \ | xargs icloud-pp-cli photos download --output ~/Desktop/mom
 
Exporting 42 item(s) to ~/Desktop/mom
✓ 42 exported, 0 failed.
Natural language queries
Ask in plain English. The one feature still on the roadmap — everything else here is live today.
Coming
$ icloud-pp-cli photos ask "vacation videos longer than 2 minutes from last summer" [ ... matching results ... ]
Audit your entire iMessage history
Reads chat.db directly and decodes the modern attributedBody blob so nothing post-2020 is missed. One command surfaces unique conversations, your longest threads, and who you talk to most.
Live
$ icloud-pp-cli messages audit --top 3
 
Conversations
1,284 unique · 1,032 DMs · 252 groups
 
Longest by message count
Mom dm 48,201 7.4 yrs
Weekend Crew group 31,544 5.1 yrs
Alex Rivera dm 22,910 6.8 yrs
 
Direction
from me: 312,887 (47.3%)
from others: 348,012 (52.7%)
Find and merge duplicate contacts
Syncs Contacts.app into a local cache, then finds likely duplicates by name, phone, or email — and hands you ready-to-paste merge commands. Merging dedupes phones, emails, and addresses, then syncs back to iCloud.
Live
$ icloud-pp-cli contacts duplicates
 
Likely duplicates (same name):
Danilo Gomes [a1b2c3d4] 2 phones, 1 email
Danilo Gomes SF [e5f6a7b8] 1 phone
→ icloud-pp-cli contacts merge a1b2c3d4 e5f6a7b8 --confirm
 
$ icloud-pp-cli contacts merge a1b2c3d4 e5f6a7b8 --confirm
✓ merged — 1 phone added, kept 1 contact
Full-text search your Notes
Pulls every note into a local FTS5 index (folders and accounts included). Search titles and bodies instantly. Password-protected notes stay private — only their metadata is read.
Live
$ icloud-pp-cli notes search "wifi password"
 
ID Title Folder Words Modified
p1842 House guide Home 412 2026-05-30
p0931 Airbnb checkout Travel 88 2026-04-12
See what's overdue across every list
Open reminders, soonest-due first, with overdue items flagged. Filter by list, by --upcoming N days, or get a full breakdown with analytics.
Live
$ icloud-pp-cli reminders list --overdue
 
Reminder List Due Pri
○ Renew passport Personal 2026-05-20 ⚠ high
○ Pay parking ticket Personal 2026-06-01 ⚠
○ Send invoice Work 2026-06-05 ⚠ ⚑ medium
Your week at a glance
A clean agenda grouped by day, pulled from every calendar. Search by keyword, list an explicit range, or run analytics for scheduled hours and your busiest weekday.
Live
$ icloud-pp-cli calendar agenda --days 3
 
Mon, Jun 8 2026
09:30–10:00 Standup [Work]
13:00–14:00 Lunch w/ Sam · Cafe Habana [Personal]
 
Tue, Jun 9 2026
all-day Flight to NYC [Travel]
See where your browsing time goes
Reads Safari's History.db read-only. Rank your most-visited domains, search history by URL or title, or list bookmarks with their folder path.
Live
$ icloud-pp-cli safari top-sites --limit 5
 
Domain Visits URLs
github.com 4,821 932
news.ycombinator 2,140 611
youtube.com 1,907 1,204
google.com 1,455 1,322
developer.apple 903 488
See what's really using your iCloud storage
Walks iCloud Drive on disk and splits every file into downloaded vs cloud-only — so you can see that one app is holding tens of GB in the cloud while taking almost nothing on your Mac. No special permission needed.
Live
$ icloud-pp-cli drive status
 
iCloud Drive
1,515 files · 566 downloaded · 949 cloud-only
1.1 GB on this Mac · 30.3 GB in the cloud only
 
Top containers
WhatsApp 61 0 B 26.8 GB (61)
iCloud Drive 1218 1.1 GB 3.4 GB (876)
Pages 10 0 B 0.1 GB (10)
Who you actually talk to
Reads your Call History (phone via Continuity + FaceTime) and ranks the people you call most — with names resolved from your synced contacts, total talk time, and missed-call counts.
Live
$ icloud-pp-cli calls analytics
 
Call history overview
3,204 total · 1,712 incoming · 1,492 outgoing · 287 missed
2,940 phone · 264 FaceTime · 9d 4h total talk time
 
Most-contacted
Mom 412 2d 1h
Alex Rivera 198 14h 22m
Your own Music Wrapped, any day of the year
Caches your Music library and ranks artists by actual play count — the year-end recap, on demand and entirely local.
Live
$ icloud-pp-cli music analytics
 
Music library
8,412 tracks · 1,204 artists · 942 albums
24d 6h total runtime · 51,308 total plays · 612 loved
 
Top artists (by plays)
Daft Punk 2,140 58
Tame Impala 1,887 41
Bad Bunny 1,502 33

Paste into any AI agent

Copy a prompt, paste it into Claude, Cursor, Codex, or any agent with terminal access — it runs the commands and handles the rest.

Photos
Your best shots. Print-ready.
Curate a year into a photo book — sorted by month, RAW keepers first.
Photos
50 best dog shots. One folder.
Surface dedicated shoot sessions from date clusters and stage them automatically.
Storage
Drop a plan tier. Save $36/yr.
Calculate exactly what to delete to downgrade, with ready-to-run commands.
–2 TB
freed this session
Videos
All your clips. Organized by day.
Find footage from any recording window and stage it for editing.
Storage
3,847 screenshots. Gone.
Find every screenshot, show total wasted space, delete in one shot.
Photos
Your 2024. The 75 best.
Pull RAW and ProRAW keepers from a full year, grouped by quarter.
Messages
Your year in conversations.
Turn a decade of iMessage into a who-you-talk-to-most report — no data leaves your Mac.
661K
messages analyzed
Reminders · Calendar
Your Monday briefing.
Combine overdue reminders and the week ahead into one plain-English start-of-week digest.
7 days
planned for you
Notes
Find what you wrote down.
Surface stale, empty, and duplicate notes — and resurface the ones worth keeping.
💡
Community
Have a use case to share?
Write your own prompt and submit it as a pull request — it might end up right here in the slider.
Open GitHub issue

Leave a star on GitHub.

Open source lives on community support. A star takes one second and helps other developers find this tool.

Apache-2.0 · free forever · macOS only

icloudcli command reference

Every command accepts --json, --compact, --no-color, and --agent (sets all three). The Contacts, Notes, Reminders, Calendar, and Music groups keep a local SQLite cache — run sync once, then every read is instant and offline. Photos, Messages, Safari, Calls, Screen Time, Podcasts, and Mail read their databases directly; iCloud Drive walks the filesystem. Run doctor to see which permissions each group needs.

photos
photos top Top N heaviest files across all media types. Flags: --limit, --type all|photo|video Live
photos videos Largest videos sorted by file size. Flags: --limit, --year, --month Live
photos storage Storage breakdown by media type (photo/video) and by year Live
photos stats Total item count and total library size Live
photos delete Move items to Recently Deleted. Dry run by default; add --confirm to act. Requires Photos.app. Live
photos download Export originals to a local folder via Photos.app — downloads from iCloud automatically if needed. Flags: --output, --sensitive, --type all|photo|video, --limit. Files renamed to <UUID>.ext. Live
photos search Filter by person, date, type, favorite, or location — pipes straight into download/delete. Flags: --person, --year, --month, --type, --favorites, --has-gps, --near LAT,LON --radius, --keyword Live
photos ask Natural language query over your library Coming
messages
messages list-chats List conversations by most-recent activity — name, handle, participant count, message count, last preview. Flags: --limit, --since, --include-empty Live
messages search Search message bodies — decodes the modern attributedBody blob so post-2020 texts aren't missed. Flags: --chat, --handle, --from-me, --since, --until, --limit Live
messages stats Totals, by-year breakdown, and top handles by message count. Flags: --top-handles, --include-tapbacks Live
messages audit Deep analysis — unique conversations (DM vs group), longest threads by count and by date span, activity recency, per-chat distribution, from-me vs from-others. Flags: --top Live
messages export Export a chat (or --chat all) to JSON with attachment paths. Flags: --out, --since, --until Live
contacts
contacts sync Pull all contacts from Contacts.app via JXA into a local SQLite cache. Run once; re-run with --force. Live
contacts list / get / search List, show one (8-char UUID prefix lookup), or full-text search across name, org, phones, emails, and notes (FTS5). Live
contacts merge / duplicates Find likely duplicates (name / phone / email) and merge two contacts — dedupes phones, emails, URLs, addresses. Dry run until --confirm. Live
contacts create / update / delete Write back to Contacts.app safely (values passed as out-of-band AppleScript args — no injection). Syncs to iCloud automatically. Live
contacts analytics Group by country (E.164 dial-code resolution), email domain, and missing-field coverage. Live
notes
notes sync Pull all notes from Notes.app via JXA into a local SQLite cache with folder and account. Password-protected notes expose metadata only. Live
notes list / get / search List by most-recently modified, show a full body, or full-text search titles and bodies (FTS5). Flags: --limit Live
notes analytics Word/char totals, averages, shared/locked/empty counts, longest note, and a per-folder breakdown. Live
reminders
reminders sync Pull all reminders from Reminders.app via JXA into a local SQLite cache, with list, priority, due/remind dates. Live
reminders list Open by default, soonest-due first. Flags: --list, --completed, --all, --overdue, --upcoming N Live
reminders get / search Show one reminder, or full-text search across titles, notes, and lists (FTS5). Live
reminders analytics Open / done / overdue, due today and this week, high-priority and flagged, plus a per-list breakdown. Live
calendar  alias: cal
calendar sync Pull events within a date window via JXA. Flags: --back (days history, default 90), --forward (default 365) Live
calendar agenda Upcoming events grouped by day (next 7 by default). Flags: --days, --calendar Live
calendar list / search Events in an explicit range (--from/--to), or full-text search across titles, locations, and notes. Live
calendar analytics Total events and scheduled hours, per-calendar breakdown, and a busiest-weekday histogram. Live
safari
safari history Recently visited pages, most recent first. Reads History.db read-only. Flags: --limit, --domain, --since Live
safari search / top-sites Search history by URL and title, or rank the most-visited domains by visit count. Live
safari bookmarks List all bookmarks flattened with their folder path (parsed from Bookmarks.plist). Live
safari reading-list Saved-for-later articles with date added, preview, and unread state. Flag: --unread Live
calls
calls list Recent phone + FaceTime calls, newest first. Flags: --missed, --incoming, --outgoing, --since, --limit Live
calls search / analytics Search by number/handle/name; analytics shows in/out/missed, phone vs FaceTime, total talk time, and most-contacted. Names resolve from your synced contacts. Live
drive
drive status Summary of iCloud Drive: file count, size on this Mac vs cloud-only, and your top containers. Live
drive usage Per-app storage breakdown — see exactly which apps hold your iCloud space (downloaded vs cloud-only). Live
drive list [subpath] List entries with per-file local/cloud download state. No special permission — they're your own files. Live
screentime  alias: st
screentime usage Top apps by foreground time. Flags: --days, --since, --limit Live
screentime web / notifications Top Safari domains by time, and per-app notification counts. Live
screentime analytics Window overview: total app time, distinct apps, notifications, most-used app. Knowledge store retains ~4 weeks. Live
music
music sync Cache your Music library (Apple Music / iCloud Music Library) via JXA — name, artist, album, genre, year, play count, rating, loved. Live
music list / search Most-played by default (--sort recent|name, --artist), or FTS5 search by name/artist/album/genre. Live
music playlists / analytics Playlists with track counts, and library analytics: top artists by plays, top genres, total runtime. Live
podcasts
podcasts shows Your shows, subscribed first, with episode counts. No permission needed — reads your own container. Live
podcasts episodes Episodes newest-first. Flags: --show, --downloaded, --unplayed Live
podcasts analytics Shows, subscriptions, episodes, downloads, and estimated listening time. Live
mail
mail list Messages across every account (envelope metadata, not bodies), newest first. Flags: --unread, --flagged, --from, --since Live
mail search / mailboxes Search by subject or sender; list mailboxes with total + unread counts. Live
mail analytics Totals, unread, flagged, and your top senders by message volume. Live
root
doctor Pre-flight check — verifies macOS, Photos library + schema, Messages and Safari Full Disk Access, and Automation for the Notes/Reminders/Calendar groups. Run this first. Live
photos ask Natural-language queries over your library — the one feature still on the roadmap. Coming

Install icloudcli on macOS

Requires macOS 13+. Run icloud-pp-cli doctor after installing to verify your setup.

Shell script (recommended)
$ curl -fsSL https://icloudcli.com/install.sh | sh
Go install
$ go install github.com/matysanchez/icloudcli/cmd/icloud-pp-cli@latest
Via Printing Press CLI
$ npx -y @mvanhorn/printing-press install icloud
Build from source
$ git clone https://github.com/matysanchez/icloudcli
$ cd icloudcli && make install
Verify — run this first
$ icloud-pp-cli doctor

System
✓ macOS required
macOS 15.4.1
✓ Photos.app installed

Library
✓ Library found · readable (read-only)
✓ Core schema valid (ZASSET + ZADDITIONALASSETATTRIBUTES)

Assets
✓ Can query assets
130,232 items · 802.12 GB (original sizes)

Messages · Safari
✓ chat.db & History.db readable (Full Disk Access granted)

Automation (Notes · Reminders · Calendar)
i Approved on first sync

All checks passed. Ready to use.
Permissions — grant once
Full Disk Access — for messages and safari (they read system SQLite databases).
System Settings → Privacy & Security → Full Disk Access →
add your terminal → quit & reopen it.


Automation — for notes, reminders, and calendar (read via JXA).
macOS prompts on first sync — click OK. Or pre-grant under
Privacy & Security → Automation → your terminal.


photos and contacts need no extra permission. Re-run doctor anytime.

icloudcli · early access

Be first when
new commands ship.

New iCloud databases unlock regularly. Get a short note when they do — no noise, no marketing.

One email per release. Unsubscribe any time.