Skip to main content
Glama

KIRA — Knowledge-Indexed Registry for Analytics

A statistics-literate MCP server for Malaysian official data.

kira (Malay): to count, to reckon. kira-kira: calculation.

Malaysian official statistics, with the caveats attached.

Existing Malaysian open-data MCP servers are couriers: they fetch a table and hand it over. KIRA resolves a question to the right series, applies the correct transformation in code, refuses invalid comparisons, and returns every number with its provenance. See PROJECT_PLAN.md for the full design and phase-by-phase progress log.

Unofficial. Not affiliated with DOSM, JDN, or the Ministry of Digital. Data sourced from data.gov.my / open.dosm.gov.my, attributed per dataset in every tool response's provenance block.

Why: three real cases, not a feature list

Full write-up with the actual tool calls in eval/baseline_comparison.md — run against the hosted mcp-datagovmy baseline, not asserted.

  1. The same query, with or without a warning. Asking for Malaysia's monthly unemployment rate across a range that spans DOSM's January 2025 census-baseline shift returns identical raw numbers from either server — DOSM documents the break in prose, in a separate metadata call. The baseline's data-fetching call carries none of that. KIRA's get_series attaches the warning to the exact same query, automatically, every time.

  2. A refusal instead of a plausible wrong comparison. compare_series refuses to plot PPI's seasonally-adjusted and unadjusted series against each other, naming both series and why. The baseline has no such gate — nothing stops that comparison from happening.

  3. DOSM's own published growth rate, not a re-derived one. get_series and compute use the agency's own growth_yoy/growth_mom rows for GDP, PPI, IPI, and trade where DOSM publishes them, rather than recomputing from levels — verified to match DOSM's figures exactly (see tests/test_engine.py), which matters most for chain-linked real GDP, where a naive level-ratio calc doesn't reproduce the official number.

  4. A real gap, found and fixed, not hidden. find_series used to return nothing for homicide/crime queries and imply the data didn't exist — it does (homicide_rate now), and DOSM publishes plenty more that KIRA still hasn't curated. find_series now says so on a miss and points at raw_query_url, which reaches any DOSM/data.gov.my Parquet directly, sandboxed the same way as raw_query, no registration required. This is the one area where the baseline's full-catalogue search genuinely beats a curated-only design — worth stating plainly rather than glossing over.

Related MCP server: Open Census MCP Server

Status

All 10 originally-planned tools are built, plus one added to close a real coverage gap: find_series, describe_series, get_series, compare_series (with its SA/NSA refusal rule), compute (cagr/real/per_capita/index_to/contribution_to_growth, plus yoy/mom/qoq), explain_break, latest_release, raw_query (sandboxed SQL escape hatch for dimensional breakdowns a registered series doesn't curate, e.g. GDP by sector), raw_query_url (the same escape hatch for a DOSM dataset with no registry entry at all — find_series only searches KIRA's curated series, a fraction of what DOSM publishes; an empty result now says so and points here instead of implying the data doesn't exist), list_geographies (state/district/parlimen/DUN hierarchy), and lookup_classification (MCOICOP, MSIC — hierarchy traversal, not just single-code lookup).

21 series registered, covering every category in the build order (prices, national accounts, labour, production, external trade, demography): cpi_headline, cpi_core, ppi_headline + ppi_headline_sa, ipi_headline + ipi_headline_sa, gdp_real + gdp_real_state, gdp_nominal, labour_unemployment_rate + labour_unemployment_rate_state, labour_force_participation_rate, trade_exports, trade_imports, trade_balance, trade_total, population_malaysia, household_income_median, vital_birth_rate, vital_death_rate, homicide_rate. See PROJECT_PLAN.md section 6 for the phase plan, eval/questions.yaml for the Phase 0 eval set (27 questions, 26 graded), and eval/baseline_comparison.md for the head-to-head above, in full.

HTTP transport, Docker packaging, CI (tests + nightly source-drift check), in-process caching, and per-client rate limiting are done. Remaining: more series toward ~40, a hosted endpoint, submitting to MCP registries (Smithery, Glama, the GitHub MCP registry), and a dedicated adversarial security review (self-review only so far) — see PROJECT_PLAN.md's progress log for exact status.

Package name: kira-dosm — confirmed. kira and kira-mcp are already taken on both PyPI and npm by unrelated projects.

Quickstart

uv sync
uv run pytest                 # -m "not network" to skip live-data tests
uv run python -m kira.server  # stdio MCP server (default — for Claude Desktop, `mcp dev`, etc.)

Point an MCP client's config at uv run --directory /path/to/KIRA python -m kira.server (stdio) to use it locally.

# Ad-hoc query against a registered series:
from kira.registry import load_registry
from kira.engine import get_connection, get_series

reg = load_registry()
con = get_connection()
get_series(reg["cpi_headline"], con, date_from="2025-06", date_to="2025-06", transform="yoy")

HTTP transport

KIRA_TRANSPORT=http KIRA_PORT=8000 uv run python -m kira.server

Serves streamable-HTTP MCP at http://127.0.0.1:8000/mcp. Set KIRA_HOST=0.0.0.0 to listen on all interfaces (e.g. inside a container).

The HTTP transport is rate limited per client IP — KIRA_RATE_LIMIT_PER_MINUTE (default 60, set 0 to disable) — since a public endpoint otherwise has no defense against one client hammering it straight through to DOSM's live storage. Results are also cached in-process for KIRA_CACHE_TTL_SECONDS (default 3600 = 1 hour; DOSM's data doesn't change faster than that) — set 0 to disable, which is what the test suite does. Neither applies to stdio: there's only ever one client, and each session is a fresh process.

Docker

docker build -t kira-dosm .
docker run -p 8000:8000 kira-dosm

Runs the HTTP transport by default (KIRA_TRANSPORT=http is baked into the image). The container needs outbound HTTPS to storage.dosm.gov.my — it queries DOSM's live Parquet files on every request, it doesn't bundle or cache data.

Layout

  • registry/*.yaml — one file per series, the actual product (see registry/SCHEMA.md)

  • src/kira/models.py — the registry schema (pydantic)

  • src/kira/registry.py — loads + validates registry/*.yaml

  • src/kira/engine.py — DuckDB query + transforms (yoy/mom/qoq) + provenance/warnings

  • src/kira/lookups.py — geography and classification lookup tables (list_geographies, lookup_classification)

  • src/kira/cache.py — in-process TTL cache in front of every DOSM query (KIRA_CACHE_TTL_SECONDS)

  • src/kira/ratelimit.py — per-client-IP rate limiting for the HTTP transport (KIRA_RATE_LIMIT_PER_MINUTE)

  • src/kira/server.py — FastMCP server: 11 tools (find_series, describe_series, get_series, compare_series, compute, explain_break, latest_release, raw_query, raw_query_url, list_geographies, lookup_classification)

  • eval/questions.yaml — Phase 0 eval set, each answer independently verified against live DOSM data

  • eval/baseline_comparison.md — head-to-head against the mcp-datagovmy baseline

  • scripts/check_sources.py — fetches every registry source_url and fails loudly on 404 or schema drift; runs nightly via .github/workflows/nightly-source-check.yml

  • .github/workflows/ci.yml — tests + registry validation + Docker build on every push/PR

Licence

MIT — see LICENSE. Data itself is DOSM's, under the terms of data.gov.my's open data licence (CC BY 4.0 for the datasets checked so far); this project adds no additional restriction on top of that. Don't use DOSM's name, logo, or crest in any derivative branding — KIRA is unofficial and says so in every response.

Available Tools

11 tools
compare_seriesCompare SeriesA

Align two or more series on a common date index. Refuses to compare a series against its own seasonally-adjusted/not-adjusted counterpart (see each series' sa_counterpart field) rather than silently returning a misleading comparison — call describe_series on each id first if you're unsure whether that applies.

ParametersJSON Schema
NameRequiredDescriptionDefault
date_toNo
date_fromNo
transformNo
series_idsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the burden of behavioral disclosure. It openly states that the tool refuses to compare a series against its own seasonally-adjusted counterpart and explains the rationale, which is valuable, non-obvious behavior. It does not mention error formats or side effects, but the key refusal behavior is clearly disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no fluff, front-loading the core action before a necessary caveat. The parenthetical and example guidance are directly useful and earn their place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the most important behavioral edge case and points to a sibling tool for verification, and an output schema is present. However, it leaves transform and date-parameter semantics unexplained, and with no annotations the overall picture is incomplete for an agent needing to construct a correct call.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate for the missing parameter documentation. It offers some meaning for series_ids by saying the tool aligns two or more series, but it gives no explanation of date_from, date_to, or transform. An agent would not know what values transform accepts or how the date range is interpreted from this description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool aligns two or more series on a common date index, which is a specific action and resource. It does not explicitly contrast itself with siblings like get_series or compute, but the alignment behavior is distinctive enough to separate it from those tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit guidance to call describe_series on each id first when unsure about seasonally-adjusted versus not-adjusted comparisons. It does not address when compare_series should be chosen over get_series or compute, but the provided alternative guidance is concrete and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

computeComputeA

Statistical operations beyond a plain lookup:

  • yoy / mom / qoq: same as get_series(transform=...), offered here too for a uniform entry point.

  • cagr: compound annual growth rate between date_from and date_to.

  • real: deflate series_id (nominal) by secondary_series_id (a price index, e.g. cpi_headline) into base_period prices (default: the latest date in range). secondary_series_id defaults to cpi_headline if omitted, but pick the deflator deliberately — CPI is a consumer basket, not a GDP deflator, and the two can diverge.

  • per_capita: divide series_id by population_series_id (default: population_malaysia), broadcasting the (annual) population estimate across every period within that year.

  • index_to: rebase series_id so its value at base_period (required) reads 100.

  • contribution_to_growth: how many percentage points of secondary_series_id's (the total's) change over the last periods_ago periods is attributable to series_id (the component). Requires secondary_series_id; both series must share a frequency.

ParametersJSON Schema
NameRequiredDescriptionDefault
date_toNo
date_fromNo
operationYes
series_idYes
base_periodNo
periods_agoNo
secondary_series_idNo
population_series_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the behavioral disclosure burden and does well: it reveals defaults (secondary_series_id defaults to cpi_headline, population_series_id defaults to population_malaysia, base_period defaults to latest date in range), required conditions (index_to requires base_period), and a caveat about CPI being a consumer basket rather than a GDP deflator. It does not describe return formatting, but the presence of an output schema reduces the need for that.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured as a scannable bulleted list with a clear opening phrase. Every line adds meaningful operational detail, and the caveats are woven in without padding or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity, eight parameters, no annotations, and an output schema that can describe returns, the description is largely complete. It covers operation semantics, defaults, requirements, and caveats. The main gap is that shared date-range behavior for date_from/date_to across operations is only implied rather than stated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate, and it largely does. It explains operation values, series_id as the primary series, secondary_series_id as a deflator or total, population_series_id for per_capita, base_period for index_to, and periods_ago for contribution_to_growth. However, date_from and date_to are only mentioned in the CAGR bullet and their general behavior across operations is not fully specified.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies a specific purpose: statistical operations beyond plain lookup, and enumerates discrete operations (yoy/mom/qoq, cagr, real, per_capita, index_to, contribution_to_growth). It distinguishes itself from siblings by positioning the tool as the uniform entry point for derived calculations, including explicitly noting overlap with get_series.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives concrete usage context: 'beyond a plain lookup' and explicitly says yoy/mom/qoq matches get_series(transform=...), making this the alternative entry point. It also specifies when special parameters are required, such as base_period for index_to and secondary_series_id for contribution_to_growth. It does not broadly cover when not to use each sibling, but the guidance is clear for the main alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

describe_seriesDescribe SeriesA

Full metadata for a series: coverage, unit, base years, known breaks/rebases, and caveats. Call this before trusting a comparison across time or before deciding whether a transform is needed.

ParametersJSON Schema
NameRequiredDescriptionDefault
series_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of disclosing behavior. It explains what the tool returns (metadata, including breaks/rebases and caveats) and frames it as a read-oriented decision aid. It does not explicitly state that it has no side effects, but 'full metadata' and the describe semantics strongly imply a non-mutating operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the tool's output and followed by actionable usage guidance. Every word earns its place with no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simple one-parameter schema, the presence of an output schema, and the clear use-case guidance, the description is nearly complete. It could be slightly improved by indicating where series_id comes from or how it relates to sibling tools like find_series, but nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has only series_id with 0% description coverage, and the description does not add any details about the parameter's format or origin. However, the parameter name is self-explanatory and the singular required field is easy to interpret, so the lack of elaboration is only a minor gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that the tool returns full metadata for a series and enumerates the metadata content (coverage, unit, base years, breaks/rebases, caveats). This distinguishes it from sibling tools like get_series or compare_series that likely return data or comparisons, though it does not explicitly name the alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit guidance on when to call the tool: before trusting a cross-time comparison or before deciding whether a transform is needed. It does not state when not to use it or mention alternative tools, so it falls just short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

explain_breakExplain BreakA

Why does this series jump/change at a given date? Returns each documented break (rebase, methodology change, classification revision, census baseline shift) in plain language, or says there are none.

ParametersJSON Schema
NameRequiredDescriptionDefault
series_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral disclosure burden. It states the output behavior: returns each documented break, describes the plain-language format, and covers the no-break case by saying it reports there are none. This is meaningful and useful, though it does not discuss error handling or side effects, which are less critical for a read-like explanation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is one purposeful sentence with no filler. It front-loads the triggering user question and immediately states the return behavior, making the tool's purpose scannable and complete.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has a single required parameter and an output schema, the description covers the essential behavior well: what breaks are returned, how they are presented, and the empty case. It could add a note clarifying the relationship between the 'given date' phrasing and the series_id-only input, but overall it is sufficient for an agent to select and call the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description should compensate for the undocumented series_id parameter. It does not describe the identifier's format, origin, or examples; it only refers to 'this series.' The parameter name and type are fairly self-explanatory, which keeps the score at a minimum viable level rather than lower.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource: it explains why a series jumps or changes by returning each documented break in plain language. The listed break types (rebase, methodology change, classification revision, census baseline shift) make the tool's domain unmistakable and distinguish it from generic siblings like get_series or describe_series.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The opening question, 'Why does this series jump/change at a given date?', gives a clear context for when the tool is appropriate. It does not explicitly contrast alternatives or say when not to use it, but the scenario is concrete enough for an agent to route to this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

find_seriesFind SeriesA

Find candidate series for a natural-language question about Malaysian official statistics. Returns ranked candidates, each with a one-line reason for the match — always call this before get_series if you don't already have a series id.

A curated KIRA series is not the only source of truth here: this only searches the ~20 series KIRA has registered so far, a small fraction of what DOSM actually publishes (open.dosm.gov.my/data-catalogue has the full list). An empty result means "not curated yet," not "this data doesn't exist" — see the no_match_hint field, and consider raw_query_url once you've found the dataset another way (web search, browsing the catalogue directly).

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full disclosure burden. It reveals the critical limitation that only ~20 curated series are searched, that empty results mean 'not curated yet' rather than nonexistence, and mentions the no_match_hint field. This prevents the agent from drawing false negative conclusions—an important behavioral trait not otherwise visible.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose and immediately follows with the key usage rule. Every sentence earns its place: the corpus limitation, the no_match_hint reference, and the raw_query_url fallback all add necessary operational context. No redundant filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given a single parameter, an output schema that covers return values, and the description's coverage of edge cases, nothing essential is missing. It addresses how to handle empty results, where to find broader data, and when to use the tool relative to siblings.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% and the only parameter is a bare 'query' string. The description supplies meaning by clarifying the query should be a natural-language question about Malaysian official statistics. This is sufficient contextual definition for the single parameter to be used correctly.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Find candidate series for a natural-language question about Malaysian official statistics.' It explicitly distinguishes itself from get_series by saying to always call this first if no series id exists. The behavior and scope are unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit when-to-use guidance: 'always call this before get_series if you don't already have a series id.' It also explains how to interpret empty results and directs the agent to raw_query_url after locating the dataset via other means. This fully covers selection and fallback behavior.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_seriesGet SeriesA

Fetch values for a series, optionally transformed (yoy/mom/qoq) and filtered by date range or geography. Every response carries a provenance block and a warnings array — never treat the bare numbers as the whole answer; read the warnings.

ParametersJSON Schema
NameRequiredDescriptionDefault
date_toNo
date_fromNo
geographyNo
series_idYes
transformNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of behavioral disclosure. It does so well by revealing that every response includes a provenance block and a warnings array, and by warning the agent not to trust bare numbers without reading warnings. This is meaningful behavioral context beyond a simple fetch.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The primary action is front-loaded, and the warning about the provenance/warnings block earns its place as essential usage guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The output schema covers return structure, and the description adds the important caveat about provenance and warnings. The main gap is missing routing guidance versus siblings, but for a fetch tool with five mostly self-explanatory parameters, the description is substantially complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It does by explaining the core parameter groups: series_id (the series), transform (yoy/mom/qoq), date range, and geography. It does not provide exact formats or enumerated transform values, but it adds genuinely useful meaning that the schema lacks.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'Fetch values for a series.' It also scopes the operation with optional transforms and filters, making it clearly distinct from siblings like find_series, describe_series, and compare_series.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given about when to choose this tool over alternatives such as describe_series or compute. The description implies 'use this when you need series values,' but it never states exclusions or points to sibling tools for other tasks.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

latest_releaseLatest ReleaseB

The newest available data point for a series, plus an estimated next release date derived from the series' frequency and typical release lag. The estimate is not authoritative — DOSM's own release calendar is the source of truth.

ParametersJSON Schema
NameRequiredDescriptionDefault
series_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral transparency burden and does a good job by disclosing that the next release date is only an estimate and not authoritative, with DOSM's calendar as the source of truth. It also explains the estimate is derived from frequency and typical release lag, which adds useful context beyond the bare tool name.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The main purpose is front-loaded, and the important caveat about the estimate being non-authoritative is placed immediately after.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has only one parameter and an output schema, so the description does not need to detail return values. However, it omits any guidance on when to choose this tool over sibling tools and leaves series_id semantics underspecified, making it minimally viable but not fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description does not explain what series_id should be, its format, or how to find valid values. The only hint is the phrase 'for a series,' which is marginal and does not compensate for the lack of schema documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that the tool returns the newest available data point for a series and adds an estimated next release date. It identifies the specific resource (a series) and the core function, but it does not explicitly distinguish itself from sibling tools like get_series or describe_series.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not specify when to use this tool over alternatives such as get_series or compare_series, nor does it mention any exclusions or prerequisites. The intended use is implied by the name and description, but no direct guidance is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_geographiesList GeographiesA

State / district / parliament (parlimen) / state assembly (DUN) codes and hierarchy, sourced from DOSM's population tables. level is one of state, district, parlimen, dun; pass parent (e.g. a state name) to filter to that parent's children — district and parlimen take a state, dun takes a parlimen.

ParametersJSON Schema
NameRequiredDescriptionDefault
levelYes
parentNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden and does a good job: it discloses the data provenance, the valid level values, and the parent-filtering behavior including specific hierarchy constraints. It does not mention edge cases like empty results or pagination, but the simple lookup nature and presence of an output schema reduce the need.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tightly packed sentences deliver the purpose, source, valid values, and parent-child rules with no filler. The hierarchy detail is front-loaded and every clause adds operational value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with two parameters, no annotations, and an output schema, the description covers everything needed to call it correctly: required level, optional parent, valid combinations, and data source. No essential call-decision information is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the description fully compensates. It enumerates the allowed `level` values and explains exactly how `parent` behaves for each level, including which parent types are valid for `dun`. This is far more useful than the bare schema's string/null types.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('list') and a clear resource: state/district/parliament/state assembly codes and hierarchy. It names the exact domain and data source, making it unmistakably distinct from the series/query siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete operational guidance: `level` must be one of state/district/parlimen/dun, and `parent` filters to children with explicit parent-child rules. It does not compare against sibling tools, but the domain is well separated and no exclusion criteria are needed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

lookup_classificationLookup ClassificationA

Look up or traverse a DOSM classification system: mcoicop (consumer expenditure, what CPI divisions are coded against) or msic (industry, Malaysian Standard Industrial Classification). Pass code (e.g. a division or section letter) to get that code's description and its full subtree; omit it to get the whole table.

ParametersJSON Schema
NameRequiredDescriptionDefault
codeNo
systemYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden. It explains the two modes of operation (whole table vs. specific code subtree) and clarifies what each system represents. It does not discuss errors or auth, but for a read-only lookup tool the disclosed behavior is sufficient.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two compact sentences deliver all key information without redundancy. The main action is front-loaded, and the parameter explanations are woven in efficiently. Every clause adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (2 params, no nested objects) and the presence of an output schema, the description covers all essential aspects: what systems are supported, how the optional code changes the result, and what outputs to expect. No critical information is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must explain the parameters. It does: 'system' values are named and defined (mcoicop/msic), and 'code' is described as optional, including example types ('division or section letter') and its effect on output. This compensates well for the empty schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses specific verbs ('look up', 'traverse') and names the exact resources ('DOSM classification system' with 'mcoicop' and 'msic'). It clearly differentiates this tool from data-series siblings by focusing on classification metadata and stating what each system means.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context on how to use the tool: pass 'code' for a specific entry and its subtree, or omit it to get the entire table. It doesn't explicitly compare against sibling tools or state when not to use it, but the classification-specific purpose makes the use case evident.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

raw_queryRaw QueryA

Escape hatch for shapes the curated tools don't cover — e.g. a division/sector/group breakdown a series' source table carries but no registry entry filters to (get_series only ever returns the one row per date the registry's filters picks out). Write a SELECT against series (aliased to series_id's source Parquet); only read-only single-statement SELECT/WITH queries are allowed, capped at row_limit rows. Prefer get_series/compare_series/compute when they cover your question — this bypasses the caveats, breaks, and warnings those carry, since it returns raw table rows, not a curated response.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYes
row_limitNo
series_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure, and it does so thoroughly. It states that only read-only single-statement SELECT/WITH queries are allowed, results are capped at row_limit rows, and the tool returns raw table rows rather than curated responses, bypassing the caveats of the curated tools.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-organized, leading with the use case, then the operational constraints, then the guidance to prefer alternatives. Every sentence earns its place and there is no redundant restatement of the tool name or schema fields.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity, the description covers purpose, usage, constraints, parameter semantics, and relationship to siblings. The presence of an output schema means return-value documentation is already handled structurally, so nothing essential is missing for an agent to select and invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate, and it does. It explains that `series` is aliased to the source Parquet identified by `series_id`, that `sql` must be a read-only SELECT/WITH statement, and that `row_limit` caps the returned rows. These meanings are not present in the bare input schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the tool as an escape hatch for shapes curated tools don't cover, specifies the resource (raw Parquet source behind `series`), and the operation (read-only SELECT/WITH). It also explicitly contrasts itself with get_series, which returns only curated registry-filtered rows, making sibling differentiation unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives an explicit usage rule: prefer get_series/compare_series/compute when they cover the question, and use raw_query only when they don't. It also provides a concrete example scenario (division/sector/group breakdown) and states the constraints under which the tool can be used.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

raw_query_urlRaw Query UrlA

Escape hatch for a dataset find_series returns nothing for and that has no registry entry at all — not even for raw_query, which still requires an existing series_id. find_series only searches KIRA's ~20 curated series; DOSM publishes far more than that (open .dosm.gov.my/data-catalogue has the full list). If find_series comes up empty, don't conclude the data doesn't exist — check DOSM's catalogue (or web search) for a storage.dosm.gov.my / storage.data.gov.my Parquet URL, then query it directly here, same sandboxing as raw_query (single read-only SELECT, aliased as series). No curation applies: no caveats, no breaks, no unit conversion — read the result with the same care you'd bring to the source file yourself. Only official Malaysian government open-data storage hosts are reachable; this is not a general-purpose fetcher.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYes
urlYes
row_limitNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden, and it delivers: it discloses that the tool is read-only, executes a single SELECT, aliases the result as `series`, applies no curation, performs no unit conversion, and only reaches official Malaysian government open-data hosts. This is exactly the kind of behavioral context an agent needs to avoid misusing an escape-hatch tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but dense and front-loaded with the core escape-hatch concept. Every sentence earns its place: scoping, fallback workflow, sandboxing constraints, curation caveats, and host restrictions. It is appropriately sized for a nuanced tool that needs to prevent misuse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given zero annotations, minimal schema, and a complex fallback use case, the description is remarkably complete. It covers when to use the tool, how to find the URL, what SQL restrictions apply, what curation is absent, and what hosts are allowed. An output schema exists, so return-value documentation is not the description's responsibility.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must supply parameter meaning. It does for the two required parameters: url is a Parquet URL on official storage hosts, and sql is a single read-only SELECT aliased as `series`. row_limit is not described, though its default of 1000 makes its purpose fairly obvious. Minor gap, but the critical parameters are well covered.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description defines a specific verb-resource pair: directly query a Parquet URL that falls outside the curated registry. It clearly distinguishes itself from raw_query (which requires an existing series_id) and find_series (which only searches ~20 curated series), so an agent can identify exactly when raw_query_url is the right tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use guidance: use this only when find_series returns nothing and the dataset has no registry entry. It also tells the agent what to do first (check DOSM's catalogue or web search for a storage.dosm.gov.my / storage.data.gov.my Parquet URL) and what not to do (treat it as a general-purpose fetcher). Exclusions are concrete and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

TDQS

A4.1/5.0
Disambiguation4/5

Each tool targets a distinct phase of the workflow—discovery, metadata, values, comparisons, breaks, geography, transforms, raw SQL—and the raw_query vs raw_query_url distinction is clear. The one soft spot is compute deliberately duplicating get_series's yoy/mom/qoq transforms, which could cause an agent to pick either for the same task.

Naming Consistency4/5

Most names follow a clear verb_noun pattern such as find_series, describe_series, get_series, and list_geographies. compute, raw_query, and raw_query_url break the pattern slightly, but the names remain readable and predictable overall.

Tool Count5/5

Eleven tools is well-scoped for a statistics server, covering the full research workflow without bloat. Each tool has a clear role, and the two raw-query escapes are justified by the curated-only limitation of the main registry.

Completeness5/5

The set covers discovery, metadata, retrieval, comparison, break explanation, release timing, geography, derived statistics, classification lookup, and raw access, leaving no obvious dead ends. The escape hatches for uncurated datasets address the one major limitation of the curated registry.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Provides seamless access to Malaysia's official government data catalogue, enabling developers to discover, explore, and fetch datasets from the Malaysian government's open data platform through a simple, unified interface.
    4
    14
    10
    ISC
  • A
    license
    A
    quality
    D
    maintenance
    Enables natural language queries of U.S. Census Bureau data, translating plain English questions into proper API calls and returning demographic, economic, and housing statistics with proper statistical interpretation and context.
    3
    20
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables querying UK Office for National Statistics datasets and their editions through natural language, with no authentication required.
    14
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables natural language discovery, querying, and analysis of Thailand's official statistics from the National Statistical Office via SDMX REST API. It provides tools for searching dataflows, exploring structures, and fetching data with caching and bilingual support.
    8
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Syakizz04/kira-dosm'

If you have feedback or need assistance with the MCP directory API, please join our Discord server