MCP Hub
Back to servers

immich-mcp

An MCP server for Immich self-hosted photo management that provides AI-accessible tools for browsing, searching, organizing, and managing photo libraries with duplicate detection and safe deletion workflows.

glama
Stars
1
Updated
Apr 18, 2026

immich-mcp

MCP server for Immich photo management. Provides AI-accessible tools for browsing, searching, organizing, and managing your self-hosted photo library — including duplicate detection and safe deletion workflows.

Features

  • 40+ MCP tools covering assets, albums, search, people, tags, shared links, activities, and duplicates
  • 3 MCP prompts for guided workflows: duplicate review, album organization, and untagged photo discovery
  • Tool annotations (title, readOnlyHint, destructiveHint, idempotentHint) for safe AI-driven automation
  • Dry-run support on all destructive operations
  • Duplicate analysis with format priority scoring and protection for favorited/album-linked assets
  • Automatic retries via httpx.AsyncHTTPTransport (configurable via IMMICH_MAX_RETRIES)

Requirements

  • Python 3.11+
  • Immich server with API access
  • uv (recommended) or pip

Installation

git clone https://github.com/whitehara/immich-mcp
cd immich-mcp
uv pip install -e .

Configuration

Set environment variables before running:

VariableRequiredDefaultDescription
IMMICH_BASE_URLYesImmich server URL (e.g. https://photos.example.com)
IMMICH_API_KEYYesAPI key from Immich → Account Settings → API Keys
IMMICH_EXTERNAL_URLNosame as IMMICH_BASE_URLPublic URL used for web_url links (useful when base URL is internal)
IMMICH_TIMEOUTNo30.0HTTP timeout in seconds. The /api/duplicates endpoint on large libraries (70k+ assets) can exceed 30 s — set to 120.0 or higher if immich.duplicates.list times out.
IMMICH_MAX_RETRIESNo3Retry attempts on transient errors

Immich API Key Permissions

Immich 1.138.0+ supports granular API key permissions. Grant the following scopes when creating your key (Immich → Account Settings → API Keys → Create).

For full functionality (all tools enabled):

ScopeRequired by
server.aboutimmich.ping
user.readimmich.user.me
asset.readimmich.assets.list/get/view, all search tools
asset.uploadimmich.assets.upload
asset.updateimmich.assets.update, immich.assets.bulk_update
asset.deleteimmich.assets.delete, immich.duplicates.delete
asset.statisticsimmich.assets.statistics
album.readimmich.albums.list/get
album.createimmich.albums.create
album.updateimmich.albums.update
album.deleteimmich.albums.delete
albumAsset.createimmich.albums.add_assets
albumAsset.deleteimmich.albums.remove_assets
person.readimmich.people.list/get
person.updateimmich.people.update
person.mergeimmich.people.merge
person.statisticsimmich.people.statistics
tag.readimmich.tags.list/get
tag.createimmich.tags.create
tag.updateimmich.tags.update
tag.deleteimmich.tags.delete
sharedLink.readimmich.shared_links.list/get
sharedLink.createimmich.shared_links.create
sharedLink.updateimmich.shared_links.update
sharedLink.deleteimmich.shared_links.remove
activity.readimmich.activities.list
activity.statisticsimmich.activities.statistics
activity.createimmich.activities.create
activity.deleteimmich.activities.delete
duplicate.readimmich.duplicates.list
duplicate.deleteimmich.duplicates.dismiss

For read-only use (no create/update/delete tools), grant only: server.about, user.read, asset.read, asset.statistics, album.read, person.read, person.statistics, tag.read, sharedLink.read, activity.read, activity.statistics, duplicate.read

On Immich versions prior to 1.138.0, select All permissions.

Usage

stdio (Claude Desktop / Claude Code)

export IMMICH_BASE_URL=https://photos.example.com
export IMMICH_API_KEY=your-api-key
immich-mcp --transport stdio

Claude Desktop config (claude_desktop_config.json):

{
  "mcpServers": {
    "immich": {
      "command": "immich-mcp",
      "args": ["--transport", "stdio"],
      "env": {
        "IMMICH_BASE_URL": "https://photos.example.com",
        "IMMICH_API_KEY": "your-api-key"
      }
    }
  }
}

HTTP (Docker / remote)

docker run -e IMMICH_BASE_URL=https://photos.example.com \
           -e IMMICH_API_KEY=your-api-key \
           -p 8000:8000 \
           ghcr.io/whitehara/immich-mcp:latest

Or build locally with docker compose up.

Default transport in Docker is streamable-http on port 8000.

Tool Reference

Annotation columns: R = readOnlyHint, D = destructiveHint, I = idempotentHint

Each tool also carries a human-readable title annotation used by MCP clients for display.

Health

ToolDescriptionRDI
immich.pingVerify connectivity, returns server version
immich.capabilitiesList supported server features

User

ToolDescriptionRDI
immich.user.meGet the authenticated user's profile (name, email, quota, role)

Assets

ToolDescriptionRDI
immich.assets.listList assets with filters (favorite, archived, trashed, type)
immich.assets.getGet full metadata for a single asset
immich.assets.viewGet thumbnail, original, and web UI URLs for an asset
immich.assets.uploadUpload an asset from a local file path or URL
immich.assets.updateUpdate favorite, archived, description, rating
immich.assets.bulk_updateBulk update multiple assets (dry_run supported)
immich.assets.deleteDelete assets, optionally permanently (dry_run supported)
immich.assets.statisticsGet counts by asset type

Search

ToolDescriptionRDI
immich.search.metadataFilter by date, type, location, camera, person, filename
immich.search.smartSemantic/CLIP search with natural language queries
immich.search.exploreDiscover popular places, people, and things

Albums

ToolDescriptionRDI
immich.albums.listList all albums
immich.albums.getGet album details and assets
immich.albums.createCreate a new album
immich.albums.updateUpdate album name, description, or cover
immich.albums.deleteDelete an album (assets are not deleted)
immich.albums.add_assetsAdd assets to an album
immich.albums.remove_assetsRemove assets from an album

People

ToolDescriptionRDI
immich.people.listList recognized people
immich.people.getGet person details
immich.people.updateUpdate name or visibility
immich.people.mergeMerge two face clusters
immich.people.statisticsGet asset count for a person

Tags

ToolDescriptionRDI
immich.tags.listList all tags
immich.tags.getGet a tag by ID
immich.tags.createCreate a tag (use / for nested tags)
immich.tags.updateUpdate tag name or color
immich.tags.deleteDelete a tag

Shared Links

ToolDescriptionRDI
immich.shared_links.listList all shared links
immich.shared_links.getGet shared link details
immich.shared_links.createCreate a shareable URL
immich.shared_links.updateUpdate expiry, password, permissions
immich.shared_links.removeRevoke a shared link

Activities

ToolDescriptionRDI
immich.activities.listList comments and likes
immich.activities.createAdd a comment or like
immich.activities.deleteDelete an activity
immich.activities.statisticsGet comment count

Duplicates

ToolDescriptionRDI
immich.duplicates.listList duplicate groups with analysis (format score, resolution, protection status). Results are served from an in-memory cache; first call after server start returns cache_ready=false while data loads in the background — retry in 1–2 minutes.
immich.duplicates.deleteDelete assets from duplicate groups (dry_run supported)
immich.duplicates.dismissDismiss duplicate groups without deleting files (dry_run supported)

Duplicate Analysis Fields

immich.duplicates.list with analyze=true (default) returns per-group analysis:

FieldDescription
keep_idRecommended asset to retain (highest quality)
safe_to_delete_idsAssets not favorited and not in any album
protected_idsAssets that are favorited or in albums — require explicit user approval
needs_reviewtrue when protected assets appear among delete candidates

Quality Priority for keep_id (highest to lowest)

Live Photo > Format score > Resolution > File size

Favorites and album membership are tiebreakers only — they do not override a quality difference. A favorited JPEG will not be recommended over an unfavorited RAW; instead the JPEG is listed in protected_ids for user review.

Format Score (highest to lowest)

RAW/DNG > HEIC/HEIF > PNG/TIFF > JPEG > WebP > GIF

Prompt Reference

Invoke prompts from your MCP client to start guided workflows.

immich/review_duplicates

Step-by-step workflow for reviewing and safely resolving duplicate photos:

  1. Fetch duplicate groups with analysis
  2. Present summary: safe-to-delete count vs. protected assets needing review
  3. For each group, choose an action:
    • Delete: keep the best asset, move the rest to trash (or permanently delete)
    • Dismiss: assets are intentionally kept as separate copies — remove the duplicate grouping without deleting files
  4. Dry-run confirmation before execution

immich/organize_album

Guided album creation workflow:

  • Organize by date, event, person, or location
  • Uses both metadata search and semantic (CLIP) search
  • Checks for existing albums to avoid duplicates
  • Confirms asset count before creating

immich/find_untagged

Discover unorganized assets in the library:

  • Identifies assets with no album, no description, or no recognized people
  • Suggests descriptions from EXIF data
  • Hands off to immich/organize_album for album creation

Safety Model

All destructive tools (delete, merge, remove) carry destructiveHint=true in their MCP annotations, signalling to clients that human confirmation is required before execution. Additional safeguards:

  • dry_run=true is the default on all delete operations — no changes occur without explicit opt-in
  • Duplicate analysis places favorited and album-linked assets in protected_ids; they are never auto-deleted
  • Prompts explicitly instruct the AI to present a summary and obtain user approval before any destructive action

Development

# Install with dev dependencies
uv pip install -e ".[dev]"

# Run tests
pytest

# Run a single test file
pytest tests/tools/test_assets.py -v

# Type check (optional)
pyright src/

Reviews

No reviews yet

Sign in to write a review