Apple Mail MCP Server
Read, search, send and organise mail in the macOS Mail app from an MCP client
Search, inspect and export photos from the macOS Photos library, with optional album and metadata edits
By Rob Sweet (individual) TypeScript Local · stdio MediaFiles and storage
43 popularity score ★ 44 ↓ 761/wk
Opens the app, which asks before it adds the server.
claude mcp add apple-photos -- npx -y apple-photos-mcp{
"mcpServers": {
"apple-photos": {
"command": "npx",
"args": [
"-y",
"apple-photos-mcp"
]
}
}
}{
"mcpServers": {
"apple-photos": {
"command": "npx",
"args": [
"-y",
"apple-photos-mcp"
]
}
}
}{
"servers": {
"apple-photos": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"apple-photos-mcp"
]
}
}
}[mcp_servers.apple-photos]
command = "npx"
args = ["-y", "apple-photos-mcp"]gemini mcp add --scope user apple-photos npx -- -y apple-photos-mcpOpens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.
git clone https://github.com/sweetrb/apple-photos-mcp.git
cd apple-photos-mcp
pnpm install
pnpm run buildclaude mcp add apple-photos -- node '<ABSOLUTE_PATH_TO_CLONE>/build/index.js'{
"mcpServers": {
"apple-photos": {
"command": "node",
"args": [
"<ABSOLUTE_PATH_TO_CLONE>/build/index.js"
]
}
}
}{
"mcpServers": {
"apple-photos": {
"command": "node",
"args": [
"<ABSOLUTE_PATH_TO_CLONE>/build/index.js"
]
}
}
}{
"servers": {
"apple-photos": {
"type": "stdio",
"command": "node",
"args": [
"<ABSOLUTE_PATH_TO_CLONE>/build/index.js"
]
}
}
}[mcp_servers.apple-photos]
command = "node"
args = ["<ABSOLUTE_PATH_TO_CLONE>/build/index.js"]gemini mcp add --scope user apple-photos node -- '<ABSOLUTE_PATH_TO_CLONE>/build/index.js'APPLE_PHOTOS_MCP_ENABLE_WRITES |
Optional: Set to 1 to allow the seven write tools; unset keeps the server read-only. |
|---|---|
APPLE_PHOTOS_MCP_TIMEOUT |
Optional: Default helper timeout in ms for read tools (60000); raise for very large libraries. |
APPLE_PHOTOS_MCP_MAX_BUFFER |
Optional: Max bytes read from the Python helper's output (100 MB by default). |
APPLE_PHOTOS_MCP_STALE_WHILE_REVALIDATE |
Optional: Set to 1 to answer from the last parse while a changed library re-parses in the background. |
APPLE_PHOTOS_MCP_SIDECAR_IDLE_MS |
Optional: Idle time in ms before the Python helper is stopped (300000); 0 keeps it running. |
APPLE_PHOTOS_MCP_NO_AUTO_SETUP |
Optional: Set to 1 to skip the automatic osxphotos venv setup and install it yourself. |
APPLE_PHOTOS_MCP_SETUP_TIMEOUT |
Optional: Max ms the automatic venv setup may run (300000). |
APPLE_PHOTOS_MCP_CONFIG_FILE |
Optional: Path of the JSON settings file used when the host drops env values. |
Apple Photos MCP Server gives an assistant access to the Photos library on a Mac. It is a Node program that talks MCP over stdio and hands the actual library work to a bundled Python helper built on osxphotos, which reads the library's SQLite database directly. Everything happens on the user's machine.
On the reading side it can filter the library by date taken or date imported, album, keyword, named person, Photos' own ML labels, place name, GPS radius, media type (screenshots, selfies, bursts and so on), aesthetic score or text Photos found in the image. It returns full metadata including EXIF camera data, shows a photo inline as a thumbnail, groups exact duplicates, reads what is currently selected in Photos.app, and copies originals or edited versions out to a folder, downloading iCloud-only originals through Photos.app when needed.
Writing is off by default. With APPLE_PHOTOS_MCP_ENABLE_WRITES=1 (set as an env value or in its config.json) it can create albums, add or remove photos from albums, set titles, descriptions, favourites, keywords and dates, and import files. These edits go through Photos.app by AppleScript, not the database. No tool deletes a photo, album or folder.
The README documents each tool but never gives a count: the v2.1.20 source (src/index.ts) registers 21 tools, 14 that read and seven gated write tools, which stay listed even while writes are disabled and return an opt-in error when called.
| Runtime | Node.js 20+ |
|---|
macOS with a Photos library; Node.js 20 or newer; Python 3.11 or newer with pip on the PATH (stock macOS ships 3.9). On the first tool call it builds a local Python venv with osxphotos, which needs network access and takes about a minute. The app that launches the server (Claude Desktop, Terminal, VS Code) needs Full Disk Access; write tools also trigger a one-time macOS Automation prompt for controlling Photos.app.
Read-only unless APPLE_PHOTOS_MCP_ENABLE_WRITES=1; even then nothing can be deleted, and an import cannot be undone except by hand in Photos.app. Writes act on whichever library Photos.app has open, not the library parameter. remove-from-album rebuilds the album, so its UUID changes and manual sort order is lost. query returns 500 results by default (limit up to 100000); album edits take at most 100 UUIDs and imports 50 files per call. export writes only under the home folder, /tmp, /private/tmp or /Volumes. Person filters work only on named faces. Large libraries can exceed the 60-second default timeout (APPLE_PHOTOS_MCP_TIMEOUT). Claude Desktop drops env values, so use the config file.
Suits Mac users who want an assistant to find, review, tag or pull out photos from their own Photos library without uploading anything, since it reads the library locally and stays read-only until writes are switched on. The opt-in edits fit album filing and keyword clean-up, but anyone who needs deletion, bulk wildcard edits, or a non-Mac or cloud-hosted photo service should look elsewhere. It is a community project, not from Apple, and depends on Full Disk Access and a recent Python being set up first.
health-checkdoctorlibrary-infoqueryget-photoget-photosget-selected-photosget-thumbnailfind-duplicateslist-albumslist-folderslist-keywordslist-personsexportcreate-albumadd-to-albumremove-from-albumset-photo-metadataset-keywordsset-photo-dateimport-photos