Skip to main content
Glama

Export PDF

export_pdf

Build a PDF book from an Immich album or asset list, including photos, video frames, and metadata like date, place, and tags.

Instructions

Build a PDF (cover, index, places, one section per asset) from an album or a list of assets, on the machine running this server. Immich metadata (date, place, camera, people, tags) is always included; pass captions {asset_id: text} with what you saw to add your analysis. Video frames go straight into the PDF and cost no tokens (up to 120 per video). The PDF never enters the conversation unless return_base64=True. If the user asked for a PDF without saying how they want it, call get_export_preview first and ask them about the choices it lists.

Keep the selection coherent: one story per PDF. Never mix unrelated assets
(two videos about different things, photos from different events) just to
show more; if the user's material spans several stories, offer one PDF per
story instead.

Args:
    album_id: Album UUID, or asset_ids: explicit asset UUIDs (exactly one of the two).
    output_path: Where to write (default ~/Desktop/<title>.pdf). Existing files are never overwritten.
    title: Cover title (default: album name or "Immich export <date>").
    captions: {asset_id: text} written after looking at the images.
    layout: 'detail' (one asset per page with its data, default), 'grid' (six per page)
        or 'photobook' (one asset per page, image as large as it fits, caption under
        it; a video with several chosen frames unfolds into one full page per frame).
    frames_per_video: Frames per video, evenly spaced (0-120, default 4; 0 = poster only).
    frame_interval: One frame every N seconds instead of frames_per_video (same 120 cap).
    frame_times: {asset_id: [seconds, ...]} exact moments for specific videos, chosen
        after looking at their frames ("the representative frame"). Wins over
        frames_per_video/frame_interval for the listed videos; others keep the spread.
    frame_captions: {asset_id: [text, ...]} one caption per extracted frame, in frame
        order (photobook prints each on its frame's page; other layouts ignore them).
    image_size: 'original' (default): photos go in at the stored file's quality,
        re-encoded to at most 3000px (a format the server cannot decode, like
        some HEIC, falls back to preview with a note); 'preview' (1440px) or
        'thumbnail' for smaller files.
    frame_size: video frame size in the PDF: 'auto' (default, same as 'preview':
        quality is free inside the PDF) or 'thumbnail' for a smaller file.
    language: 'en' (default) or 'es' for the fixed labels on the pages (Index,
        Places, Camera, page numbers); captions stay in whatever language you wrote.
    map: Draw an OpenStreetMap map on the Places page when assets carry GPS
        (default True; tiles come from tile.openstreetmap.org, the only
        third-party call this server makes — pass map=False to skip it).
    cover, index, places: Include each front-matter page (all default True;
        turn them off for a print-ready photobook of bare pages).
    footer: 'full' (plugin name, server and page number, default), 'pages'
        (just the page number) or 'none'.
    header: Repeat the title at the top of every page except the cover
        (default False).
    videos_position: Where the video pages (frame strips or frame pages) go:
        'mixed' with the photos in the general order (default), 'first' or 'last'.
    order: 'auto' (albums read oldest to newest, like the frames inside a video;
        asset_ids keep the order you passed), 'oldest', 'newest' or 'given'.
    confirm: Only asked for when explicit asset_ids mix videos more than 90 days
        apart (different stories). Pass True only when the user themselves asked
        to mix them; exporting a whole album never needs it.
    limit: Max assets (1-500, default 100).
    return_base64: Also return the PDF bytes (skipped above 2 MB; every MB is
        roughly 350k tokens in the conversation).

Returns: JSON {path, pages, bytes, assets_included, assets_skipped:[{id, reason}], warnings:[...]}.

Input Schema

NameRequiredDescriptionDefault
mapNo
coverNo
indexNo
limitNo
orderNoauto
titleNo
footerNofull
headerNo
layoutNodetail
placesNo
confirmNo
album_idNo
captionsNo
languageNoen
asset_idsNo
frame_sizeNoauto
image_sizeNooriginal
frame_timesNo
output_pathNo
return_base64No
frame_captionsNo
frame_intervalNo
videos_positionNomixed
frames_per_videoNo

Output Schema

NameRequiredDescriptionDefault
resultYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Addedv2.0.1

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only say readOnlyHint=false and destructiveHint=false; the description adds materially more — existing files are never overwritten, output is written to the host filesystem, HEIC decode failures fall back to preview with a note, the OSM tile fetch is disclosed as the only third-party call, and base64 returns are capped near 2 MB with a token-cost estimate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and usage rules, then a clean Args block with a Returns line. It is long, but for 24 parameters most sentences carry distinct semantics; a few parenthetical asides (e.g. the token-cost arithmetic) could be trimmed without loss.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 24-parameter, nested-object, filesystem-writing tool this covers what an agent needs: input constraints, ordering defaults, safety gates, network side effects, and even a summary of the return payload despite an output schema already existing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% and all 24 parameters are documented with defaults, valid ranges, and interaction rules the schema cannot express — frame_times overriding frames_per_video/frame_interval only for listed videos, frame_captions being ignored outside photobook, exactly-one-of album_id/asset_ids, and confirm applying only to asset_ids spread over 90 days.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a concrete verb and artifact ('Build a PDF... from an album or a list of assets') plus the internal structure (cover, index, places, one section per asset) and where it lands ('on the machine running this server'). It also distinguishes itself from the geographically close sibling get_export_preview.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit routing rule: if the user asked for a PDF without specifying how, call get_export_preview first and ask about the choices. It also supplies content-selection guidance ('one story per PDF', offer one PDF per story) and an explicit when-to-pass-confirm rule, including when it is not needed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Deploy Server

Other Tools