Immich MCP Server
Immich MCP Server
Stellt eine selbst gehostete Immich-Fotobibliothek für ChatGPT (und andere MCP-Clients) über Streamable HTTP bereit, sodass Sie Fragen wie „finde die Fotos vom Kigali-Standortbesuch im März“ stellen und echte Antworten von Ihrem eigenen NAS erhalten können.
ChatGPT ──HTTPS──▶ Cloudflare Tunnel ──▶ immich_mcp:8080 ──▶ immich_server:2283
bearer token MCP → REST x-api-keyChatGPT benutzerdefinierte Connectors akzeptieren nur einen remote HTTPS-Endpunkt — es gibt keine stdio- oder localhost-Option. Der Server muss also aus dem Internet erreichbar sein, daher der Tunnel, und er muss sich verteidigen, daher das Bearer-Token.
Inhaltsverzeichnis
Related MCP server: immich-photo-manager
Werkzeuge
Werkzeug | Zweck |
| CLIP semantische Suche über Bildinhalte |
| Vollständige EXIF-Daten für ein Asset per UUID |
| Filtern nach Datum, Ort, Kamera, Person, Favorit |
| Alle Alben mit Anzahl |
| Details und Inhalt eines Albums |
| Erkannte Gesichter mit IDs zum Filtern |
| Foto-/Videoanzahl und Speichernutzung |
| Immich-Version und aktivierte Funktionen |
| Öffentlicher Link zu bestimmten Assets — standardmäßig deaktiviert |
search und fetch sind bewusst benannt: ChatGPTs Deep Research-Modus ignoriert alle anderen Werkzeuge, daher tragen diese beiden die Last, wenn der Entwicklermodus nicht verfügbar ist.
Zugriff auf bestimmte Alben beschränken
Standardmäßig legt der Server alles offen, was der API-Schlüssel sehen kann. Um nur eine Teilmenge freizugeben, fügen Sie Album-UUIDs in ALLOWED_ALBUM_IDS ein:
python list_albums.py # prints every album with its UUIDALLOWED_ALBUM_IDS=a1b2c3d4-...,e5f6g7h8-...Jedes Werkzeug ist dann auf Assets in diesen Alben beschränkt. Immichs intelligente Suche hat keinen Albumfilter, daher erstellt der Server selbst die Menge der erlaubten Asset-IDs und verwirft alles außerhalb — einschließlich direktem fetch per UUID, das eine Ablehnung statt des Assets zurückgibt. Die Menge wird für SCOPE_TTL Sekunden zwischengespeichert, sodass Fotos, die zu einem erlaubten Album hinzugefügt werden, ohne Neustart erscheinen.
Zwei Ebenen sind kombinierenswert: Beschränken Sie den Immich-API-Schlüssel auf einen dedizierten Benutzer und setzen Sie ALLOWED_ALBUM_IDS. Der Schlüssel begrenzt, was dieser Server jemals erreichen könnte; die Albumliste begrenzt, was er tatsächlich offenlegt.
Verschiedene Clients verbinden
Der Server akzeptiert das Token auf drei Arten, da MCP-Clients sich darin unterscheiden, was sie senden können:
Client | URL | Authentifizierung |
ChatGPT-Connector |
|
|
Claude-Connector |
| OAuth-Felder leer lassen |
Claude Code, Cursor, Zed |
|
|
Alles URL-only |
| — |
Claudes benutzerdefinierter Connector-Dialog bietet nur OAuth-Client-ID und -Secret, die dieser Server nicht implementiert — daher die Pfadform. Die Sicherheit ist bei einem Token mit hoher Entropie gleichwertig, aber Pfade und Abfragezeichenfolgen landen leichter in Proxy-Logs und Shell-Verlauf als Header, daher bevorzugen Sie den Header, wo der Client es erlaubt.
Projektstruktur
immich-mcp/
├── Dockerfile
├── docker-compose.yml
├── .env <- you create this, never commit it
├── .env.example
├── .dockerignore
├── preflight.py <- validate config before building
├── run_local.py <- run without Docker, with auto-reload
├── list_albums.py <- discover album UUIDs for scoping
├── smoke_test.py <- full MCP handshake test
├── cloudflared/
│ └── config.example.yml
└── app/
├── immich_mcp.py
└── requirements.txtapp/ ist wichtig. Wenn diese beiden Dateien neben der Dockerfile statt in app/ landen, schlägt der Build mit "/app/immich_mcp.py": not found fehl.
Teil 1 — Zum Laufen auf Ihrem Laptop bringen
Optional, aber eine viel schnellere Schleife als ein Image für jede Konfigurationsänderung neu zu erstellen. Alles hier funktioniert auch auf dem NAS.
1. Einen Immich-API-Schlüssel erhalten
Immich → Kontoeinstellungen → API-Schlüssel → Neuer API-Schlüssel. Beschränken Sie ihn auf schreibgeschützt, es sei denn, Sie planen, Freigabelinks zu aktivieren.
Immich 3.x beschränkt Schlüssel pro Endpunkt. Die Werkzeuge hier benötigen Lesezugriff auf Assets, Alben, Personen und Suche. /users/me ist nicht erforderlich — der Preflight meldet einen fehlenden user.read-Bereich als Warnung, nicht als Fehler.
2. Konfigurieren
cp .env.example .env
openssl rand -hex 32 # paste into MCP_BEARER_TOKEN
$EDITOR .envVom Laptop aus muss IMMICH_URL die LAN-Adresse des NAS sein — immich_server ist ein Docker-Containername, der nur auf dem NAS selbst aufgelöst wird:
IMMICH_URL=http://192.168.0.43:2283Beachten Sie, dass es kein zweites http:// gibt. Ein doppeltes Schema ist ein häufiger Einfügefehler und führt zu einem verwirrenden Hostname-Fehler.
3. Preflight
pip install httpx python-dotenv
python preflight.pyÜberprüft die Projektstruktur, validiert .env, öffnet eine TCP-Verbindung zu Immich, bestätigt, dass der API-Schlüssel Assets lesen kann, und meldet, ob die intelligente Suche und Gesichtserkennung tatsächlich aktiviert sind. Es nennt die genaue Lösung für jeden Fehler.
Es lohnt sich, die gemeldete Asset-Anzahl zu lesen. Wenn es 1 Asset sichtbar sagt und Ihre Bibliothek Tausende hat, gehört der Schlüssel einem Benutzer, der fast nichts besitzt — alles nachgelagerte wird perfekt funktionieren und nichts zurückgeben.
4. Ohne Docker ausführen
pip install -r app/requirements.txt
python run_local.pyBedient auf http://127.0.0.1:8099 mit automatischem Neuladen. In einem zweiten Terminal:
python smoke_test.py http://127.0.0.1:8099 <your-bearer-token>Dies führt den exakten Handshake aus, den ChatGPT macht — initialize, tools/list, dann einen Live-Tool-Aufruf — und bestätigt, dass nicht authentifizierte Anfragen einen 401 erhalten.
5. Das Image erstellen (optional auf dem Laptop)
Wenn Sie den Docker-Build überprüfen möchten, bevor Sie ihn ausliefern, löschen Sie zuerst den networks:-Block aus docker-compose.yml — immich_default existiert nur auf dem NAS.
docker compose up -d --build
curl.exe http://127.0.0.1:8099/healthzTeil 2 — Auf dem NAS bereitstellen
Vier Dinge ändern sich: wie der Container Immich erreicht, welches Docker-Netzwerk er beitritt, Dateibesitzer und wie das Image erstellt wird.
0. Beide Geheimnisse zuerst rotieren
Wenn der Immich-API-Schlüssel oder das Bearer-Token in einen Chat, eine E-Mail oder ein freigegebenes Dokument eingefügt wurde, behandeln Sie es als kompromittiert. Dieser Endpunkt wird dem Internet ausgesetzt.
Immich → Kontoeinstellungen → API-Schlüssel → alten löschen, neuen erstellen
Neues Bearer-Token:
openssl rand -hex 32
Kopieren Sie nicht Ihr Laptop-.env rüber. Es zeigt IMMICH_URL auf eine LAN-Adresse, was funktioniert, aber Foto-Metadaten unnötig über das LAN hin und her leitet. Beginnen Sie mit .env.example auf dem NAS.
1. Das Projekt rüberkopieren
Platzieren Sie es neben Ihren anderen Stacks, z.B. /volume1/docker/immich-mcp/. Entweder per Drag & Drop über File Station oder:
scp -r . wanjau@<nas-ip>:/volume1/docker/immich-mcp/Überprüfen Sie, ob app/ überlebt hat — File Station Drag & Drop glättet manchmal Verzeichnisse:
ls -la /volume1/docker/immich-mcp/app/2. Den tatsächlichen Containernamen und das Netzwerk finden
SSH einloggen (Systemsteuerung → Terminal & SNMP → SSH aktivieren), dann:
sudo docker ps --format '{{.Names}}\t{{.Image}}' | grep -i immich
sudo docker network ls | grep -i immichContainer Manager stellt oft Projektnamen voran, daher erhalten Sie möglicherweise immich-immich_server-1 statt immich_server. Beweisen Sie, dass der Name von innerhalb von Docker aufgelöst wird, was tatsächlich zählt:
sudo docker run --rm --network <network-name> curlimages/curl:latest \
-s -o /dev/null -w '%{http_code}\n' http://<container-name>:2283/api/server/versionEin 200 hier bedeutet, dass der Rest davon langweilig ist. Wenn Sie es überspringen, erhalten Sie später einen Tunnel-502, der wie ein Cloudflare-Problem aussieht, aber keines ist.
3. .env auf dem NAS schreiben
cd /volume1/docker/immich-mcp
cp .env.example .env
vi .env
chmod 600 .envJetzt verwendet IMMICH_URL den Containernamen aus Schritt 2 und hält den Datenverkehr innerhalb von Docker:
IMMICH_URL=http://immich_server:2283
IMMICH_API_KEY=<the new key>
MCP_BEARER_TOKEN=<the new token>
PUBLIC_URL=https://photos.yourdomain.com
ALLOWED_ALBUM_IDS=4. Netzwerknamen und Benutzer korrigieren
Setzen Sie in docker-compose.yml das Netzwerk auf das, was Schritt 2 gemeldet hat:
networks:
immich-net:
external: true
name: immich_default # <- from step 2Die Dockerfile erstellt einen Benutzer mit UID 1027, der üblichen Synology-Konvention. Überprüfen Sie Ihre mit id; wenn sie abweicht, bearbeiten Sie entweder die Dockerfile oder überschreiben Sie in der Compose mit user: "1026:100". Ist nur wichtig, wenn Sie Volumes einbinden — eine Abweichung ist vorerst harmlos.
5. Preflight und Alben auswählen, von innerhalb eines Containers
DSMs Python ist umständlich, um Pakete zu installieren, und das Ausführen von Preflight auf dem Host würde die Container-zu-Container-Namensauflösung ohnehin nicht testen:
cd /volume1/docker/immich-mcp
sudo docker run --rm -it \
--network <network-name> \
-v "$PWD":/work -w /work \
python:3.12-slim sh -c "pip install -q httpx python-dotenv && python preflight.py"Derselbe Einzeiler führt list_albums.py aus. Kopieren Sie die UUIDs, die Sie freigeben möchten, in ALLOWED_ALBUM_IDS.
6. Erstellen und starten
sudo docker compose up -d --build
sudo docker compose logs -f immich-mcpAchten Sie auf drei Zeilen:
Immich MCP server configured for http://immich_server:2283
Scope: restricted to <album-id>
Album scope refreshed: 1 album(s), N asset(s)Wenn N 0 ist, ist die Album-ID falsch oder der Schlüssel kann dieses Album nicht lesen.
Die Container Manager GUI funktioniert auch — Projekt → Erstellen → auf den Ordner zeigen — aber sie hat manchmal Probleme mit external: true-Netzwerken. Verwenden Sie SSH, wenn es einen Fehler gibt.
7. Auf dem NAS überprüfen, bevor etwas freigegeben wird
curl -s http://127.0.0.1:8099/healthz | head -c 300Erwarten Sie Status ok, die Immich-Version und Ihre Bereichszusammenfassung. Dann den vollständigen Handshake:
sudo docker run --rm -it --network host \
-v "$PWD":/work -w /work \
python:3.12-slim sh -c "pip install -q httpx && \
python smoke_test.py http://127.0.0.1:8099 <bearer-token>"Ein hier gefundenes Problem ist ein Konfigurationsproblem. Das gleiche Problem, das nach dem nächsten Abschnitt gefunden wird, sieht wie ein Tunnelproblem aus.
Teil 3 — Freigeben und ChatGPT verbinden
1. Den Cloudflare-Tunnel-Hostnamen hinzufügen
Zero Trust-Dashboard → Netzwerke → Tunnel → Ihr Tunnel → Öffentlicher Hostname → Hinzufügen:
Subdomain:
immich-mcpDomain:
yourdomain.comService:
HTTP→immich_mcp:8080
Wenn cloudflared als Container läuft, muss es ein Netzwerk mit immich_mcp teilen, damit dieser Name aufgelöst wird; wenn es auf dem Host läuft, verwenden Sie http://127.0.0.1:8099. Siehe cloudflared/config.example.yml für das Äquivalent in der Konfigurationsdatei.
Fügen Sie keine Access-Richtlinie hinzu. ChatGPT kann keinen interaktiven Access-Login abschließen. Das Bearer-Token ist das einzige Tor — weshalb das Rotieren wichtig war.
Überprüfen Sie von außerhalb des LAN, wenn möglich; ein Telefon-Hotspot ist ein guter Test:
python smoke_test.py https://immich-mcp.yourdomain.com <bearer-token>2. Den Connector erstellen
Einstellungen → Connectors → Erweiterte Einstellungen → Entwicklermodus aktivieren (erfordert einen kostenpflichtigen Plan), dann Erstellen:
Name: Immich Photos
Description: dies ist wichtig — das Modell liest es, um zu entscheiden, ob der Connector aufgerufen werden soll. So etwas wie „Persönliche Foto- und Videobibliothek. Verwenden Sie sie zum Finden, Beschreiben oder Auflisten von Fotos, Alben und erkannten Personen.“
URL:
https://immich-mcp.yourdomain.com/mcpAuthentication: API key / custom header →
Authorization: Bearer <token>
Aktivieren Sie dann den Connector im Chat-Komponisten und testen Sie mit einem expliziten Werkzeugnamen:
Verwende immich search, um Fotos der Trockengestelle zu finden
Betrieb
Nennen Sie das Werkzeug in Ihrer Eingabeaufforderung. ChatGPT wird nicht zuverlässig erraten, wann es einen benutzerdefinierten Connector verwenden soll. „Verwende immich search, um Fotos der Trockengestelle zu finden“ funktioniert, wo „finde meine Trockengestell-Fotos“ oft nicht funktioniert.
ChatGPT kann Ihre Fotos nicht sehen. Werkzeugergebnisse sind Text — Beschreibungen und Metadaten, keine Pixel. create_share_link überbrückt diese Lücke, aber ein Freigabelink ist für jeden, der die URL hat, öffentlich, weshalb er standardmäßig deaktiviert ist.
Code aktualisieren. Bearbeiten Sie app/immich_mcp.py, dann sudo docker compose up -d --build.
Bearer-Token rotieren. Bearbeiten Sie .env, docker compose up -d --force-recreate, dann aktualisieren Sie den Connector in ChatGPT. Es gibt ein Zeitfenster, in dem ChatGPT defekt ist — tun Sie es, wenn Sie nicht mitten in einem Gespräch sind.
Fotos zu einem eingeschränkten Album hinzufügen. Nichts zu tun. Der Bereichscache wird alle SCOPE_TTL Sekunden (Standard 300) neu aufgebaut.
Autostart nach einem Neustart. restart: unless-stopped erledigt das, aber Container Manager-Projekte benötigen manchmal ein Häkchen für Autostart in der GUI. Starten Sie einmal bewusst neu, zu einem Zeitpunkt, der Ihnen passt, anstatt es zu entdecken, während Sie weg sind.
Fixieren Sie Ihre Immich-Version. Die API ändert sich zwischen Versionen — /server/statistics war vor nicht allzu langer Zeit /server-info/statistics. Ihre Instanz veröffentlicht die genaue Spezifikation unter https://photos.yourdomain.com/api/docs; überprüfen Sie dort, bevor Sie einen 404 debuggen.
Fehlerbehebung
Symptom | Cause |
Build: | Dateien sind flach; sie gehören in |
| Falscher Netzwerkname – wiederhole Teil 2 Schritt 2 |
| Immich nicht erreichbar – falsche |
Container wird sofort beendet | Fehlende erforderliche Umgebungsvariable – überprüfe |
| Falsche Album-ID, oder der Schlüssel kann dieses Album nicht lesen |
Preflight: API-Schlüssel mit 403 auf | Fehlender |
Preflight: nur 1 Asset sichtbar | Schlüssel gehört einem Benutzer, der fast nichts besitzt |
401 bei jeder Anfrage | Bearer-Token stimmt nicht zwischen |
Funktioniert auf dem NAS, 502 durch den Tunnel | cloudflared kann |
Tunnel gibt eine Login-Seite zurück | Eine Access-Richtlinie ist angehängt; entferne sie |
ChatGPT: "search action not found" | Im Deep Research-Modus hinzugefügt; aktiviere den Entwicklermodus |
Connector hinzugefügt, wird aber nie ausgelöst | Beschreibung zu vage, oder das Tool ist im Chat nicht aktiviert |
| Immich Machine Learning deaktiviert – überprüfe |
Immich lehnt den Schlüssel ab (401 in Logs) | Schlüssel widerrufen oder gehört zu einem anderen Immich-Benutzer |
This server cannot be deployed
Maintenance
Related MCP Connectors
Search photos and video moments by visual meaning, people, dates, and folders across local libraries, Apple Photos, and OneDrive. Manage collections, groups, favorites, people, and duplicate review. Synced metadata remains searchable while the desktop is offline; local and Apple Photos media access needs the owning device online with remote access enabled. OneDrive media can be accessed directly from the cloud. OAuth or Bearer API keys. Paid Cloud Access required; hosted visual search uses prepaid credits. Text-in-image search is semantic matching, not guaranteed exact OCR. Setup: https://organizewith.ai/en/guides/connect-ai-assistants
Search photos/videos; manage collections, people and duplicates. Requires paid OwAI Cloud Access.
AI-native digital asset management: semantic search, generative image edits, and CDN delivery.
Search, organize, and publish AI-generated images and video with provenance and lineage.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to search, browse, and retrieve metadata and images from your Google Photos library. It supports content-based filtering, album listing, and location extraction via STDIO and HTTP transports.54MIT
- AlicenseAqualityAmaintenanceManage your self-hosted Immich photo library through conversation — natural language search via CLIP, geographic album curation, duplicate detection with perceptual hashing,94124 PyPI62MIT
- AlicenseAqualityAmaintenanceEnables AI assistants to query and export from the macOS Apple Photos library using natural language, backed by osxphotos.211,219 npm36MIT

CoreViz MCPofficial
AlicenseNot gradedqualityDmaintenanceExposes a visual library with semantic search, tagging, editing, and management of photos as tools for AI agents like Claude Code.13 npm49MIT