MCP server that provides historical events for a given date (today, yesterday, or tomorrow) in Vietnamese, sourced from lichngaytot.com
Single tool 'ngay_nay_nam_xua' with significant quality gaps. Tool name does not follow verb_noun convention (should be get_history_event or fetch_history_events). Description is present but lacks LLM-critical context (no WHEN to use, no expected output format). Input schema exists but parameter description is minimal (18 chars: 'Date option: TODAY, YESTERDAY, or TOMORROW'). Output schema is partially documented in server.py as a dict with 'success', 'option', 'events' fields, but this is NOT visible in the tool registration in history_tool.py. Tool performs external HTTP fetch with timeout and error handling, but error messages are generic ('Lỗi khi lấy dữ liệu: {e}') and do not guide recovery. No input validation beyond uppercase/strip normalization. No pagination despite potentially large response content. No rate limiting. No security annotation (tool is READ_ONLY per risk assessment, but not explicitly marked in schema). Tool description uses emoji and Vietnamese language exclusively, which may confuse LLM tokenization and reasoning.
📜 Trả về sự kiện 'Ngày này năm xưa' bằng tiếng Việt (nguồn: lichngaytot.com) - opt: "TODAY" | "YESTERDAY" | "TOMORROW"
Tool name does not follow verb_noun convention. 'ngay_nay_nam_xua' is a Vietnamese phrase with no action verb. Should be 'get_history_event', 'fetch_historical_events', or similar. LLMs cannot infer intent from the name alone.
Parameter description is too short (18 characters). Current: 'Date option: TODAY, YESTERDAY, or TOMORROW'. Missing: expected input format, which values are recommended, when to use each, what happens if invalid input provided.
Tool description lacks WHEN/WHY context. Current description: '📜 Trả về sự kiện Ngày này năm xưa bằng tiếng Việt (nguồn: lichngaytot.com) - opt: TODAY | YESTERDAY | TOMORROW'. Missing: When should LLM call this vs other tools? What does it return? Is it appropriate for all user queries? Output structure is not documented in tool registration (only visible in server.py as dict with 'success', 'option', 'events' keys, but not in @mcp.tool() docstring).
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 35 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 23 | - | v1 |
Output schema not documented in tool registration. server.py shows return type is dict with fields 'success', 'option', 'events', but this schema is invisible to LLMs consuming the tool definition. No structured output annotation. LLMs cannot plan downstream tool calls without knowing return structure.
Error handling is generic and non-actionable. Function returns 'Lỗi khi lấy dữ liệu: {e}' (Error fetching data: {e}) with raw exception message. This tells LLM nothing about what went wrong or what to do next. Should return: error classification (retryable vs fatal), the constraint violated, and recovery guidance per pattern:recovery-guide.
No input validation. Parameter 'opt' is free-form string with default 'TODAY'. Function normalizes input (uppercase, strip) but no explicit enum constraint in JSON Schema. LLM could pass 'next_week', 'last_month', or other invalid values; function silently defaults to TODAY without informing LLM of the invalid input.
Description uses emoji and Vietnamese language exclusively ('📜 Trả về sự kiện Ngày này năm xưa'). While culturally appropriate, this may confuse LLM tokenization and reasoning in English-language contexts. Description should be in the LLM's primary language (usually English for agent toolkits) or bilingual.
Response may contain unstructured HTML-scraped text. Function calls clean_content() which removes HTML tags and duplicates, but output is a single concatenated string ('events' field). No pagination despite potentially large result sets (historical events for a date could be hundreds of entries). No limit on response size.
No timeout specification or retry guidance in tool description. Function includes requests.post(..., timeout=10), but LLM is not informed of timeout behavior or how to retry. If external API is slow, tool fails silently with generic error.
Risk classification (READ_ONLY) is declared in the evaluation metadata but not reflected in tool schema. Missing readOnlyHint tool annotation. Per spec, tools should declare destructiveHint, idempotentHint, or readOnlyHint to help agents reason about side effects.