MCP server providing access to Malaysian government datasets from data.gov.my API, including population statistics, births, fuel prices, household income, and car registration data
This server exposes 6 data query tools with basic but incomplete schema definitions. All tools have descriptions and input parameters, but descriptions are generic (1-2 sentences), parameters lack type validation constraints (no enums, ranges, or patterns), and output schemas are entirely undocumented. Tool naming is noun-based rather than verb-based ('population_state' instead of 'get_population_state'), which deviates from the production baseline where 90% of A+ tools start with action verbs. Error handling is minimal, handlers return only HTTP status codes without guidance for LLMs on recovery. Parameter descriptions provide good domain context but omit formal constraints (e.g., 'state' lists 16 valid options in prose but not as an enum). The tools are read-only queries with no state modification, so composition and idempotency are moot, but the interface does not match the 'chat data model' baseline where agents operate with natural language, not field names alone.
Number of people born daily in Malaysia, based on registrations with JPN from 1920 to the present
Weekly retail prices of RON95 petrol, RON97 petrol, and diesel in Malaysia
Mean and median monthly gross household income in Malaysia from 1970 to 2022
Population at national level from 1970 to 2024, by sex, age group and ethnicity
Population at state level from 1970 to 2024, by sex, age group and ethnicity
Car registration transactions from 2000 to the present
Tool names are nouns, not verbs. Baseline production data shows 90% of A+ tools start with action verbs (get_, list_, search_). LLMs infer intent from the name before reading the description. 'population_state' leaves the LLM guessing whether it retrieves, searches, aggregates, or lists. Use 'get_population_state' or 'list_population_by_state' instead.
No output schemas documented. Tools return raw JSON from the data.gov.my API (visible in birthHandler, fuelpriceHandler, etc.) without documenting what fields, types, and structure the response contains. LLMs cannot plan downstream calls or extract data without knowing the schema. Add explicit output schema documentation (e.g., 'Returns {date: string, count: number, ...}') to every tool.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 38 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 45 | - | v1 |
Parameters lack enum constraints. 'state' (population_state) description says 'One of 16 states' in prose but provides no enum list. 'sex' lists valid values ('male', 'female', 'both') in the description as prose examples, not as formal enum constraints. Free-form strings invite hallucinated values. Declare all constrained parameters as enums with explicit allowed values.
Error handling lacks recovery guidance. Handlers check HTTP status (e.g., 'if resp.StatusCode != http.StatusOK') and return a generic error like 'unexpected status code: 400' with no guidance. LLMs cannot infer whether the error is retryable, user-fixable, or fatal. Enrich errors: 'Invalid state parameter. Must be one of: Johor, Kedah, ... Try calling with a valid state name.'
Parameter relationships undocumented. 'registration_transactions_car' accepts both 'date_reg' (single date) and 'date_start'/'date_end' (range). No description states these are mutually exclusive or how to use them. Undocumented dependencies cause silent misuse. Add explicit documentation: 'Either provide date_reg for a single date, OR both date_start and date_end for a range, but not both.'
Numeric parameters lack ranges. 'births' parameter 'births' is mcp.WithNumber() with no min/max. 'registration_transactions_car' accepts 'maker' and 'model' as free-form strings with no length limits. Unbounded inputs let LLMs pass absurd values. Specify min/max for numeric fields and validation rules for strings (e.g., 'case-insensitive uppercase, 1-50 chars').