immich-mcp
v0.5.0
Published
MCP server for Immich — browse and search photos, manage albums, recognize people, surface memories, resolve duplicates, manage stacks via LLM tool calls
Maintainers
Readme
An MCP (Model Context Protocol) server for Immich. Exposes Immich's photo and video library surface to LLMs - browse and search assets, manage albums and tags, recognize and merge people, surface memories, resolve duplicates, and group motion photos into stacks, all as typed tool calls.
Companion to jellyfin-mcp and reelgrep-mcp in the home-media MCP family.
Features
- ~55 MCP tools across 11 domains, more comprehensive coverage than existing options
- Memories, duplicates, and stacks support out of the box (net-new versus other Immich MCP servers)
- Smart / CLIP semantic search via
immich_search_smartplus metadata search and the discovery "explore" feed - Two-tier write protection: writes are gated by the
IMMICH_ALLOW_WRITES=trueenv var, and destructive tools additionally requireconfirm: trueper call - People recognition: list, update, hide, get assets per person, merge duplicates
- Albums, tags, shared links, and activities as first-class typed surfaces
- Asset uploads from local paths, EXIF reads, and original / thumbnail downloads
- Works with Claude Desktop, Claude Code, OpenClaw, Hermes Agent, Codex CLI, and any MCP-compatible client
Tools
System (5)
immich_ping- health checkimmich_get_server_info- version, build, featuresimmich_get_server_statistics- photo count, video count, total usageimmich_get_storage- disk usage and free spaceimmich_get_capabilities- feature flags exposed by the server
Assets (11)
immich_list_assets- paginated list with filtersimmich_get_asset- full asset metadataimmich_get_asset_exif- EXIF block for one assetimmich_get_asset_statistics- per-library countsimmich_update_asset- rename, set favorite, archive, set descriptionimmich_bulk_update_assets- bulk favorite / archive / visibility (requiresconfirm: true)immich_delete_asset- soft delete (trash) by default; passpermanent: trueto bypass trash (permanent delete requiresconfirm: true)immich_restore_from_trash- undo a soft deleteimmich_download_asset_original- return the original file bytesimmich_download_asset_thumbnail- return a preview/thumbnailimmich_upload_asset_from_path- upload a local file
Search (3)
immich_search_smart- CLIP / semantic search by natural-language queryimmich_search_metadata- structured search (date range, camera make, location, etc.)immich_search_explore- server-side discovery feed (cities, people, things)
Albums (8)
immich_list_albumsimmich_get_albumimmich_get_album_statisticsimmich_create_albumimmich_update_albumimmich_add_assets_to_albumimmich_remove_assets_from_albumimmich_delete_album(requiresconfirm: true)
People (6)
immich_list_peopleimmich_get_personimmich_get_person_assets- photos and videos this face appears inimmich_update_person- rename, set birth date, set thumbnailimmich_hide_person- exclude from discovery without deletingimmich_merge_people- fold duplicate face clusters into one (requiresconfirm: true)
Tags (7)
immich_list_tagsimmich_get_tagimmich_create_tagimmich_update_tagimmich_delete_tag(requiresconfirm: true)immich_add_tag_to_assetsimmich_remove_tag_from_assets
Shared Links (5)
immich_list_shared_linksimmich_get_shared_linkimmich_create_shared_linkimmich_update_shared_linkimmich_delete_shared_link(requiresconfirm: true)
Activities (4)
immich_list_activities- comments and likes on shared albumsimmich_get_activity_statisticsimmich_create_activityimmich_delete_activity(requiresconfirm: true)
Memories (2)
immich_list_memories- "on this day" and other generated memoriesimmich_get_memory
Duplicates (2)
immich_list_duplicates- duplicate clusters detected by Immich's hashing passimmich_resolve_duplicates- pick a keeper, trash the others (requiresconfirm: true)
Stacks (4)
immich_list_stacks- stack groups (motion photos, bracketed shots, RAW + JPEG pairs)immich_create_stackimmich_update_stack- re-pick the primary asset or add/remove membersimmich_delete_stack(requiresconfirm: true)
Install
npm install -g immich-mcpOr from source:
git clone https://github.com/solomonneas/immich-mcp.git
cd immich-mcp
npm install
npm run buildConfiguration
Set these environment variables in your MCP client config:
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| IMMICH_BASE_URL | yes | - | Base URL of your Immich API, e.g. https://photos.example.com/api |
| IMMICH_API_KEY | yes | - | API key from Account Settings > API Keys in the Immich web UI |
| IMMICH_ALLOW_WRITES | no | false | Set to true to expose write and delete tools. Reads always work. |
| IMMICH_VERIFY_SSL | no | true | Set to false for self-signed certs |
Getting an API key
- Log into Immich
- Account Settings > API Keys > New API Key
- Name it (e.g.
mcp) and copy the value
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"immich-mcp": {
"command": "immich-mcp",
"env": {
"IMMICH_BASE_URL": "https://photos.example.com/api",
"IMMICH_API_KEY": "YOUR_KEY",
"IMMICH_ALLOW_WRITES": "false"
}
}
}
}Claude Code
claude mcp add immich-mcp \
-e IMMICH_BASE_URL=https://photos.example.com/api \
-e IMMICH_API_KEY=YOUR_KEY \
-e IMMICH_ALLOW_WRITES=false \
-- immich-mcpAdd --scope user to make it available from any directory instead of only the current project.
OpenClaw
Add to ~/.openclaw/openclaw.json under mcps.entries.immich-mcp:
{
"mcps": {
"entries": {
"immich-mcp": {
"command": "immich-mcp",
"env": {
"IMMICH_BASE_URL": "https://photos.example.com/api",
"IMMICH_API_KEY": "YOUR_KEY",
"IMMICH_ALLOW_WRITES": "false"
}
}
}
}
}Or, when running from a source checkout instead of the global npm install:
{
"mcps": {
"entries": {
"immich-mcp": {
"command": "node",
"args": ["/absolute/path/to/immich-mcp/dist/index.js"],
"env": {
"IMMICH_BASE_URL": "https://photos.example.com/api",
"IMMICH_API_KEY": "YOUR_KEY",
"IMMICH_ALLOW_WRITES": "false"
}
}
}
}
}Then restart the OpenClaw gateway so the new server is picked up:
systemctl --user restart openclaw-gateway
openclaw mcp list # confirm "immich-mcp" is registeredHermes Agent
Hermes Agent reads MCP config from ~/.hermes/mcps.json. Add an entry:
{
"mcpServers": {
"immich-mcp": {
"command": "immich-mcp",
"env": {
"IMMICH_BASE_URL": "https://photos.example.com/api",
"IMMICH_API_KEY": "YOUR_KEY",
"IMMICH_ALLOW_WRITES": "false"
}
}
}
}Or, when running from a source checkout:
{
"mcpServers": {
"immich-mcp": {
"command": "node",
"args": ["/absolute/path/to/immich-mcp/dist/index.js"],
"env": {
"IMMICH_BASE_URL": "https://photos.example.com/api",
"IMMICH_API_KEY": "YOUR_KEY",
"IMMICH_ALLOW_WRITES": "false"
}
}
}
}Then reload MCP from inside a Hermes session:
/reload-mcpCodex CLI
Codex CLI reads MCP servers from ~/.codex/config.toml. Add a [mcp_servers.immich-mcp] block:
[mcp_servers.immich-mcp]
command = "immich-mcp"
env = { IMMICH_BASE_URL = "https://photos.example.com/api", IMMICH_API_KEY = "YOUR_KEY", IMMICH_ALLOW_WRITES = "false" }Or, when running from a source checkout:
[mcp_servers.immich-mcp]
command = "node"
args = ["/absolute/path/to/immich-mcp/dist/index.js"]
env = { IMMICH_BASE_URL = "https://photos.example.com/api", IMMICH_API_KEY = "YOUR_KEY", IMMICH_ALLOW_WRITES = "false" }Verify with:
codex mcp listExample Prompts
Show me memories from this week.
Calls immich_list_memories and filters by the current week.
Find duplicate photos and tell me which to delete (don't delete yet).
Calls immich_list_duplicates and returns the clusters as a dry run, without calling immich_resolve_duplicates.
Group these motion photos into a stack.
Calls immich_create_stack with the asset IDs and a primary pick.
License
MIT - see LICENSE.
