get_poem
Retrieve poems by ID or title from a poetry catalog, with options to include full text content for literary analysis and reference.
Instructions
Get a poem by ID or title.
Args: identifier: Poem ID or exact title include_content: Whether to include full poem text
Returns: Poem object or None if not found
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| identifier | Yes | ||
| include_content | No |
Implementation Reference
- src/poetry_mcp/server.py:83-113 (handler)The handler function for the 'get_poem' MCP tool, decorated with @mcp.tool() for automatic registration and schema inference from signature/docstring. Retrieves poem by ID or title from catalog index.@mcp.tool() async def get_poem( identifier: str, include_content: bool = True ) -> Optional[Poem]: """ Get a poem by ID or title. Args: identifier: Poem ID or exact title include_content: Whether to include full poem text Returns: Poem object or None if not found """ cat = get_catalog() # Try by ID first poem = cat.index.get_by_id(identifier.lower()) # Try by title if not found if not poem: poem = cat.index.get_by_title(identifier) if poem and not include_content: # Return copy without content poem_dict = poem.model_dump() poem_dict['content'] = None poem = Poem(**poem_dict) return poem
- src/poetry_mcp/models/poem.py:11-136 (schema)Pydantic BaseModel defining the structure and validation for the Poem object returned by the get_poem tool.class Poem(BaseModel): """ Poem model representing a single poem with metadata from frontmatter. Required frontmatter properties: - state: Production state (completed, fledgeling, etc.) - form: Structural pattern (free_verse, prose_poem, etc.) Optional frontmatter properties: - tags: Thematic tags for nexus connections - keywords: Legacy comma-separated tags Computed properties: - id: Generated from filename - word_count, line_count, stanza_count: Computed from content - created_at, updated_at: From filesystem timestamps """ # Core identity id: str = Field(..., description="Unique identifier (filename without .md)") title: str = Field(..., description="Poem title from first # heading or filename") file_path: str = Field(..., description="Relative path from vault root") # Frontmatter: Required properties state: Literal[ "completed", "fledgeling", "still_cooking", "needs_research", "risk" ] = Field(..., description="Production state of the poem") form: Literal[ "free_verse", "prose_poem", "american_sentence", "catalog_poem" ] = Field(..., description="Structural/formal pattern") # Frontmatter: Optional properties tags: list[str] = Field( default_factory=list, description="Thematic tags for nexus connections" ) keywords: Optional[str] = Field( default=None, description="Legacy comma-separated keywords (prefer tags)" ) notes: Optional[str] = Field( default=None, description="Editorial notes about the poem" ) # Computed metrics word_count: int = Field(..., description="Total word count") line_count: int = Field(..., description="Total line count") stanza_count: Optional[int] = Field( default=None, description="Number of stanzas (blank-line separated)" ) # Filesystem metadata created_at: datetime = Field(..., description="File creation timestamp") updated_at: datetime = Field(..., description="File modification timestamp") # Content (optional, for search/display) content: Optional[str] = Field( default=None, description="Full poem text (only included if requested)" ) @field_validator('state') @classmethod def validate_state(cls, v: str) -> str: """Validate state enum value.""" valid_states = { "completed", "fledgeling", "still_cooking", "needs_research", "risk" } if v not in valid_states: raise ValueError( f"Invalid state '{v}'. Must be one of: {', '.join(valid_states)}" ) return v @field_validator('form') @classmethod def validate_form(cls, v: str) -> str: """Validate form enum value.""" valid_forms = { "free_verse", "prose_poem", "american_sentence", "catalog_poem" } if v not in valid_forms: raise ValueError( f"Invalid form '{v}'. Must be one of: {', '.join(valid_forms)}" ) return v @field_validator('tags') @classmethod def normalize_tags(cls, v: list[str]) -> list[str]: """Normalize tags: lowercase, strip whitespace, remove duplicates.""" if not v: return [] normalized = [tag.lower().strip() for tag in v if tag.strip()] return list(dict.fromkeys(normalized)) # Preserve order, remove dupes class Config: """Pydantic configuration.""" json_schema_extra = { "example": { "id": "second-bridge-out-old-route-12", "title": "Second Bridge Out Old Route 12", "file_path": "catalog/Completed/second-bridge-out-old-route-12.md", "state": "completed", "form": "free_verse", "tags": ["water", "body", "memory", "Vermont"], "word_count": 358, "line_count": 42, "stanza_count": 7, "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-06-20T14:22:00Z" } }