list_assets
Browse the library by status (favorites, archived, trashed) or media type without search queries. Returns paginated asset details.
Instructions
List assets with simple filters (no search query needed). Use this to browse the library by status (favorites, archived, trashed) or type. For finding specific content, use search_metadata (structured) or search_smart (visual AI). Read-only.
Args:
is_favorite: true = only favorites, false = only non-favorites, omit = all.
is_archived: true = only archived, false = only non-archived, omit = all.
is_trashed: true = only trashed items, false = only active, omit = all.
asset_type: 'IMAGE' or 'VIDEO'. Omit for both.
page: Page number, starting from 1 (default 1).
size: Results per page (1-200, default 50).
Returns: JSON with total count, current page, and assets array with IDs, filenames, dates, and types.Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| is_favorite | No | ||
| is_archived | No | ||
| is_trashed | No | ||
| asset_type | No | ||
| page | No | ||
| size | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- MCP tool handler for 'list_assets' — decorates with @mcp.tool(), accepts filters (is_favorite, is_archived, is_trashed, asset_type, page, size), delegates to ImmichClient.list_assets(), and formats the response as JSON.
@mcp.tool() async def list_assets( ctx: Context, is_favorite: bool | None = None, is_archived: bool | None = None, is_trashed: bool | None = None, asset_type: str = "", page: int = 1, size: int = 50, ) -> str: """List assets with simple filters (no search query needed). Use this to browse the library by status (favorites, archived, trashed) or type. For finding specific content, use search_metadata (structured) or search_smart (visual AI). Read-only. Args: is_favorite: true = only favorites, false = only non-favorites, omit = all. is_archived: true = only archived, false = only non-archived, omit = all. is_trashed: true = only trashed items, false = only active, omit = all. asset_type: 'IMAGE' or 'VIDEO'. Omit for both. page: Page number, starting from 1 (default 1). size: Results per page (1-200, default 50). Returns: JSON with total count, current page, and assets array with IDs, filenames, dates, and types. """ try: result = await _client(ctx).list_assets( is_favorite=is_favorite, is_archived=is_archived, is_trashed=is_trashed, asset_type=asset_type or None, page=page, size=min(size, 200), ) assets = result.get("assets", {}).get("items", []) total = result.get("assets", {}).get("total", 0) return json.dumps({"total": total, "page": page, "assets": assets}, default=str) except httpx.HTTPStatusError as e: return json.dumps({"error": f"Immich API error: {e.response.status_code}", "detail": e.response.text[:200]}) - ImmichClient.list_assets — helper method that builds the request body from optional filters and POSTs to /search/metadata. Adds a default isArchived=false filter if none was provided (Immich API requires at least one filter).
async def list_assets( self, is_favorite: bool | None = None, is_archived: bool | None = None, is_trashed: bool | None = None, asset_type: str | None = None, page: int = 1, size: int = 100, ) -> dict: """List assets with optional filters (uses search/metadata endpoint).""" body: dict[str, Any] = {"page": page, "size": size} if is_favorite is not None: body["isFavorite"] = is_favorite if is_archived is not None: body["isArchived"] = is_archived if is_trashed is not None: body["isTrashed"] = is_trashed if asset_type: body["type"] = asset_type # Ensure at least one filter (Immich /search/metadata requires it) if len(body) == 2: # only page and size body["isArchived"] = False return await self._request("POST", "/search/metadata", json=body) - src/immich_mcp_server/server.py:1304-1306 (registration)Registration of 'list_assets' as an MCP tool via the @mcp.tool() decorator on the FastMCP instance.
@mcp.tool() async def list_assets(