Skip to main content
Glama

Statistics Canada MCP Server

get_sdmx_data

Read-only

Fetch filtered time-series observations from a StatCan table via SDMX REST.

Filtering is done server-side — only the requested slice is returned. Call get_sdmx_structure first to see dimension positions and valid codes.

Key syntax (dot-separated codes in dimension position order): "1.2.1" = Geography=1 (Canada), Gender=2 (Men+), Age=1 (All ages) ".2.1" = all geographies, Gender=2, Age=1 (wildcard — preferred for multi-geo) "1+2.2.1" = Geography 1 or 2, Gender=2, Age=1 (OR)

IMPORTANT — key position codes:

  • Use member IDs from get_cube_metadata(), NOT SDMX codelist positions from get_sdmx_structure(). Member IDs and SDMX codelist codes are the same numbers.

  • Wildcard (omit a position) returns EVERY member of that dimension, including totals and parent aggregates — on large dimensions (e.g. 309 NOC occupations) that can exceed the 500-row cap here; use query_sdmx or fetch_sdmx_to_database instead.

  • To sum or rank across a hierarchy without double-counting totals, use leaf codes: get_sdmx_key_for_dimension(productId, dimension_position) returns them as an OR key.

Time filtering (use one or the other, not both): lastNObservations=12 → last 12 periods (e.g. 1 year of monthly data) startPeriod="2020" → from 2020 onwards (annual); "2020-01" for monthly endPeriod="2023-12" → up to Dec 2023

LIMITATION: StatCan rejects combining lastNObservations with startPeriod/endPeriod (returns 406).

Output is grouped by series: each entry in "series" holds the fields that are constant for that series once (dimension labels, _series_key, VECTOR_ID, UOM, SCALAR_FACTOR, ...) plus "observations" as [period, value] pairs with numeric values (null = suppressed). A third element {field: label} appears only on observations with their own attributes (e.g. a STATUS flag).

Observations are capped at MAX_SDMX_ROWS (500). For larger result sets, narrow the key or use startPeriod/endPeriod/lastNObservations.

Growth, percent change, averages, ranking or comparisons? Use query_sdmx instead of computing by hand from these values. Fetch each series and period range once: do not re-fetch periods you already have from get_sdmx_vector_data.

IMPORTANT: In your final response to the user, you MUST cite the source of your data. This means including the _sdmx_url, table information and productId/key in your response.

Input Schema

NameRequiredDescriptionDefault
keyYesDot-separated dimension codes in position order (e.g. '1.2.1'). Use '+' for OR ('1+2.2.1' = Geography 1 or 2). Omit a value for wildcard ('.2.1' = all geographies, Gender=2, Age=1). Code numbers match WDS memberIds — no translation needed. Call get_sdmx_structure first to see dimension positions and valid codes.
endPeriodNoEnd period in YYYY or YYYY-MM format.
productIdYes
startPeriodNoStart period in YYYY or YYYY-MM format.
lastNObservationsNoReturn only the last N observations per series (e.g. 12 for one year of monthly data).

Output Schema

NameRequiredDescriptionDefault
seriesYesObservations grouped by series.
_messageNoTruncation guidance, when truncated.
_sdmx_urlYesSDMX request URL — cite as the data source.
row_countYesTotal observations returned by StatCan (before truncation).
_truncatedYesTrue if observations were capped at 500.
series_countYesNumber of series in `series`.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed7 schema fields changed
    • addedOutput schema / $defs
      Added value: +{
      +  "SDMXSeries": {
      +    "additionalProperties": true,
      +    "description": "One series: its constant fields (dimension labels, VECTOR_ID, UOM, ...) once.",
      +    "properties": {
      +      "_series_key": {
      +        "description": "Dot-separated SDMX key of this series.",
      +        "title": "Series Key",
      +        "type": "string"
      +      },
      +      "observations": {
      +        "description": "[period, value] pairs; value is a number or null (suppressed). Observations with their own attributes add a third element {field: label}.",
      +        "items": {
      +          "items": {},
      +          "type": "array"
      +        },
      +        "title": "Observations",
      +        "type": "array"
      +      }
      +    },
      +    "required": [
      +      "_series_key",
      +      "observations"
      +    ],
      +    "title": "SDMXSeries",
      +    "type": "object"
      +  }
      +}
    • changedOutput schema / properties / _truncated / description
      Previous value: -"True if data was capped at 500 rows."New value: +"True if observations were capped at 500."
    • removedOutput schema / properties / data
      Removed value: -{
      -  "description": "Observation rows: dimension columns, period, value, and SDMX attributes.",
      -  "items": {
      -    "additionalProperties": true,
      -    "type": "object"
      -  },
      -  "title": "Data",
      -  "type": "array"
      -}
    • changedOutput schema / properties / row_count / description
      Previous value: -"Total rows returned by StatCan (before truncation)."New value: +"Total observations returned by StatCan (before truncation)."
    • addedOutput schema / properties / series
      Added value: +{
      +  "description": "Observations grouped by series.",
      +  "items": {
      +    "$ref": "#/$defs/SDMXSeries"
      +  },
      +  "title": "Series",
      +  "type": "array"
      +}
    • addedOutput schema / properties / series_count
      Added value: +{
      +  "description": "Number of series in `series`.",
      +  "title": "Series Count",
      +  "type": "integer"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "_sdmx_url",
      -  "row_count",
      -  "data",
      -  "_truncated"
      -]New value: +[
      +  "_sdmx_url",
      +  "row_count",
      +  "series_count",
      +  "series",
      +  "_truncated"
      +]
  2. First observed

TDQS

A4.9/5.0
Behavior5/5

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

Annotations only declare readOnlyHint/openWorldHint, but the description adds substantial behavior: server-side filtering, a hard MAX_SDMX_ROWS=500 cap, the 406 error when combining lastNObservations with startPeriod/endPeriod, wildcard expansion including totals/parent aggregates on large dimensions, and null meaning suppressed values. It even documents the response grouping shape despite an output schema existing.

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

Conciseness4/5

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

Well front-loaded and organized under clear headers, but there is some redundancy — the 500-row cap and the 'narrow the key or use period filters' advice appear twice, and the citation mandate is somewhat bolted on. Long overall, though nearly every block carries usable information.

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?

Covers prerequisites, key syntax, time-filter rules, row limits, failure modes, and return structure. For a 5-parameter tool with an open-world read, an agent has everything needed to construct a valid call without trial and error.

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 coverage is already 80%, yet the description adds real semantics for the hardest parameter — 'key' — with dot-position ordering, '+' for OR, omitted position for wildcard, and three worked examples. It also clarifies the mutual exclusivity of lastNObservations vs startPeriod/endPeriod and gives format examples ('2020-01' for monthly).

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 ('fetch filtered time-series observations') plus resource (StatCan table via SDMX REST) and scope (server-side filtering, only requested slice returned). This cleanly distinguishes it from siblings like query_sdmx (computed analytics), get_sdmx_vector_data (already-fetched vectors), and get_sdmx_structure (metadata).

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?

Explicitly routes the agent: call get_sdmx_structure first for dimension positions, use get_cube_metadata for member IDs, use get_sdmx_key_for_dimension for leaf codes, and prefer query_sdmx for growth/percent-change/ranking or when results exceed 500 rows. It also warns not to re-fetch periods already obtained from get_sdmx_vector_data — a genuine when-not rule.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.