MCP server for Pingen v2 — send physical letters (A-Post/B-Post/registered) from a PDF and track them via the Pingen REST API
Strong naming conventions (verb_noun pattern across all 8 tools). Descriptions are present and substantive (100-200 chars typical), clearly stating what each tool does and safety implications. Input schemas are complete with proper JSON Schema types and enums. However, output schemas are not documented, LLMs cannot predict response structure. Error handling is implicit (confirm:true gates) but lacks explicit recovery guidance. Tool composition is sound: read-only tools (get, list, download, events) are ungated; destructive tools (send, submit, delete) require confirm:true; cancel is safe and ungated. No tool annotations (readOnlyHint, destructiveHint) present in code.
Cancel a submitted letter before it is printed. This is the safe direction and does not require confirmation.
Delete a draft letter permanently. This cannot be undone. Requires confirm:true to proceed.
Download the PDF file of a letter
Retrieve details about a specific letter by ID
Retrieve the event history/tracking information for a letter
List letters in the account, optionally filtered by status
Output schemas not documented. LLMs cannot predict response structure for any tool, forcing them to guess what fields are returned and breaking downstream tool chaining.
Tool annotations missing. No readOnlyHint on read tools (get_letter, list_letters, download_letter, get_letter_events) and no destructiveHint on write tools (send_letter, submit_letter, delete_letter). Clients cannot infer tool safety without explicit annotations.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 64 | 2026-07-28+ | v2 |
Send a physical letter via Pingen. Creates a draft letter (auto_send=false by default) from a PDF file. Pass auto_send:true to send immediately, or call pingen_submit_letter afterward. Requires confirm:true to actually send.
Submit a draft letter for printing and posting. This spends money and reaches the physical world. Requires confirm:true to proceed.
pingen_list_letters lacks pagination documentation. No mention of how many results are returned by default, whether results are capped, or how to fetch additional pages. Large result sets could exhaust context.
Error recovery guidance is implicit (confirm:true gates destructive ops) but not explicit. Descriptions do not state what happens on failure or how to recover. E.g., 'If submission fails, call pingen_cancel_letter to undo the draft.'
Read-only tools (get_letter, list_letters, download_letter, get_letter_events) have minimal descriptions (65-70 chars). Descriptions should explain when to call each and what distinguishes them. E.g., 'get_letter returns metadata; download_letter returns the PDF file.'