immichctrl

Active

Your Immich library holds your whole life in photos, but the web UI is built for clicking, not for "find every duplicate and tell me which to keep" across thousands of assets. immich-mcp hands the library to your agent as typed, write-gated tool calls: smart search, albums, people, memories, and checksum-safe dedupe, all over stdio.

74 tools16 domainswrite-gatedstdioNode 20+MIT

See it work

one question, the tools it calls, the answer

representative session · claude + immich-mcp
My library feels bloated. Find duplicate photos and tell me which to delete, but don't delete anything yet.
immich_categorize_duplicates{ scope: "active" }
312 duplicate groups, 1.9 GB reclaimable checksum-exact 214 groups byte-identical, safe to trash resolution-variants 61 groups keep highest-res edits 37 groups original + edited copy
immich_explain_duplicate_group{ id: "grp_00b1" }
3 assets, checksum-exact keeper IMG_4821.jpg 4032x3024 in album "Iceland 2019" discard IMG_4821 (1).jpg, IMG_4821 (2).jpg no album
You have 312 duplicate groups, about 1.9 GB to reclaim. The 214 checksum-exact groups are byte-identical and safe. For grp_00b1 I'd keep the copy that's already in your Iceland album and trash the two loose duplicates. Say the word and I'll run immich_resolve_with_keep_strategy as a dry run first.

Representative session. Illustrative values, RFC 5737 addresses. Nothing leaves your box, and no write runs without IMMICH_ALLOW_WRITES plus a per-call confirm.

What it does

immich-mcp (repo immichctrl) is an operator control surface for Immich, the self-hosted photo and video library: an MCP adapter plus a read-only `immichctrl` CLI for shells and cron. Point any MCP client at it and Immich's REST API becomes 74 schema-validated tools across 16 domains, so an agent can smart-search by natural language, curate albums and tags, recognize and merge people, surface "on this day" memories, and resolve duplicates in plain language instead of clicking through a grid. It differs from other Immich MCP servers in breadth and safety: it covers memories, motion-photo stacks, checksum-safe duplicate resolution, trash auditing, and job control, and it ships a two-tier write model where reads always work but every write hides behind `IMMICH_ALLOW_WRITES=true` and every destructive call demands a per-request `confirm: true`, so an agent cannot quietly delete your photos.

Capabilities

74 tools across 16 domains

Search & discovery3 tools
CLIP smart search, structured metadata search, and a server-side explore feed.
Assets & EXIF11 tools
List, read metadata and EXIF, favorite, archive, rate, geotag, trash, restore, and confined upload.
Albums, tags & shared links20 tools
Full lifecycle for albums, tags, and shared links, plus search-then-album in one gated step.
People & faces7 tools
Enumerate faces, rename, hide, suggest names for unnamed clusters, and merge duplicate clusters.
Duplicates & dedupe10 tools
Categorize groups, find byte-identical and CLIP dupes, audit active library and trash, resolve by keep strategy.
Memories, stacks, trash & jobs16 tools
On-this-day lanes and daily digest, motion-photo stacks, trash audit and empty, and background job control.
Full reference on GitHub →

Set it up

npm i -g immich-mcp (or npx -y immich-mcp, no install)

Set IMMICH_BASE_URL (note the /api suffix) and IMMICH_API_KEY from Account Settings > API Keys. IMMICH_ALLOW_WRITES defaults to false; set true to expose write and delete tools. Optional: IMMICH_UPLOAD_BASE_DIR to allow confined path uploads, IMMICH_VERIFY_SSL=false for self-signed certs.

MCP client config
{ "mcpServers": { "immich-mcp": { "command": "npx", "args": ["-y", "immich-mcp"], "env": { "IMMICH_BASE_URL": "https://photos.example.com/api", "IMMICH_API_KEY": "YOUR_KEY", "IMMICH_ALLOW_WRITES": "false" } } } }
[ shield ]

Two-tier write protection. Reads always work; write and delete tools only register when IMMICH_ALLOW_WRITES=true, and destructive calls (bulk updates, permanent deletes, people merges, emptying trash) additionally refuse to run without a per-call confirm: true. Dedupe tools are dry-run by default. Path-based upload is confined to IMMICH_UPLOAD_BASE_DIR after resolving symlinks, and relaxed TLS is scoped to the Immich client's dispatcher, not the whole process. The CLI exposes reads only. Nothing is sent anywhere except the Immich server you point it at.

74
MCP tools
16
domains
write-gated
two-tier confirm
stdio
transport
MIT
license