Immich-photo-manager album-manager

install
source · Clone the upstream repo
git clone https://github.com/drolosoft/immich-photo-manager
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/drolosoft/immich-photo-manager "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/album-manager" ~/.claude/skills/drolosoft-immich-photo-manager-album-manager && rm -rf "$T"
manifest: skills/album-manager/SKILL.md
source content

Album Manager

⚠️ Connection Required — ALWAYS CHECK FIRST

Before doing ANYTHING else in this skill, call

ping
on the Immich MCP server.

  • If
    ping
    succeeds → proceed with the skill normally.
  • If
    ping
    fails or the MCP tools are not available → STOP. Do not continue. Tell the user:

Immich is not connected. This plugin needs a running Immich MCP server to work.

Run /setup-immich-photo-manager to configure your Immich connection. You'll need:

  1. Your Immich server URL (e.g.,
    http://192.168.1.100:2283
    )
  2. An Immich API key (how to create one)
  3. The MCP server running (
    ./immich-mcp-server
    )

Nothing in this plugin will work until the connection is configured.

Do NOT skip this check. Do NOT try to run any other tool first. Always ping, always block if it fails.

Intelligent album creation and curation for Immich photo libraries. Organizes photos geographically by default — albums represent places, not dates.

Core Principle

Geography first, chronology second. A user who visited Mexico twice gets one "Mexico" album (or sub-albums by city), not "Mexico 2018" and "Mexico 2023". Dates are metadata shown inside the album, never the organizing principle.

Available MCP Tools

Use the Immich MCP tools for all API interactions:

  • immich_search_assets
    — Search by GPS coordinates, date range, city, country, camera, person, or smart/CLIP text query
  • immich_create_album
    — Create a new album with name and description
  • immich_add_assets_to_album
    — Add photos/videos to an album by asset IDs
  • immich_remove_assets_from_album
    — Remove assets from an album
  • immich_list_albums
    — List all albums with asset counts
  • immich_get_album
    — Get album details including all assets
  • immich_delete_album
    — Delete an album (does NOT delete the photos)
  • immich_create_shared_link
    — Create a public shared link for an album (makes it visible in Gallery)
  • immich_get_asset_info
    — Get full metadata for a specific asset (GPS, EXIF, dates)
  • immich_get_statistics
    — Get library statistics (total photos, videos, storage)
  • immich_get_asset_thumbnail
    — Get base64 thumbnail for an asset (used for gallery HTML generation)

Album Creation Workflow

1. Discover photos for a location

Search by GPS bounding box OR by CLIP semantic search OR by date range:

# GPS-based (most accurate)
immich_search_assets(latitude=41.87, longitude=12.49, radius_km=50)  # Rome area

# CLIP semantic search (when GPS is missing)
immich_search_assets(query="Colosseum Rome Italy")

# Date-based (supplement)
immich_search_assets(date_from="2023-06-01", date_to="2023-06-15")

# Combined
immich_search_assets(latitude=41.87, longitude=12.49, radius_km=50, date_from="2023-06-01")

2. Filter and curate

From the search results, filter out:

  • Screenshots (typical screen resolutions, no GPS, no lens info)
  • Duplicate/near-duplicate images
  • Blurry or very dark photos (if quality metadata available)
  • Photos that don't match the location theme

Prefer photos that:

  • Have strong composition or visual interest
  • Show landmarks, landscapes, or characteristic scenes of the place
  • Have good resolution and quality
  • Tell the story of the place

Target: 20-50 photos per album for optimal gallery experience. Can go up to 100 for major destinations.

3. Create the album

Naming convention:

[Country emoji] Place, Country
Examples:
🇮🇹 Cinque Terre, Italia
🇪🇬 Cairo & Luxor, Egypt
🇲🇽 Chiapas, México
🏝️ Lanzarote
🌴 La Palma
🏙️ Barcelona

For the description, include:

  • When the photos were taken (year or date range)
  • Brief context (e.g., "Summer road trip through coastal villages")
  • Number of photos

4. Share for Gallery publication

After creating the album, create a shared link to make it visible in the Gallery frontend:

immich_create_shared_link(album_id="{id}", show_metadata=true, allow_download=false)

5. Verify

Confirm the album appears correctly:

  • Check album name and description
  • Verify photo count matches expectations
  • Confirm shared link is active

Batch Album Creation

When creating multiple albums at once (e.g., "create albums for all my trips"):

  1. First, get library statistics and map view data to understand what locations exist
  2. Cluster photos by GPS coordinates to identify distinct locations
  3. Present a proposed album list to the user for approval BEFORE creating
  4. Create albums one by one, reporting progress
  5. Summarize all created albums at the end

Always err on the side of creating MORE albums — the user can merge or delete later. It's easier to remove an unwanted album than to discover a missing one.

Handling Missing GPS Data

Many photos (especially older ones or screenshots) lack GPS coordinates. Strategy:

  1. First search by GPS for photos that have it
  2. Then search by date range to find photos taken during the same trip
  3. Use CLIP semantic search as a fallback ("beach Lanzarote", "pyramid Egypt")
  4. Flag photos without GPS that were found by date/CLIP — they may or may not belong

Album Maintenance

When asked to update or refine an existing album:

  1. Get current album contents
  2. Search for additional photos that might belong (expanded date range, nearby GPS, related CLIP queries)
  3. Present additions and potential removals to the user
  4. Apply changes after approval

Gallery HTML Generation

When the user asks to "show me photos from [album]", "generate a gallery for [album]", "show me [album name]", or any variation of viewing/displaying album contents visually, generate an interactive HTML gallery page.

Template

Use the gallery template at

assets/viewer-template.html
(from the plugin root). This is a self-contained, single-file HTML gallery with:

  • Triple theme support — Light, System (auto-detects), and Dark modes
  • 5 view modes: detail grid, icon grid, list, masonry, compact
  • Full-screen gallery overlay with keyboard navigation (arrows, Escape, Space for slideshow)
  • Touch/swipe gestures for mobile
  • Lazy loading with intersection observers
  • Manual pagination with "Load more" button (no infinite scroll)
  • Slideshow mode with progress bar
  • Polaroid-style album cards linking back to Immich
  • Responsive design for all screen sizes

Placeholder Reference

The template uses these placeholders that MUST be replaced:

PlaceholderDescriptionExample
{{ALBUM_NAME}}
Display name of the album
Lanzarote Verde
{{ALBUM_TOTAL}}
Total number of photos in the album
273
{{SEARCH_QUERY}}
The query or description used to find photos
“green landscapes in Lanzarote”
{{IMMICH_URL}}
Immich server base URL
https://your-immich-server.com
{{PAGE_SIZE}}
Number of photos per lazy-load page
20
{{PHOTO_COUNT}}
Total photos in the gallery (limit ~50 for file size)
50
{{PHOTO_ENTRIES}}
The photo data entries (see format below)See below
{{ALBUMS_JSON}}
JSON array of album linksSee below

Photo Entry Format (base64 embedded thumbnails)

The Cowork viewer runs in an

about:
protocol sandbox that blocks ALL external network requests. Thumbnails MUST be embedded as base64
data:
URIs.

Each entry in

{{PHOTO_ENTRIES}}
includes the full thumbnail data:

{src:'data:image/jpeg;base64,/9j/4AAQ...',id:'<asset-id>',name:'<filename>',date:'<ISO-date>'}
  • src
    : Base64 data URI of the thumbnail (from
    get_thumbnails_batch
    , size=thumbnail, ~250px, ~15-25KB each)
  • id
    : The Immich asset ID (for linking to Immich web UI)
  • name
    : Original filename (displayed as label)
  • date
    : ISO date string from the asset metadata

Always use

size="thumbnail"
(250px) — never
preview
(1440px). Thumbnails average ~18KB each, so 50 photos ≈ 0.9MB HTML file.

Entries are comma-separated, one per line.

Albums JSON Format

{{ALBUMS_JSON}}
is injected raw into JS. It can be either a JSON array
[{...}]
or a single object
{...}
— the template handles both. Use standard JSON with quoted keys:

[{"id":"<album-id>","name":"<Album Name>","total":<count>}]

Each album object needs:

id
(string),
name
(string),
total
(integer).

Generation Workflow

  1. Get album data: Call
    get_album
    to get the album ID, name, and full asset list (IDs, filenames, dates)
  2. Fetch thumbnails: Call
    get_thumbnails_batch(asset_ids=[...], size="thumbnail", limit=50)
    — call in batches of 50 if needed
  3. Read the template: Read
    assets/viewer-template.html
    from the plugin root
  4. Replace placeholders: Fill in all
    {{...}}
    placeholders
  5. Build
    {{PHOTO_ENTRIES}}
    :
    {src:'data:...',id:'...',name:'...',date:'...'}
    for each asset with base64 thumbnail
  6. Write the HTML: Save to the outputs directory as
    <album-name-slug>.html
    (~0.9MB for 50 photos)
  7. Present to user: Share the file link via
    computer://

get_thumbnails_batch
is REQUIRED. The Cowork sandbox blocks all external requests — base64 is the only way.

⚠️ Placeholder Rules (IMPORTANT)

  • {{PAGE_SIZE}}
    ,
    {{PHOTO_COUNT}}
    ,
    {{ALBUM_TOTAL}}
    : Must be plain integers (e.g.
    200
    , not
    200+
    or
    "200"
    ). These are injected directly into JavaScript.
  • {{ALBUM_NAME}}
    ,
    {{SEARCH_QUERY}}
    ,
    {{IMMICH_URL}}
    : Can be any string (they are placed inside HTML or JS string literals).
  • {{PHOTO_ENTRIES}}
    : Must be valid JS object literals, comma-separated.
  • {{ALBUMS_JSON}}
    : Must be comma-separated JSON objects (NOT wrapped in array brackets — the template adds
    [...]
    ). Example:
    {"id":"abc","name":"My Album","total":50}
    . If no related albums, use empty string.

CRITICAL: Related Albums = REAL Albums Only

The

{{ALBUMS_JSON}}
placeholder must ONLY contain real, user-created albums. Never fabricate album entries. Never create temporary albums to populate this field.

When generating a gallery for an album, find OTHER real albums that are related (e.g., same country, same trip) and list them as Related Albums. If there are no related albums, use

[]
.

Performance Notes

  • PAGE_SIZE: Keep at 20 for initial load. Pagination is manual ("Load more" button)
  • PHOTO_COUNT: Limit to ~50 photos per gallery for reasonable file size (~0.9MB)
  • Thumbnails: Embedded as base64 via
    get_thumbnails_batch(size="thumbnail")
    — ~18KB avg each
  • For albums with 100+ photos, show first 50 and tell the user the total count

Example: Generating a gallery

User: "Show me photos from Lanzarote Verde"

1. list_albums() -> find "Lanzarote Verde" album (id: abc123, 273 photos)
2. get_album(album_id="abc123") -> get full asset list with IDs, names, dates
3. Read assets/viewer-template.html
4. Replace:
   - {{ALBUM_NAME}} -> "Lanzarote Verde"
   - {{ALBUM_TOTAL}} -> 273
   - {{SEARCH_QUERY}} -> "Lanzarote Verde"
   - {{IMMICH_URL}} -> "https://your-immich-server.com"
   - {{PAGE_SIZE}} -> 20
   - {{PHOTO_COUNT}} -> 50 (first 50 of 273)
   - {{PHOTO_ENTRIES}} -> {src:'data:image/jpeg;base64,...',id:"abc",name:"IMG_001",date:"2023-06-15"},{src:'data:...',id:"def",...}
   - {{ALBUMS_JSON}} -> {"id":"abc123","name":"Lanzarote Verde","total":273}
5. Save as lanzarote-verde.html (~0.9MB)
6. Present computer:// link

Reference Files

  • references/geographic-search-patterns.md
    — GPS bounding boxes of common destinations and search strategies
  • assets/index-template.html
    — Dashboard template listing all saved gallery HTML files
  • assets/viewer-template.html
    — Self-contained HTML gallery template with dark/light themes, multiple view modes, slideshow, Cowork Actions Panel, and keyboard navigation