find_poems_by_tag
Search for poems using specific tags with flexible matching options to filter poetry collections by themes, subjects, or characteristics.
Instructions
Find poems by tags.
Args: tags: List of tags to match match_mode: "all" (poems must have all tags) or "any" (at least one tag) states: Optional filter by states limit: Maximum number of results
Returns: List of matching poems
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| tags | Yes | ||
| match_mode | No | all | |
| states | No | ||
| limit | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- src/poetry_mcp/server.py:192-229 (handler)The primary handler function for the find_poems_by_tag tool. It is registered via the @mcp.tool() decorator. Retrieves matching poems from the catalog index, applies state filtering if provided, limits the results, strips poem content for efficiency, and returns the list of Poem objects.
@mcp.tool() async def find_poems_by_tag( tags: List[str], match_mode: str = "all", states: Optional[List[str]] = None, limit: int = 20 ) -> List[Poem]: """ Find poems by tags. Args: tags: List of tags to match match_mode: "all" (poems must have all tags) or "any" (at least one tag) states: Optional filter by states limit: Maximum number of results Returns: List of matching poems """ cat = get_catalog() # Get poems matching tags poems = cat.index.get_by_tags(tags, match_mode=match_mode) # Apply state filter if states: poems = [p for p in poems if p.state in states] # Limit results poems = poems[:limit] # Remove content for efficiency poems = [ Poem(**{**p.model_dump(), 'content': None}) for p in poems ] return poems - Core helper method in CatalogIndex that implements the tag matching logic using set intersection (for 'all') or union (for 'any') on the pre-built tag index to find matching poem IDs efficiently.
def get_by_tags( self, tags: list[str], match_mode: str = "all" ) -> list[Poem]: """ Get poems matching tag criteria. Args: tags: List of tags to match match_mode: "all" (AND) or "any" (OR) Returns: List of matching poems """ if not tags: return [] tag_sets = [self.by_tag.get(tag.lower(), set()) for tag in tags] if match_mode == "all": # Intersection: poems must have all tags matching_ids = set.intersection(*tag_sets) if tag_sets else set() else: # "any" # Union: poems must have at least one tag matching_ids = set.union(*tag_sets) if tag_sets else set() return [self.by_id[pid] for pid in matching_ids if pid in self.by_id]