Immich MCP Server
Immich MCP 服务器
将自托管的 Immich 照片库通过 Streamable HTTP 暴露给 ChatGPT(以及任何其他 MCP 客户端),这样你就可以提出诸如“查找三月份基加利现场考察的照片”之类的问题,并从你自己的 NAS 获得真实答案。
ChatGPT ──HTTPS──▶ Cloudflare Tunnel ──▶ immich_mcp:8080 ──▶ immich_server:2283
bearer token MCP → REST x-api-keyChatGPT 自定义连接器只接受 远程 HTTPS 端点——没有 stdio 或 localhost 选项。因此服务器必须能从互联网访问,所以才需要隧道,并且必须自我保护,所以才需要 bearer token。
目录
Related MCP server: immich-photo-manager
工具
工具 | 用途 |
| 基于 CLIP 语义的图像内容搜索 |
| 按 UUID 获取单个资产的完整 EXIF 数据 |
| 按日期、地点、相机、人物、收藏筛选 |
| 所有相册及其数量 |
| 单个相册的详细信息和内容 |
| 已识别的人脸,附带用于筛选的 ID |
| 照片/视频数量及磁盘使用情况 |
| Immich 版本和已启用的功能 |
| 指向特定资产的公开链接——默认关闭 |
search 和 fetch 是特意命名的:ChatGPT 的深度研究模式会忽略所有其他工具,因此如果开发者模式不可用,这两个工具将承担主要负载。
限制对特定相册的访问
默认情况下,服务器会暴露 API 密钥所能看到的所有内容。若只想共享子集,请在 ALLOWED_ALBUM_IDS 中放入相册 UUID:
python list_albums.py # prints every album with its UUIDALLOWED_ALBUM_IDS=a1b2c3d4-...,e5f6g7h8-...此后每个工具都被限制在这些相册内的资产中。Immich 的智能搜索没有相册过滤器,因此服务器自行构建允许的资产 ID 集合,并丢弃任何不在其中的内容——包括直接按 UUID 的 fetch,此时会返回拒绝而非资产。该集合会缓存 SCOPE_TTL 秒,因此添加到允许相册中的照片无需重启即可出现。
建议结合两层限制:将 Immich API 密钥限定给专用用户,同时设置 ALLOWED_ALBUM_IDS。密钥限制了此服务器可能触及的范围;相册列表则限制了它实际暴露的内容。
连接不同的客户端
服务器接受三种方式的 token,因为 MCP 客户端能发送的内容各不相同:
客户端 | URL | 认证方式 |
ChatGPT 连接器 |
|
|
Claude 连接器 |
| 留空 OAuth 字段 |
Claude Code, Cursor, Zed |
|
|
仅 URL 的任意客户端 |
| — |
Claude 的自定义连接器对话框只提供 OAuth 客户端 ID 和密钥,而此服务器未实现这些——因此采用了路径形式。在高熵 token 下安全性是等效的,但路径和查询字符串比请求头更容易出现在代理日志和 shell 历史中,因此如果客户端允许,优先使用请求头。
项目结构
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/ 很重要。如果这两个文件最终位于 Dockerfile 旁边而不是 app/ 内部,构建将失败,并显示 "/app/immich_mcp.py": not found。
第一部分——在笔记本电脑上运行
可选,但比每次配置更改都重建镜像要快得多。这里的所有内容在 NAS 上同样适用。
1. 获取 Immich API 密钥
Immich → 账户设置 → API 密钥 → 新建 API 密钥。除非你计划启用分享链接,否则将其限定为只读。
Immich 3.x 按端点限定密钥作用域。这里的工具需要对资产、相册、人物和搜索的读取权限。不需要 /users/me——预检会将缺少 user.read 作用域报告为警告而非失败。
2. 配置
cp .env.example .env
openssl rand -hex 32 # paste into MCP_BEARER_TOKEN
$EDITOR .env从笔记本电脑上,IMMICH_URL 必须是 NAS 的 LAN 地址——immich_server 是一个仅在 NAS 本身上可解析的 Docker 容器名称:
IMMICH_URL=http://192.168.0.43:2283注意没有第二个 http://。重复的协议方案是常见的粘贴错误,会导致令人困惑的主机名失败。
3. 预检
pip install httpx python-dotenv
python preflight.py检查项目布局,验证 .env,打开到 Immich 的 TCP 连接,确认 API 密钥可以读取资产,并报告智能搜索和人脸识别是否实际启用。它会指出每个失败的具体修复方法。
值得阅读它报告的资产数量。如果显示 1 个资产可见 而你的库有数千个,说明该密钥属于一个几乎不拥有任何内容的用户——所有下游操作都会完美运行但返回空结果。
4. 无需 Docker 运行
pip install -r app/requirements.txt
python run_local.py在 http://127.0.0.1:8099 上提供服务,并启用自动重载。在第二个终端中:
python smoke_test.py http://127.0.0.1:8099 <your-bearer-token>这会运行 ChatGPT 执行的精确握手——初始化、tools/list,然后是一个实时的工具调用——并确认未经认证的请求会收到 401。
5. 构建镜像(笔记本电脑上可选)
如果你想在部署前验证 Docker 构建,请先删除 docker-compose.yml 中的 networks: 块——immich_default 只存在于 NAS 上。
docker compose up -d --build
curl.exe http://127.0.0.1:8099/healthz第二部分——部署到 NAS
有四件事会改变:容器如何访问 Immich、加入哪个 Docker 网络、文件所有权以及镜像的构建方式。
0. 首先轮换两个密钥
如果 Immich API 密钥或 bearer token 已被粘贴到聊天、电子邮件或共享文档中,请视为已泄露。此端点即将面向互联网。
Immich → 账户设置 → API 密钥 → 删除旧的,创建新的
新的 bearer token:
openssl rand -hex 32
不要复制笔记本电脑上的 .env。它指向 LAN 地址的 IMMICH_URL 虽然能工作,但会无缘无故地将照片元数据路由到 LAN 再返回。请在 NAS 上从 .env.example 开始。
1. 将项目复制过去
将其放在其他堆栈旁边,例如 /volume1/docker/immich-mcp/。可以通过 File Station 拖入,或使用:
scp -r . wanjau@<nas-ip>:/volume1/docker/immich-mcp/验证 app/ 是否完好——File Station 的拖放有时会压平目录:
ls -la /volume1/docker/immich-mcp/app/2. 查找真实的容器名称和网络
SSH 登录(控制面板 → 终端和 SNMP → 启用 SSH),然后:
sudo docker ps --format '{{.Names}}\t{{.Image}}' | grep -i immich
sudo docker network ls | grep -i immichContainer Manager 通常会在名称前加上项目前缀,因此你可能会得到 immich-immich_server-1 而不是 immich_server。从 Docker 内部 验证名称解析是否有效,这才是真正重要的:
sudo docker run --rm --network <network-name> curlimages/curl:latest \
-s -o /dev/null -w '%{http_code}\n' http://<container-name>:2283/api/server/version如果返回 200,那么剩下的步骤就很简单了。跳过这一步意味着稍后会出现隧道 502 错误,看起来像是 Cloudflare 的问题,但实际上不是。
3. 在 NAS 上编写 .env
cd /volume1/docker/immich-mcp
cp .env.example .env
vi .env
chmod 600 .env现在 IMMICH_URL 使用步骤 2 中的容器名称,将流量保留在 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. 修复网络名称和用户
在 docker-compose.yml 中,将网络设置为步骤 2 报告的名称:
networks:
immich-net:
external: true
name: immich_default # <- from step 2Dockerfile 创建了一个 UID 为 1027 的用户,这是通常的 Synology 约定。使用 id 检查你的 UID;如果不同,可以编辑 Dockerfile 或在 compose 中使用 user: "1026:100" 覆盖。只有在你挂载卷时才重要——目前不匹配是无害的。
5. 从容器内部进行预检并选择相册
DSM 的 Python 安装包比较麻烦,而且在主机上运行预检也无法测试容器到容器的名称解析:
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"同一个单行命令可以运行 list_albums.py。将你想要暴露的 UUID 复制到 ALLOWED_ALBUM_IDS 中。
6. 构建并启动
sudo docker compose up -d --build
sudo docker compose logs -f immich-mcp注意三行输出:
Immich MCP server configured for http://immich_server:2283
Scope: restricted to <album-id>
Album scope refreshed: 1 album(s), N asset(s)如果 N 为 0,说明相册 ID 错误或密钥无法读取该相册。
Container Manager GUI 也可以工作——项目 → 创建 → 指向文件夹——但它有时在处理 external: true 网络时会遇到问题。如果出错,请使用 SSH。
7. 在暴露任何内容之前在 NAS 上验证
curl -s http://127.0.0.1:8099/healthz | head -c 300预期输出为 status ok、Immich 版本以及你的作用域摘要。然后进行完整握手:
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>"在这里发现的问题是配置问题。同样的发现在下一节之后看起来就像是隧道问题。
第三部分——暴露并连接 ChatGPT
1. 添加 Cloudflare Tunnel 主机名
Zero Trust 仪表板 → 网络 → 隧道 → 你的隧道 → 公共主机名 → 添加:
子域名:
immich-mcp域名:
yourdomain.com服务:
HTTP→immich_mcp:8080
如果 cloudflared 作为容器运行,它必须与 immich_mcp 共享网络才能解析该名称;如果它在主机上运行,请使用 http://127.0.0.1:8099。配置文件等效项请参见 cloudflared/config.example.yml。
不要附加 Access 策略。 ChatGPT 无法完成交互式 Access 登录。Bearer token 是唯一的门禁——这就是为什么轮换它很重要。
如果可能,请从 LAN 外部验证;手机热点是一个很好的测试:
python smoke_test.py https://immich-mcp.yourdomain.com <bearer-token>2. 创建连接器
设置 → 连接器 → 高级设置 → 启用 开发者模式(需要付费计划),然后创建:
名称:Immich Photos
描述:这很重要——模型会读取它来决定是否调用连接器。类似 "个人照片和视频库。用于查找、描述或列出照片、相册和已识别的人物。"
URL:
https://immich-mcp.yourdomain.com/mcp认证:API 密钥 / 自定义请求头 →
Authorization: Bearer <token>
然后在聊天编辑器中启用该连接器,并使用明确的工具名称进行测试:
使用 immich search 查找干燥架的照片
运维
在提示中明确指定工具名称。 ChatGPT 无法可靠地猜测何时使用自定义连接器。"使用 immich search 查找干燥架的照片" 有效,而 "查找我的干燥架照片" 通常无效。
ChatGPT 无法看到你的照片。 工具结果是文本——描述和元数据,而不是像素。create_share_link 可以弥补这一差距,但分享链接对任何持有 URL 的人都是公开的,这就是为什么它默认被禁用。
更新代码。 编辑 app/immich_mcp.py,然后执行 sudo docker compose up -d --build。
轮换 bearer token。 编辑 .env,执行 docker compose up -d --force-recreate,然后在 ChatGPT 中更新连接器。会有一个 ChatGPT 中断的窗口——请在非对话进行时操作。
向限定范围的相册添加照片。 无需任何操作。作用域缓存每 SCOPE_TTL 秒(默认 300)重建一次。
重启后自动启动。 restart: unless-stopped 会处理,但 Container Manager 项目有时需要在 GUI 中勾选自动重启。请在你方便的时候有意重启一次,而不是在离开时才发现问题。
锁定你的 Immich 版本。 API 在不同版本之间会变化——/server/statistics 不久前还是 /server-info/statistics。你的实例在 https://photos.yourdomain.com/api/docs 发布了精确规范;在调试 404 之前请先检查那里。
故障排除
症状 | 原因 |
构建: | 文件是扁平的;它们应位于 |
| 网络名称错误 — 重新执行第2部分第2步 |
| 无法访问 Immich — |
容器立即退出 | 缺少必需的环境变量 — 检查 |
| 专辑 ID 错误,或密钥无法读取该专辑 |
预检:API 密钥在 | 缺少 |
预检:仅可见 1 个资产 | 密钥属于一个几乎没有任何资产的用户 |
每次请求都返回 401 |
|
在 NAS 上工作正常,通过隧道返回 502 | cloudflared 无法解析 |
隧道返回登录页面 | 附加了访问策略;请移除它 |
ChatGPT:"search action not found" | 在深度研究模式下添加;启用开发者模式 |
连接器已添加但从未触发 | 描述过于模糊,或工具未在聊天中启用 |
| Immich 机器学习已禁用 — 检查 |
Immich 拒绝密钥(日志中显示 401) | 密钥已撤销,或属于不同的 Immich 用户 |
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.56MIT
- AlicenseAqualityAmaintenanceManage your self-hosted Immich photo library through conversation — natural language search via CLIP, geographic album curation, duplicate detection with perceptual hashing,94250 PyPI62MIT
- AlicenseAqualityAmaintenanceEnables AI assistants to query and export from the macOS Apple Photos library using natural language, backed by osxphotos.211,306 npm38MIT

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