Skip to main content
Glama

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

TableJSON Schema
NameRequiredDescriptionDefault
is_favoriteNo
is_archivedNo
is_trashedNo
asset_typeNo
pageNo
sizeNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

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)
  • Registration of 'list_assets' as an MCP tool via the @mcp.tool() decorator on the FastMCP instance.
    @mcp.tool()
    async def list_assets(
Behavior5/5

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

No annotations exist, so the description carries full burden. It declares 'Read-only', explains each filter's behavior (true/false/omit), pagination defaults, and return format (total count, page, assets array with fields). This fully discloses behavioral traits.

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

Conciseness5/5

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

The description is concise with a clear 'Args' section and 'Returns' section. Every sentence provides necessary information without redundancy. It is front-loaded with the core purpose.

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?

Given the tool's simplicity (6 optional params, pagination, no nested objects), the description fully covers input details, usage context, and return structure. Even though output schema exists, the description adds valuable return field names.

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%, but the description thoroughly explains all 6 parameters: is_favorite (true/false/omit), is_archived, is_trashed, asset_type (IMAGE/VIDEO), page (starting 1), size (1-200, default 50). This adds extensive meaning beyond the schema's bare type definitions.

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?

The description clearly states 'List assets with simple filters (no search query needed).' It specifies the verb (list) and resource (assets) with scope (filters by status/type). It distinguishes from siblings like search_metadata and search_smart by contrasting browsing versus specific search.

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?

The description explicitly says '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).' This provides clear when-to-use and when-not-to-use, naming specific alternatives.

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

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/drolosoft/immich-photo-manager'

If you have feedback or need assistance with the MCP directory API, please join our Discord server