immich-mcp
Connects to a self-hosted Immich instance's REST API, providing tools across 22 toolsets (assets, albums, people, faces, search, server, admin, users, sessions, libraries, tags, trash, memories, jobs, shared links, API keys, partners, activities, notifications, sync, plugins, workflows, cluster groups) covering 287 operations for browsing, searching, uploading, and managing photos and videos, with write operations gated behind explicit confirmation.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@immich-mcpsearch my photos for beach sunsets from last summer"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
immich-mcp (Immich MCP connector)
MCP connector for a self-hosted Immich instance. It speaks the Immich REST API over stdio and over stateless Streamable HTTP on localhost.
Immich is AGPL-3.0 software. This connector is MIT. It only calls the public REST API on the server you configure. It is not affiliated with Immich or the Immich maintainers. Bring your own API key from the Immich user settings.
The connector covers all 199 paths and 287 operations in immich.openapi.json (Immich 3.3.0-rc.0). Operations are grouped into 22 toolsets. Enable a subset with IMMICH_TOOLSETS so the model only sees the tools you need.
Setup
npm install
npm run ci
npm start
npm run start:httpnpm start speaks stdio. npm run start:http serves Streamable HTTP at http://127.0.0.1:3000/mcp and GET /health. HTTP mode has no authentication. Keep it on localhost.
Create an API key in Immich (Account settings, API Keys). The connector sends it as x-api-key and never prints it.
{
"mcpServers": {
"immich": {
"command": "node",
"args": ["/workspace/connectors/immich/dist/index.js"],
"env": {
"IMMICH_URL": "https://photos.example.com",
"IMMICH_API_KEY": "...",
"IMMICH_ALLOW_WRITES": "false",
"IMMICH_TOOLSETS": "assets,albums,people,search,server",
"IMMICH_CONTACT": "you@example.com"
}
}
}
}A trailing /api on IMMICH_URL is stripped. The API is called at {IMMICH_URL}/api.
Docker (HTTP, no authentication, localhost only):
docker build -t immich-mcp .
docker run -p 3000:3000 \
-e IMMICH_URL=http://host.docker.internal:2283 \
-e IMMICH_API_KEY=... \
immich-mcpDo not put the API key in the image.
Regenerate the operations registry after an OpenAPI bump:
npm run gen:operationsRelated MCP server: shutter-mcp
Config
Variable | Meaning |
| Server base, for example |
| API key. Sent as |
| Must be the literal |
| Comma list of toolsets, or |
| Local request budget. Default 30. |
| Upstream timeout. Default 20000. |
| GET cache TTL. Default 60. Writes clear the cache. |
| Contact token in the User-Agent. |
|
|
| HTTP port. Default 3000. |
Safety
Every non-GET operation is gated unless the registry marks it read-only. Search metadata, smart search, random search, bulk-upload check, download info, and a few other POST reads are read-only. They run without confirm.
A write needs confirm: true and IMMICH_ALLOW_WRITES=true. Otherwise the tool returns a dry-run preview of the exact method, path, query, and body. The API key is redacted. Deletes, empty trash, user deletion, library scan or removal, API-key and session revoke, shared-link creation, and admin config changes add extra warnings in that preview.
Asset upload is multipart from a local file_path and is confirm-gated. Original and thumbnail downloads return metadata only, or write bytes to save_path. Binaries are not dumped into the model context. Server filesystem paths, tokens, passwords, and shared-link keys are stripped or redacted.
Tools
Default IMMICH_TOOLSETS publishes 5 tools (107 operations). IMMICH_TOOLSETS=all publishes 22 tools (287 operations). Each tool takes action plus params, query, body, and optional file_path, save_path, and confirm.
Toolset | Tool | Operations | Tags | Default |
assets |
| 43 | Assets, Asset files, Download, Duplicates, Stacks | yes |
albums |
| 13 | Albums | yes |
people |
| 19 | People, Faces | yes |
search |
| 16 | Search, Map, Timeline, Views | yes |
server |
| 16 | Server, Config (public) | yes |
admin |
| 40 | Users (admin), Maintenance (admin), Config (admin), Database Backups (admin), Notifications (admin), Authentication (admin), System config, System metadata | no |
users |
| 18 | Users, Config (user) | no |
sessions |
| 31 | Sessions, Authentication, Passkeys | no |
libraries |
| 8 | Libraries | no |
tags |
| 9 | Tags | no |
trash |
| 3 | Trash | no |
memories |
| 8 | Memories | no |
jobs |
| 8 | Jobs, Queues | no |
shared-links |
| 9 | Shared links | no |
api-keys |
| 7 | API keys | no |
partners |
| 5 | Partners | no |
activities |
| 4 | Activities | no |
notifications |
| 6 | Notifications | no |
sync |
| 4 | Sync | no |
plugins |
| 4 | Plugins | no |
workflows |
| 8 | Workflows | no |
cluster-groups |
| 8 | Cluster groups | no |
Example. List albums, then create one after previewing:
{ "action": "get_all_albums" }{ "action": "create_album", "body": { "albumName": "Trip" } }{ "action": "create_album", "body": { "albumName": "Trip" }, "confirm": true }Live check
npm run live-check talks to a real Immich when IMMICH_URL and IMMICH_API_KEY are set. It exercises read tools and confirm-gated create, modify and delete cycles for albums, tags, assets (upload, download, update, delete), memories, shared links and API keys. If those variables are unset, it prints a skip message and exits 0.
LIVE-CHECK.md records the real run (Immich v3.3.0-rc.0 built from source on the box, failed=0) and lists what was not exercised live.
License
MIT, see LICENSE. This is an independent, unofficial connector and is not endorsed by the Immich project or its owners.
The upstream immich.openapi.json comes from a AGPL-3.0 project, so it is not shipped here. src/operations.ts was generated from it, and tests fall back to a route-only fixture in test/fixtures/. To regenerate, download the spec from the upstream project into the repo root (it is gitignored) and run node scripts/gen-operations.mjs.
This server cannot be deployed
Maintenance
Related MCP Connectors
Read-only MCP server over the JENRIKS daily photoblog: one photo per day since 2006. No auth.
- RasterOAuthapp.raster
Browse, search, upload, tag, transfer, and delete images in your Raster libraries over MCP.
Remote MCP server for full read/write access to a Zotero library
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables MCP-compatible clients to interact with an Immich photo management instance, providing access to users, assets, API keys, and partners through standardized resources and tools.1MIT
- AlicenseAqualityBmaintenanceA local, read-only MCP server that lets AI agents inspect and analyze photo libraries by scanning files, aggregating EXIF stats, finding duplicates, scoring blur, and generating cull reports without uploading any data.6MIT

Lumaflux MCP Serverofficial
AlicenseNot gradedqualityAmaintenanceEnables local agents to browse, import, organize, nondestructively edit, and export photos in a running desktop photo catalog, with revision-checked edits, previews, and batch operations over an authenticated loopback endpoint or bundled stdio adapter.MIT- AlicenseDqualityCmaintenanceEnables secure, configurable access to one or more Syncthing instances over MCP, with read-only defaults and opt-in write, destructive, and administrative operations. Supports stdio and authenticated Streamable HTTP transports, typed tools, bounded responses, and multi-instance configuration.40MIT