Skip to main content
Glama
sweetrb

apple-photos-mcp

by sweetrb

query

Find photos by applying filters such as album, keyword, person, date range, location, and more. Returns matching photo summaries with UUIDs for further actions.

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

TableJSON Schema
NameRequiredDescriptionDefault
liveNoOnly live photos
nearNoGPS-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
uuidNoSpecific UUIDs to fetch
yearNoTaken in calendar year(s); ANY-match (e.g. [2024, 2025])
albumNoAlbum name(s); ANY-match
burstNoOnly burst photos
labelNoML classification label(s) from Photos object detection (the labels field of get-photo, e.g. Dog, Beach, Text); ANY-match, exact whole-string
limitNoCap the number of results returned (default 500 when omitted; count still reports the total matches)
placeNoPlace-name substring(s) from reverse geocoding (city, region, landmark). NOTE: multiple values are ANDed, not ORed — a photo must match every value
titleNoSubstring match on title
videoNoOnly videos/movies (alias of movies)
folderNoFolder name(s)/path(s) — matches photos in albums that live inside the folder; ANY-match (see list-folders for names)
hiddenNoOnly hidden photos
moviesNoInclude movies
personNoPerson name(s); ANY-match
photosNoInclude still photos
selfieNoOnly selfies (front-camera photos)
slowMoNoOnly slow-motion videos
toDateNoISO 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
keywordNoKeyword(s); ANY-match
libraryNoPath to a .photoslibrary (default: system Photos library)
maxSizeNoOriginal file size at most this many bytes
minSizeNoOriginal file size at least this many bytes
favoriteNoOnly favorites
fromDateNoISO 8601 lower bound on photo date
minScoreNoOnly 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
panoramaNoOnly panoramas
portraitNoOnly portrait-mode (depth-effect) photos
noKeywordNoOnly photos carrying no keyword at all
notHiddenNoExclude hidden photos (default behavior)
timelapseNoOnly time-lapse videos
addedAfterNoISO 8601 inclusive lower bound on IMPORT date (dateAdded — when the photo entered the library, not when it was taken)
screenshotNoOnly screenshots
addedBeforeNoISO 8601 upper bound on IMPORT date. A bare date includes that whole day; a full datetime is a precise exclusive bound
addedInLastNoImported 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"
descriptionNoSubstring match on description
hasLocationNotrue = only photos WITH GPS coordinates; false = only photos WITHOUT; omit for no location filter
newestFirstNoSort matches by taken date, newest first, BEFORE limit is applied — so limit means 'the N most recent matches' instead of 'N in database order'
notFavoriteNoExclude favorites
detectedTextNoCase-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
screenRecordingNoOnly screen recordings

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
countNo
photosNo
returnedNo
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations, but the description covers return structure, default behavior, exclusion of hidden photos, sorting with newestFirst, and post-filters like minScore and detectedText. It does not explicitly state read-only nature, but it's implied. Minor gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well-structured with 'Use when', 'Returns', 'Do not use when'. While somewhat lengthy, every sentence is informative and contributes to understanding. Could be slightly more concise, but effectively organized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (41 parameters, no required, output schema exists), the description covers key aspects: return fields, default limit, sorting, exclusion, and post-filter behavior. It is complete enough for an AI agent to use effectively.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

All 41 parameters have schema descriptions (100% coverage), so baseline is 3. The tool description adds value by summarizing usage patterns, e.g., 'pass newestFirst=true with a limit to get the N most recent matches', and explaining post-filters, which makes parameter semantics clearer.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it's a search/discovery tool for finding photos matching filters. It specifies to start here when UUIDs are not available, and distinguishes from siblings like get-photo, get-thumbnail, and list-albums.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit 'Use when' and 'Do not use when' sections provide clear context for when to use this tool versus alternatives, such as using get-photo for UUIDs or list-albums for catalog browsing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sweetrb/apple-photos-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server