Skip to main content
Glama

zotero_advanced_search

Search your Zotero research library with advanced criteria, combining multiple conditions to filter, sort, and retrieve precise results efficiently.

Instructions

Perform an advanced search with multiple criteria.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
conditionsYes
join_modeNoall
limitNo
sort_byNo
sort_directionNoasc

Implementation Reference

  • The main handler function for the 'zotero_advanced_search' tool. It creates a temporary saved search in Zotero using the provided conditions, executes it, formats the results in markdown, and cleans up the saved search afterward.
        name="zotero_advanced_search",
        description="Perform an advanced search with multiple criteria."
    )
    def advanced_search(
        conditions: List[Dict[str, str]],
        join_mode: Literal["all", "any"] = "all",
        sort_by: Optional[str] = None,
        sort_direction: Literal["asc", "desc"] = "asc",
        limit: Union[int, str] = 50,
        *,
        ctx: Context
    ) -> str:
        """
        Perform an advanced search with multiple criteria.
        
        Args:
            conditions: List of search condition dictionaries, each containing:
                       - field: The field to search (title, creator, date, tag, etc.)
                       - operation: The operation to perform (is, isNot, contains, etc.)
                       - value: The value to search for
            join_mode: Whether all conditions must match ("all") or any condition can match ("any")
            sort_by: Field to sort by (dateAdded, dateModified, title, creator, etc.)
            sort_direction: Direction to sort (asc or desc)
            limit: Maximum number of results to return
            ctx: MCP context
        
        Returns:
            Markdown-formatted search results
        """
        try:
            if not conditions:
                return "Error: No search conditions provided"
            
            ctx.info(f"Performing advanced search with {len(conditions)} conditions")
            zot = get_zotero_client()
            
            # Prepare search parameters
            params = {}
            
            # Add sorting parameters if specified
            if sort_by:
                params["sort"] = sort_by
                params["direction"] = sort_direction
            
            if isinstance(limit, str):
                limit = int(limit)
            
            # Add limit parameter
            params["limit"] = limit
            
            # Build search conditions
            search_conditions = []
            for i, condition in enumerate(conditions):
                if "field" not in condition or "operation" not in condition or "value" not in condition:
                    return f"Error: Condition {i+1} is missing required fields (field, operation, value)"
                
                # Map common field names to Zotero API fields if needed
                field = condition["field"]
                operation = condition["operation"]
                value = condition["value"]
                
                # Handle special fields
                if field == "author" or field == "creator":
                    field = "creator"
                elif field == "year":
                    field = "date"
                    # Convert year to partial date format for matching
                    value = str(value)
                
                search_conditions.append({
                    "condition": field,
                    "operator": operation,
                    "value": value
                })
            
            # Add join mode condition
            search_conditions.append({
                "condition": "joinMode",
                "operator": join_mode,
                "value": ""
            })
            
            # Create a saved search
            search_name = f"temp_search_{uuid.uuid4().hex[:8]}"
            saved_search = zot.saved_search(
                search_name,
                search_conditions
            )
            
            # Extract the search key from the result
            if not saved_search.get("success"):
                return f"Error creating saved search: {saved_search.get('failed', 'Unknown error')}"
            
            search_key = next(iter(saved_search.get("success", {}).values()), None)
            
            # Execute the saved search
            try:
                results = zot.collection_items(search_key)
            finally:
                # Clean up the temporary saved search
                try:
                    zot.delete_saved_search([search_key])
                except Exception as cleanup_error:
                    ctx.warn(f"Error cleaning up saved search: {str(cleanup_error)}")
            
            # Format the results
            if not results:
                return "No items found matching the search criteria."
            
            output = ["# Advanced Search Results", ""]
            output.append(f"Found {len(results)} items matching the search criteria:")
            output.append("")
            
            # Add search criteria summary
            output.append("## Search Criteria")
            output.append(f"Join mode: {join_mode.upper()}")
            
            for i, condition in enumerate(conditions, 1):
                output.append(f"{i}. {condition['field']} {condition['operation']} \"{condition['value']}\"")
            
            output.append("")
            
            # Format results
            output.append("## Results")
            
            for i, item in enumerate(results, 1):
                data = item.get("data", {})
                title = data.get("title", "Untitled")
                item_type = data.get("itemType", "unknown")
                date = data.get("date", "No date")
                key = item.get("key", "")
                
                # Format creators
                creators = data.get("creators", [])
                creators_str = format_creators(creators)
                
                # Build the formatted entry
                output.append(f"### {i}. {title}")
                output.append(f"**Type:** {item_type}")
                output.append(f"**Item Key:** {key}")
                output.append(f"**Date:** {date}")
                output.append(f"**Authors:** {creators_str}")
                
                # Add abstract snippet if present
                if abstract := data.get("abstractNote"):
                    # Limit abstract length for search results
                    abstract_snippet = abstract[:150] + "..." if len(abstract) > 150 else abstract
                    output.append(f"**Abstract:** {abstract_snippet}")
                
                # Add tags if present
                if tags := data.get("tags"):
                    tag_list = [f"`{tag['tag']}`" for tag in tags]
                    if tag_list:
                        output.append(f"**Tags:** {' '.join(tag_list)}")
                
                output.append("")  # Empty line between items
            
            return "\n".join(output)
        
        except Exception as e:
            ctx.error(f"Error in advanced search: {str(e)}")
            return f"Error in advanced search: {str(e)}"
  • The @mcp.tool decorator registers the advanced_search function as the 'zotero_advanced_search' tool.
        name="zotero_advanced_search",
        description="Perform an advanced search with multiple criteria."
    )

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/54yyyu/zotero-mcp'

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