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.

$npm i -g immich-mcp (or npx -y immich-mcp, no install)
write-gatedstdioNode 20+

See it workrepresentative session

you
My library feels bloated. Find duplicate photos and tell me which to delete, but don't delete anything yet.
tool
immich_categorize_duplicates{ scope: "active" }
result
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
tool
immich_explain_duplicate_group{ id: "grp_00b1" }
result
3 assets, checksum-exact keeper IMG_4821.jpg 4032x3024 in album "Iceland 2019" discard IMG_4821 (1).jpg, IMG_4821 (2).jpg no album
agent
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.

Capabilities74 tools across 16 domains

Search & discovery

3 tools

CLIP smart search, structured metadata search, and a server-side explore feed.

Assets & EXIF

11 tools

List, read metadata and EXIF, favorite, archive, rate, geotag, trash, restore, and confined upload.

Albums, tags & shared links

20 tools

Full lifecycle for albums, tags, and shared links, plus search-then-album in one gated step.

People & faces

7 tools

Enumerate faces, rename, hide, suggest names for unnamed clusters, and merge duplicate clusters.

Duplicates & dedupe

10 tools

Categorize groups, find byte-identical and CLIP dupes, audit active library and trash, resolve by keep strategy.

Memories, stacks, trash & jobs

16 tools

On-this-day lanes and daily digest, motion-photo stacks, trash audit and empty, and background job control.

Full tool reference on GitHub →

Setup

01 · install
npm i -g immich-mcp   (or npx -y immich-mcp, no install)
02 · configure

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.

03 · 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" } } } }

Safety

how it stays safe
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.

More in Homelab5 tools

proxmox-mcpOperate Proxmox VMs, containers, and nodes from your agent, every write gated. adguardctrlRun AdGuard Home DNS filtering from shells and agents, destructive writes gated. proxguardAudit Proxmox against CIS benchmarks: config parsers and remediation scripts. jellyctrlDrive Jellyfin libraries, sessions, and users from a CLI or MCP, writes gated. samba-ad-migrationAutomated migration of a Windows AD file share to Samba on Proxmox, with Winbind domain join and permission-preserving data copy.