Skip to content

maximbilan/photos-macos-mcp

Repository files navigation

PhotosMCP

A Model Context Protocol (MCP) server in Swift that provides AI assistants with read-only access to the macOS Photos library via Apple's PhotoKit framework.

Requirements

  • macOS 13.0+
  • Swift 6.0+ (Xcode 16+)
  • Photos app with a library

Building

swift build -c release

The executable will be at:

.build/release/PhotosMCP

Claude Desktop App Integration

  1. Build the project (see above).

  2. Add to Claude Desktop config

    Edit ~/Library/Application Support/Claude/claude_desktop_config.json:

    {
      "mcpServers": {
        "photos": {
          "command": "/Users/YOUR_USERNAME/Developer/photos-macos-mcp/.build/release/PhotosMCP",
          "args": []
        }
      }
    }

    Replace YOUR_USERNAME (or the whole path) with the actual absolute path to your built binary, for example:

"command": "/Users/max/Developer/photos-macos-mcp/.build/release/PhotosMCP"
  1. Grant Photos access

    The PhotosMCP process (or the parent Claude app) needs access to your Photos library. If prompted, allow it in:

    System Settings → Privacy & Security → Photos

    If the server was spawned by the Claude desktop app, you may need to grant Photos access to the Claude app.

  2. Restart Claude so it picks up the new MCP server.

MCP Tools

Tool Description
list_albums List all user and smart albums (name, id, asset count, type)
get_library_stats Total photos, videos, albums, and date range
search_photos Search by date range, media type, favorites, keyword
get_album_contents Assets in an album by identifier
get_asset_details Full metadata for an asset
get_photo_thumbnail Base64 JPEG thumbnail
get_photo_full Full-resolution image as base64 JPEG
get_photos_by_place Photos by place name (e.g. Valencia, Paris)—geocodes and searches
get_photos_by_location Photos within a radius of lat/long
get_photos_by_date Photos on a date or in a range
list_moments Moments/collections (iOS only on macOS)

All list/search tools support limit (default 50, max 200) and offset for pagination.

Permissions

The server uses PHPhotoLibrary.requestAuthorization and will show a system dialog on first use. If access is denied, tools return clear error messages.

Read-Only

This server is read-only. It does not modify, delete, or create assets or albums.

Privacy & Data

  • Place search (get_photos_by_place): Place names you provide (e.g. "Valencia", "Paris") are sent to Apple's geocoding service to resolve coordinates. This may involve network requests.
  • Image export: Thumbnails and full images are written to a PhotosMCP subdirectory in the system temp folder. Files older than 1 hour are automatically deleted when new exports occur.

Project Structure

PhotosMCP/
├── Package.swift
├── Info.plist              # NSPhotoLibraryUsageDescription for Photos access
├── Sources/
│   └── PhotosMCP/
│       ├── main.swift              # Entry point, stdio transport
│       ├── PhotosServer.swift      # MCP server, tool registration
│       ├── Tools/
│       │   ├── ToolDefinitions.swift  # Tool schemas
│       │   ├── LibraryTools.swift    # list_albums, get_library_stats, list_moments
│       │   ├── SearchTools.swift     # search_photos, get_photos_by_location, get_photos_by_date
│       │   ├── AlbumTools.swift      # get_album_contents
│       │   ├── AssetTools.swift      # get_asset_details
│       │   └── ImageTools.swift      # get_photo_thumbnail, get_photo_full
│       └── Helpers/
│           ├── PhotoKitHelpers.swift  # PHAsset → JSON structs
│           ├── ImageExport.swift      # PHImageManager, base64 JPEG
│           ├── PhotosAccess.swift     # Library authorization
│           ├── DateParsing.swift      # ISO 8601 date parsing
│           ├── GeoUtils.swift         # Haversine distance for location search
│           └── ContentClassifier.swift # Vision ML keyword matching
└── README.md

Notes

  • list_moments returns an empty list on macOS; the fetchMoments API is iOS-only.
  • Keyword search in search_photos uses Vision ML (pizza, food, car, city, dog, beach, etc.). Analyzes up to 1000 photos—combine with date range for large libraries.
  • Place search via get_photos_by_place—geocodes "Valencia", "Paris" etc. and finds photos taken there.
  • Date search accepts yyyy-MM-dd or full ISO 8601. Use start_date and end_date for ranges.

License

MIT

About

Read-only Model Context Protocol (MCP) server in Swift for browsing, searching, and retrieving metadata/images from macOS Photos.

Topics

Resources

License

Stars

Watchers

Forks

Contributors