photo-archive-kit
Claude Code skills and agents that turn photo chaos into one dated archive - and only free your cloud storage after every file is proven to be in the backup.
- Sort a messy trip dump into day folders, fixing wrong dates (screenshots, forwarded images, phone copies).
- Get years of photos out of iCloud Photos and Google Photos (Takeout) into
Year/MonthsandYear/Tripsfolders, without downloading anything twice. - Fold old hard drives, SSDs, zips and phone backups into the same archive - only what is not already there.
- Verify an upload to Google Drive (or anything rclone can list) by name and exact size, folder by folder.
- Delete at the source (iCloud, Google Photos, Drive duplicates) only after verification, your explicit OK, a one-item test, and always into a recoverable bin.
- General organisers for any photo folder or any messy folder, in the spirit of
/reorganize.
Built from a real clean-up of ~26,000 iCloud items, ~12,000 Google Photos items and a 3,400-file SSD. The rules in the skills are there because each one, once skipped, nearly lost something.
What's inside
| Skill / agent | For |
|---|---|
organize-photos | Any folder of photos/videos -> Year/Month (or day / trip) by real capture date; screenshots, shared images, undated, non-media and checksum-proven duplicates parked in honest holding folders. Plan -> apply -> undo. Cross-platform Python, no installs. |
organize-folder | Any messy non-code folder (Downloads, dumps, project drafts): survey, follow the existing taxonomy, sort by role, checksum duplicates, never delete. |
sort-trip-photos | One trip -> D1_26Oct_Travel ... Dn_Return, unrelated, unsorted, duplicates; contact sheets for judging hundreds of undated images in a few looks; lossless, logged EXIF date fixes; iPhone copy over USB. Windows. |
photo-archive | iCloud / Google Photos / loose drives -> archive; Drive verification; safe deletion protocol. |
agent trip-photo-sorter | Runs a trip sort end to end and reports. |
agent archive-verifier | Read-only "is it really all on Drive? can I delete this folder?" check. |
Install
In Claude Code:
/plugin marketplace add Azimlearning/photo-archive-kit
/plugin install photo-archive-kit@photo-archive-kit
Update later with claude plugin update photo-archive-kit. The plugin includes the two agents.
Codex:
codex plugin marketplace add Azimlearning/photo-archive-kit
codex plugin add photo-archive-kit@photo-archive-kit
Any other agent (Cursor, Copilot, Gemini CLI, opencode, ...) via the skills CLI:
npx skills add https://github.com/Azimlearning/photo-archive-kit --skill organize-photos
npx skills add https://github.com/Azimlearning/photo-archive-kit # all four skills
Add -g to install globally. More options in docs/other-agents.md.
No installer? Copy the folders.
Copy skills/<name>/ into ~/.claude/skills/<name>/ (or a project's .claude/skills/) and agents/*.md into
~/.claude/agents/. Restart Claude Code.
Then put a CLAUDE.md in your photo folder (start from templates/CLAUDE.project.md) with your paths, home
timezone, layout and rules, and ask Claude things like:
- "organize the photos in D:\OldLaptop\Pictures into D:\Photos\archive"
- "sort the new batch of my Japan trip photos"
- "get everything before 2025 out of iCloud into my archive"
- "I uploaded the 2023 folders to Drive - check them and tell me what I can delete"
Requirements
- Python 3.9+ (standard library only). Run scripts as
python -I script.py .... sort-trip-photos: Windows, PowerShell 7 (pwsh), Windows PowerShell 5.1 for the iPhone copy, optionalffprobefor video dates. EXIF writing installspiexifinto a throwaway venv in %TEMP%.- iCloud / Google Photos steps: your own signed-in browser tab, driven by a browser tool such as the Playwright MCP server (or paste the snippets into DevTools). Google Takeout zips for Google Photos.
- Drive verification:
rclone, or Claude's Google Drive connector.
Safety model
- Nothing here deletes local files. Moves are logged (CSV) and reversible; collisions are renamed, never overwritten.
- Cloud deletes need: a verified copy (name + exact size), an offline-approved list fingerprint (iCloud), your OK for the exact count, a one-item test, small batches with server-side confirmation, and land in a recoverable bin.
- Protected by default: iCloud Hidden album, your albums, shared albums (asks first).
- You type passwords and 2FA yourself. No photo, GPS or account data is sent anywhere by these scripts; the only network calls are to the services you are signed in to, from your own browser or with their signed URLs.
Caveats
- The iCloud and Google Photos browser snippets use the web apps' internal endpoints. They are unofficial and can break when Apple or Google change their sites. They fail loudly (an error object), never silently.
- Test on a small phase first. You are responsible for your data; keep the bins until you have checked the archive.
Layout of this repo
skills/ the skills (single source of truth)
organize-photos/ SKILL.md, scripts/organize_media.py, remove_empty_dirs.py
organize-folder/ SKILL.md
sort-trip-photos/ SKILL.md, scripts/*.ps1, fix_exif.py
photo-archive/ SKILL.md, reference/*.md, scripts/*.py, *.js
agents/ trip-photo-sorter.md, archive-verifier.md
.claude-plugin/ .codex-plugin/ plugin.json manifests (Claude Code, Codex, generic)
.claude/ .agents/ .opencode/ symlinks to skills/ for each agent's discovery path
templates/ CLAUDE.project.md, trips.example.csv
tests/ scripts/check_repo.py tests on synthetic files + repo checks (run in CI on Windows/macOS/Linux)
docs/other-agents.md AGENTS.md PRIVACY.md CHANGELOG.md
Contributing
Read AGENTS.md. Before a pull request: python -I scripts/check_repo.py and
python -I -m unittest discover -s tests -v.
License
MIT