Skip to main content
Glama

Poetry MCP Server

poem.py4.46 kB
"""Pydantic model for Poem entity. Data comes from markdown file frontmatter, not BASE files. """ from datetime import datetime from typing import Literal, Optional from pydantic import BaseModel, Field, field_validator 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" } }

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