Skip to main content
Glama
james-livefront

Poetry MCP Server

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
NameRequiredDescriptionDefault
identifierYes
include_contentNo

Implementation Reference

  • 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
  • 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"
                }
            }

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/james-livefront/poetry-mcp'

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