Local stdio MCP server that renders letters as PDF, DIN 5008 compliant for German mail, multilingual, with signature images.
Strong tool naming (all verb-first: create_, preview_, prepare_, list_, get_). Descriptions are detailed and contextual (avg 180 chars), exceeding the 10-1024 baseline. Input schemas are comprehensive with proper JSON Schema types and enums. However, nested object parameters (sender, recipient, signature, etc.) lack internal field documentation, forcing LLMs to infer structure. Output schemas are documented in descriptions but not formally declared in the tool registration. Error handling is present but generic (toError wraps exceptions without recovery guidance). No tool annotations (readOnlyHint/destructiveHint) despite clear risk levels (WRITE vs READ_ONLY).
Renders a letter as a PDF file in the fixed house layout (DIN 5008 address field, 25 mm writing margin, fold and punch marks, bold subject block). Pass content only, the layout is fixed. The signature image intentionally overlaps the closing line. Returns the absolute file path, the page count, layout metrics and warnings.
Returns the millimetre geometry of the layout: address field, remark zone, writing margins, subject position, fold and punch marks.
Lists the built-in font families and resolves a font name against the installed system fonts, so you can check what create_letter would embed.
Lists the supported languages together with their fixed texts (salutation, closing, enclosures, page numbering).
Lists the sender profiles configured on this machine. Each profile carries the address and the signature of one person, so create_letter only needs the profile key.
Cleans up a scanned signature: crops white borders, turns the paper background transparent and optionally recolours the ink. Writes a PNG that can be passed to create_letter as signature.path. Needs the optional sharp dependency.
Nested object parameters lack internal field documentation. 'sender', 'recipient', 'signature', 'font', 'geometry', 'infoBlock', 'letterhead', 'footer', 'labels', 'metadata' are typed as objects but their required/optional fields and constraints are not documented in the schema or descriptions.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear semantic differences. create_letter and prepare_signature are destructive (WRITE); others are read-only. Annotations enable agents to reason about side effects and retry safety.
Output schemas not formally declared in tool registration. Descriptions mention return fields (path, pageCount, warnings, layout, base64) but inputSchema lacks corresponding outputSchema declaration. LLMs cannot validate response structure.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 59 | 2026-07-28+ | v2 |
Renders the letter in memory and returns layout metrics and warnings without writing a file. Use it to check whether the address fits the address field or the letter runs onto a second page.
Error handling is generic. toError() wraps exceptions without categorization (retryable vs fatal) or recovery guidance. E.g., 'File not found' should suggest 'Check outputPath or use default directory'; 'Sharp not installed' should suggest 'Install optional dependency: npm install sharp'.
Parameter constraints not fully specified. 'locale' accepts 12 language codes but no enum is declared in the schema (only in description). 'form' has enum ['A', 'B', 'private'] but preview_letter omits the enum constraint. Inconsistency invites hallucinated values.