zotero_search_items
Search your Zotero library for specific items using query strings, filtering by item type or search mode, and customize results with optional limits for precise research access.
Instructions
Search for items in your Zotero library, given a query string.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| item_type | No | -attachment | |
| limit | No | ||
| qmode | No | titleCreatorYear | |
| query | Yes |
Implementation Reference
- src/zotero_mcp/server.py:73-162 (handler)The main handler function for the 'zotero_search_items' tool. It is decorated with @mcp.tool(name="zotero_search_items"), making this both the implementation and registration point. The function searches the Zotero library using the pyzotero client, formats results as markdown, and handles errors.@mcp.tool( name="zotero_search_items", description="Search for items in your Zotero library, given a query string." ) def search_items( query: str, qmode: Literal["titleCreatorYear", "everything"] = "titleCreatorYear", item_type: str = "-attachment", # Exclude attachments by default limit: Optional[Union[int, str]] = 10, tag: Optional[List[str]] = None, *, ctx: Context ) -> str: """ Search for items in your Zotero library. Args: query: Search query string qmode: Query mode (titleCreatorYear or everything) item_type: Type of items to search for. Use "-attachment" to exclude attachments. limit: Maximum number of results to return tag: List of tags conditions to filter by ctx: MCP context Returns: Markdown-formatted search results """ try: if not query.strip(): return "Error: Search query cannot be empty" tag_condition_str = "" if tag: tag_condition_str = f" with tags: '{', '.join(tag)}'" else : tag = [] ctx.info(f"Searching Zotero for '{query}'{tag_condition_str}") zot = get_zotero_client() if isinstance(limit, str): limit = int(limit) # Search using the query parameters zot.add_parameters(q=query, qmode=qmode, itemType=item_type, limit=limit, tag=tag) results = zot.items() if not results: return f"No items found matching query: '{query}'{tag_condition_str}" # Format results as markdown output = [f"# Search Results for '{query}'", f"{tag_condition_str}", ""] 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[:200] + "..." if len(abstract) > 200 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 searching Zotero: {str(e)}") return f"Error searching Zotero: {str(e)}"