query
Find photos in an Apple Photos library by combining filters like album, person, date, place, media type, OCR text, and size, then get matching photo summaries with UUIDs.
Instructions
Use when: you need to find photos matching one or more filters — album, keyword, person, ML label, place, GPS radius (near), folder, taken-date or import-date range (addedAfter/addedInLast for 'recently imported'), year, file size, media type (screenshot, screen recording, selfie, panorama, live, portrait, time-lapse, slow-mo, burst, video), aesthetic score (minScore), OCR-detected text (detectedText), favorite/hidden flags, or title/description substrings — and get back a list of matches. This is the primary search/discovery tool; start here when you don't already have a UUID. Hidden photos are excluded unless hidden=true. Pass newestFirst=true with a limit to get the N most recent matches. Returns: count (the TOTAL number of matches), returned (the number of summaries in this response — capped at limit, default 500), and photo summaries (UUID, filename, date, dimensions, favorite/hidden/movie flags) — feed a UUID into get-photo/get-photos for full metadata, get-thumbnail to see it, or export to copy files. Do not use when: you already have UUIDs and want full metadata — use get-photo / get-photos; you want to see an image — use get-thumbnail; or you just want the catalog of album/keyword/person names — use list-albums / list-keywords / list-persons.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| live | No | Only live photos | |
| near | No | GPS-radius filter: "lat,lon,radiusKm" — only photos within radiusKm of the point (great-circle distance). Composes (AND) with every other filter. Requires location data: photos without GPS coordinates never match | |
| uuid | No | Specific UUIDs to fetch | |
| year | No | Taken in calendar year(s); ANY-match (e.g. [2024, 2025]) | |
| album | No | Album name(s); ANY-match | |
| burst | No | Only burst photos | |
| label | No | ML classification label(s) from Photos object detection (the labels field of get-photo, e.g. Dog, Beach, Text); ANY-match, exact whole-string | |
| limit | No | Cap the number of results returned (default 500 when omitted; count still reports the total matches) | |
| place | No | Place-name substring(s) from reverse geocoding (city, region, landmark). NOTE: multiple values are ANDed, not ORed — a photo must match every value | |
| title | No | Substring match on title | |
| video | No | Only videos/movies (alias of movies) | |
| folder | No | Folder name(s)/path(s) — matches photos in albums that live inside the folder; ANY-match (see list-folders for names) | |
| hidden | No | Only hidden photos | |
| movies | No | Include movies | |
| person | No | Person name(s); ANY-match | |
| photos | No | Include still photos | |
| selfie | No | Only selfies (front-camera photos) | |
| slowMo | No | Only slow-motion videos | |
| toDate | No | ISO 8601 upper bound on photo date. A bare date (e.g. 2025-06-30) includes that whole day; pass a full datetime (e.g. 2025-06-30T18:00:00) for a precise exclusive bound | |
| keyword | No | Keyword(s); ANY-match | |
| library | No | Path to a .photoslibrary (default: system Photos library) | |
| maxSize | No | Original file size at most this many bytes | |
| minSize | No | Original file size at least this many bytes | |
| favorite | No | Only favorites | |
| fromDate | No | ISO 8601 lower bound on photo date | |
| minScore | No | Only photos whose Photos-computed overall aesthetic score (0–1) is at least this — e.g. 0.7 for 'the good ones'. Post-filter over the other filters' matches; photos without a computed score never match | |
| panorama | No | Only panoramas | |
| portrait | No | Only portrait-mode (depth-effect) photos | |
| noKeyword | No | Only photos carrying no keyword at all | |
| notHidden | No | Exclude hidden photos (default behavior) | |
| timelapse | No | Only time-lapse videos | |
| addedAfter | No | ISO 8601 inclusive lower bound on IMPORT date (dateAdded — when the photo entered the library, not when it was taken) | |
| screenshot | No | Only screenshots | |
| addedBefore | No | ISO 8601 upper bound on IMPORT date. A bare date includes that whole day; a full datetime is a precise exclusive bound | |
| addedInLast | No | Imported within the trailing duration — "<number><unit>", unit s(econds) / m(inutes) / h(ours) / d(ays) / w(eeks), e.g. "7d" or "24h". The natural way to express "recently imported" | |
| description | No | Substring match on description | |
| hasLocation | No | true = only photos WITH GPS coordinates; false = only photos WITHOUT; omit for no location filter | |
| newestFirst | No | Sort matches by taken date, newest first, BEFORE limit is applied — so limit means 'the N most recent matches' instead of 'N in database order' | |
| notFavorite | No | Exclude favorites | |
| detectedText | No | Case-insensitive substring match over the text Photos' own OCR indexed in each photo (macOS 13+) — receipts, signs, screenshots. Post-filter that reads per-photo search info over every other filter's matches, so combine it with narrowing filters (dates, album) on big libraries | |
| screenRecording | No | Only screen recordings |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | ||
| photos | No | ||
| returned | No |