← Discover MCPs and Agents
I
MCPOtherGitHub

ImmichMCP

MCP server for Immich photo management

Links

README

From the repo.

ImmichMCP

A Model Context Protocol (MCP) server for Immich - the self-hosted photo and video management solution. This server provides a first-class AI interface to manage your Immich library.

Features

  • Asset Management: Search, browse, upload, update, and delete photos/videos
  • Direct Local Upload: Authorize a short-lived, upload-only URL and stream a local folder straight to Immich — no API key exposed, nothing to install beyond curl, resumable by content dedup
  • Smart Search: ML-powered semantic search using CLIP (e.g., "sunset at the beach")
  • Metadata Search: Filter by date, location, camera, people, and more
  • Albums: Create, manage, and share photo albums
  • People: View and manage face recognition clusters
  • Tags: Organize assets with custom tags
  • Shared Links: Create shareable URLs for albums and assets
  • Activities: Add comments and likes to albums/assets

Requirements

  • .NET 10.0 SDK
  • Immich v3.0 or newer server instance
  • Immich API key

Compatibility

ImmichMCP 3.x targets Immich v3 APIs. Use an older ImmichMCP release for Immich v2 servers.

Integration Tests

Read-only integration tests can run against an existing Immich server without deploying ImmichMCP:

export IMMICH_BASE_URL="http://127.0.0.1:2283"
export IMMICH_API_KEY="your-api-key"
export IMMICH_INTEGRATION_TESTS=true
dotnet test ImmichMCP.Tests/ImmichMCP.Tests.csproj --filter "Category=Integration"

Mutation coverage (create/update/delete paths) is disabled by default. Enable it explicitly to also run the full 49-tool smoke:

export IMMICH_INTEGRATION_MUTATION_TESTS=true
dotnet test ImmichMCP.Tests/ImmichMCP.Tests.csproj --filter "Category=Integration"

(If your Immich runs somewhere not directly reachable, point IMMICH_BASE_URL at it however you normally reach it — e.g. a port-forward or tunnel — before running the tests.)

With mutation coverage enabled, ToolCoverageIntegrationTests exercises all 49 tools against the live server. It is strictly non-destructive to existing data: every mutation runs on throwaway fixtures the test creates (uploaded PNGs, an album, a tag, shared links, an activity) and teardown deletes only those; the two tools that would mutate real, un-creatable data (immich_people_update, immich_people_merge) are exercised with bogus IDs only and must refuse safely.

Deployment

ImmichMCP is published as a container image at ghcr.io/barryw/immichmcp. Run it wherever you host containers — Docker, Docker Compose, or Kubernetes.

  • Set IMMICH_BASE_URL and IMMICH_API_KEY (see Environment Variables).
  • Expose the HTTP port (default 5000). The MCP endpoint is served at /mcp. Two health endpoints are available: /health (liveness, use for restarts) and /health/ready (readiness, pings Immich and returns 503 if unreachable, use for traffic routing).
  • For remote/HTTP clients, set IMMICH_TOOL_MODE=gateway so clients enable tool categories on demand instead of loading all tools up front.

Docker Compose

cp .env.example .env          # set IMMICH_BASE_URL and IMMICH_API_KEY
docker compose up --build

Kubernetes

A sample manifest is provided in k8s/deployment.yaml — set the image, the two environment variables, and IMMICH_TOOL_MODE=gateway, then apply it with kubectl.

Installation

Option 1: Run from Source

# Clone the repository
git clone https://github.com/barryw/ImmichMCP.git
cd ImmichMCP

# Set environment variables
export IMMICH_BASE_URL="https://photos.example.com"
export IMMICH_API_KEY="your-api-key"

# Run with stdio transport (for Claude Desktop)
dotnet run --project ImmichMCP -- --stdio

# Or run with HTTP transport (for remote usage)
dotnet run --project ImmichMCP

Option 2: Docker

docker run -e IMMICH_BASE_URL="https://photos.example.com" \
           -e IMMICH_API_KEY="your-api-key" \
           -p 5000:5000 \
           ghcr.io/barryw/immichmcp:latest

Environment Variables

VariableRequiredDefaultDescription
IMMICH_BASE_URLYes-Base URL of your Immich instance
IMMICH_API_KEYYes-API key for authentication
MCP_LOG_LEVELNoInformationLogging level
DOWNLOAD_MODENourlurl returns URLs, base64 returns the file content inline as MCP image/resource content
MAX_INLINE_DOWNLOAD_BYTESNo26214400Max asset size returned inline with DOWNLOAD_MODE=base64; larger assets get a PAYLOAD_TOO_LARGE error that includes the download URL
MAX_PAGE_SIZENo100Maximum items per page
MCP_PORTNo5000HTTP server port
IMMICH_TOOL_MODENostaticstatic exposes all tools; gateway exposes immich_tools_list and immich_tools_enable first

In gateway mode, immich_tools_enable emits the MCP notifications/tools/list_changed notification so clients can refresh the normal tools/list inventory after enabling a category or tool.

Claude Desktop Configuration

Add to your Claude Desktop config (~/.config/claude/claude_desktop_config.json on Linux/macOS or %APPDATA%\Claude\claude_desktop_config.json on Windows):

{
  "mcpServers": {
    "immich": {
      "command": "dotnet",
      "args": ["run", "--project", "/path/to/ImmichMCP/ImmichMCP", "--", "--stdio"],
      "env": {
        "IMMICH_BASE_URL": "https://photos.example.com",
        "IMMICH_API_KEY": "your-api-key"
      }
    }
  }
}

Or with Docker:

{
  "mcpServers": {
    "immich": {
      "command": "docker",
      "args": ["run", "-i", "--rm",
               "-e", "IMMICH_BASE_URL=https://photos.example.com",
               "-e", "IMMICH_API_KEY=your-api-key",
               "ghcr.io/barryw/immichmcp:latest", "--stdio"]
    }
  }
}

Available Tools

Health & Capabilities

ToolDescription
immich_pingVerify connectivity and return server version
immich_capabilitiesList available API features

Assets

ToolDescription
immich_assets_listList recent assets with filters
immich_assets_getGet full asset metadata
immich_assets_exifGet EXIF data for an asset
immich_assets_download_originalGet download URL for original (or inline content with DOWNLOAD_MODE=base64)
immich_assets_download_thumbnailGet thumbnail/preview URLs (or inline preview image with DOWNLOAD_MODE=base64)
immich_assets_uploadUpload asset (base64)
immich_assets_upload_from_pathUpload from local file path
immich_assets_upload_authorizeMint a short-lived, upload-only URL so a client can upload local files directly to Immich (no API key exposed)
immich_assets_upload_initStart an out-of-band upload session; returns a URL to POST a file to
immich_assets_upload_statusCheck the status of an out-of-band upload session
immich_assets_updateUpdate asset metadata
immich_assets_bulk_updateBulk update multiple assets
immich_assets_deleteDelete asset(s)
immich_assets_statisticsGet asset statistics

Search

ToolDescription
immich_search_metadataSearch by metadata filters
immich_search_smartML-based semantic search (CLIP)
immich_search_ocrOCR text search inside images
immich_search_exploreGet explore/discovery data

Albums

ToolDescription
immich_albums_listList all albums
immich_albums_getGet album details
immich_albums_createCreate new album
immich_albums_updateUpdate album metadata
immich_albums_assets_addAdd assets to album
immich_albums_assets_removeRemove assets from album
immich_albums_deleteDelete album
immich_albums_statisticsGet album statistics

People

ToolDescription
immich_people_listList all recognized people
immich_people_getGet person details
immich_people_updateUpdate person info
immich_people_mergeMerge duplicate people
immich_people_assetsList assets for a person

Tags

ToolDescription
immich_tags_listList all tags
immich_tags_getGet tag by ID
immich_tags_createCreate new tag
immich_tags_updateUpdate tag
immich_tags_deleteDelete tag
immich_tags_assets_addTag assets
immich_tags_assets_removeRemove tag from assets

Shared Links

ToolDescription
immich_shared_links_listList all shared links
immich_shared_links_getGet shared link details
immich_shared_links_createCreate shared link
immich_shared_links_updateUpdate shared link
immich_shared_links_deleteDelete shared link

Activities

ToolDescription
immich_activities_listList comments/likes
immich_activities_createAdd comment or like
immich_activities_deleteDelete activity
immich_activities_statisticsGet activity statistics

Example Usage

Search for photos from last month

Search for photos taken in the last 30 days that are favorites

Create an album and add photos

Create a new album called "2026 Winter Vacation" and add all photos from January 2026

Smart search

Find photos of sunset at the beach

Bulk archive

Archive all photos from 2020 that aren't favorites

Upload a local folder (no install, no exposed API key)

Upload ~/Photos/Iceland2026 to Immich into an album called "Iceland 2026"

Because the MCP server is remote and cannot read your disk, immich_assets_upload_authorize mints a short-lived, upload-only shared-link URL scoped to a (dynamically created) album. The client then uploads the files directly to Immich with curl it already has — the master API key never leaves the server, and no CLI/script needs to be installed. Re-running is safe and resumable: Immich deduplicates by content, so already-uploaded files return duplicate. See the uploading-local-media doc for the exact client recipe.

// immich_assets_upload_authorize(album_name: "Iceland 2026", ttl_minutes: 120)
{
  "upload_url": "https://immich.example/api/assets?key=<token>",
  "album_id": "…", "shared_link_id": "…", "expires_at": "2026-07-02T14:00:00.0000000Z"
}
// then: POST each file to upload_url (multipart: assetData, fileCreatedAt, fileModifiedAt)

Safety Features

  • All destructive operations require explicit confirm: true parameter
  • Bulk operations default to dryRun: true mode
  • Dry runs return what would be affected without making changes

Response Format

All tools return a consistent JSON envelope:

{
  "ok": true,
  "result": { ... },
  "meta": {
    "request_id": "uuid",
    "page": 1,
    "page_size": 25,
    "total": 123,
    "next": "cursor-or-null",
    "immich_base_url": "https://photos.example.com"
  },
  "warnings": []
}

Error responses:

{
  "ok": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "Asset not found",
    "details": { ... }
  },
  "meta": { ... }
}

Upstream failures are never swallowed into empty/success-looking results: a non-2xx response from Immich surfaces as an error, and per the MCP spec every tool-execution error is returned as a result with isError: true (not a JSON-RPC protocol error), so the calling model can see and react to it. Error code maps the upstream status (AUTH_FAILED, NOT_FOUND, VALIDATION, RATE_LIMIT, UPSTREAM_ERROR).

License

MIT License - see LICENSE file for details.

Related Projects

  • Immich - Self-hosted photo and video management
  • PaperlessMCP - MCP server for Paperless-ngx

Collected info

  • 48 stars
  • 14 forks
  • Language: C#
  • Source updated: 9/20/2026

Config for your environment

Replace {MCP_ENDPOINT_URL} with this MCP’s endpoint URL (from its repo or docs above). No API key — you connect directly.

Tool

OS

Config file: ~/.cursor/mcp.json

{
  "mcpServers": {
    "mcp-server": {
      "url": "{MCP_ENDPOINT_URL}"
    }
  }
}

Paste into mcpServers in the config file. Restart Cursor after saving.

If this MCP is also published on mcpchannel.ai, you can subscribe from Browse and use the gateway config there instead.