The first Model Context Protocol server for Japanese sake — a flavor-space engine over the Sakenowa open dataset.
Five tools with clear verb-noun naming (sync_, search_, get_, find_, compare_) and detailed descriptions (150 - 250 chars each). All tools have input schemas with typed parameters and descriptions. However, output schemas are undocumented, responses are markdown strings with no structured field definitions. Error handling is minimal (e.g., 'No sake with id X' is a string, not a typed error). Parameters lack enums where appropriate (e.g., find_similar_sake's 'mode' accepts 8 values but is free-form string). No tool annotations (readOnlyHint, idempotentHint). Descriptions are good but could be more concise for LLM parsing. Overall solid foundation with gaps in output structure and validation.
Compare 2–5 sake side by side across all six flavor axes, with the spread (max−min) per axis to highlight where they differ most.
★ Core feature ★ Given one sake, find others by flavor-vector proximity. `mode` steers the direction in flavor space: - similar : nearest overall (a true taste-alike) - drier : like this, but drier - sweeter : like this, but less dry / rounder - lighter : like this, but lighter & crisper - richer : like this, but fuller & heavier - more_aromatic : like this, but more floral/fragrant - calmer : like this, but quieter on the nose - contrast : the opposite palate (for deliberate exploration) Only sake that have a flavor chart can be matched.
Return the six-axis flavor profile of one sake: an ASCII radar, the dominant flavor tags, an *estimated* four-type class (薫/爽/醇/熟, heuristic), and its overall/area popularity rank. Also lists the bottle-spec fields the Sakenowa dataset does NOT provide (polishing ratio, SMV, ABV, price, …) so they are never invented.
Find sake by brand name or brewery name and return their IDs. Names are Japanese; kanji queries (e.g. 八海山, 獺祭) match directly, and so do Chinese kanji that share the glyphs. Use `area` to filter by prefecture name (e.g. '新潟'). Use the returned `id` with get_sake_profile / find_similar_sake / compare_sake.
Output schemas undocumented. All tools return markdown strings with no structured field definitions. LLMs cannot parse response structure or chain results reliably.
find_similar_sake 'mode' parameter accepts 8 values (similar, drier, sweeter, lighter, richer, more_aromatic, calmer, contrast) but is defined as free-form string, not enum. Invites hallucinated values.
No tool annotations (readOnlyHint, idempotentHint, destructiveHint). All tools are read-only but this is not declared in schema, forcing LLMs to infer safety from descriptions.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 58 | 2026-07-28+ | v2 |
Fetch/refresh the Sakenowa open dataset into a local cache and report its scale. The cache auto-refreshes weekly, so you rarely need this — call it with force=True only to pull the latest monthly snapshot immediately. Returns dataset counts, the data's year-month, and the required attribution.
Error responses are unstructured markdown strings. No error classification (retryable vs user-fixable vs fatal) or recovery guidance. E.g., 'No sake with id X' gives no hint to call search_sake first.
compare_sake accepts 2 - 5 brand_ids but no validation shown in code. If LLM passes 1 or 6 items, error handling is unclear.