Local MCP tools for parsing, validating, and normalizing Pinterest URLs
SavePinner MCP demonstrates solid fundamentals: all 3 tools have clear verb-noun naming (parse_, normalize_, is_), complete input schemas with type and description, and comprehensive output schemas. Tool annotations (readOnlyHint, destructiveHint, idempotentHint) are present and correct. However, tool descriptions are terse (34 - 52 chars), falling below the 50 - 200 char baseline for LLM-optimized descriptions. Descriptions lack context on WHEN to use each tool or dependencies between them. Error handling is basic (generic toolError wrapper) with no recovery guidance. The server is narrow in scope (Pinterest URL utilities only) but well-executed within that domain.
Return whether a value is a supported Pinterest URL without making a network request.
Convert a supported Pinterest URL to its canonical form and remove tracking parameters.
Parse a Pinterest URL and return its kind, canonical URL, host, and type-specific identifiers.
Tool descriptions are too brief (34 - 52 chars vs. 50 - 200 char baseline). Lack context on WHEN to use each tool, dependencies, or expected input formats. LLMs cannot distinguish parse_pinterest_url from normalize_pinterest_url without richer descriptions.
Error handling is generic. toolError() returns only the error message with no recovery guidance. LLMs cannot determine if an error is retryable, user-fixable, or fatal. No actionable next steps provided.
Input parameter 'url' lacks format constraints in description. No mention of supported URL patterns (pinterest.com, pin.it, etc.), expected structure, or examples of valid/invalid inputs. Description only says 'A complete Pinterest or pin.it URL'.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 59 | 2025-06-18+ | v2 |
Output schema for parse_pinterest_url includes many optional fields (pinId, shortcode, username, boardSlug, ideaSlug, ideaId) but no documentation of which fields are populated for which URL kinds. LLMs cannot reliably extract the right field for downstream use.
No tool composition guidance. No description of how these three tools relate or when to call them in sequence. E.g., should an LLM call is_pinterest_url before parse_pinterest_url, or is parse_pinterest_url safe to call on any string?