Koskamo

ilostat-mcp-server

An MCP server that provides access to ILOSTAT labour statistics. It allows users to search the indicator catalog, describe datasets, query observations for countries and regions, compare geographies, and generate country profiles. It also supports running SQL queries on staged dataframes for further analysis.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

ilostat-mcp-server logo, by cyanheadsCommunity listingStreamable HTTPNo sign-inEndpoint checked 2026-11-07Published by cyanheads
MCP endpoint (Streamable HTTP)
https://ilostat.caseyjhand.com/mcp
Vendor documentation

What its tools do

8 tools, grouped by the hints the server advertises. Hints are self-declared, not verified behavior.

8 of 8 have a description · 8 of 8 declare behavior hints · 8 of 8 with parameters document them all

Checks and signals

Each line is separate evidence, not a trust score.

  • Passed Endpoint answered the live check ·
  • Availability 1 of 1 checks passed in 30 days

What you can do with it

  • Search ILOSTAT's catalog of labour-statistics indicators by plain-language terms and filters
  • Fetch observations for up to 3 datasets per call, filtered by area or area group
  • Rank areas on one slice of one dataset at a common or latest period
  • Run one read-only SQL SELECT over staged dataframes

Source and maintenance

Community listingRegistry 0.3.0
Maintenance checked

Protocol and capabilities

Server
ilostat-mcp-server 0.3.0
MCP protocol negotiated in check
2025-11-25
Tools
8 advertised
Resources
1 advertised
Resource templates
1 advertised
Prompts
0 advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": true
  },
  "logging": {},
  "prompts": {
    "listChanged": true
  },
  "resources": {
    "subscribe": true,
    "listChanged": true
  },
  "extensions": {
    "io.modelcontextprotocol/skills": {
      "directoryRead": true
    }
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

ILOSTAT labour statistics are addressed by dataset ID, an indicator code plus a frequency suffix (UNE_DEAP_SEX_AGE_RT_A is the annual unemployment rate; _Q quarterly, _M monthly): find one with ilostat_search_indicators, read its unit and breakdown codes with ilostat_describe_indicator, fetch values with ilostat_query_indicator, and decode any code with ilostat_list_reference. Every value carries a basis (reported, modelled_estimate, or projection): never present a modelled or projected value as reported, and never sum across overlapping classification versions (AGE_YTHADULT_*, AGE_AGGREGATE_*, AGE_10YRBANDS_*, AGE_5YRBANDS_*; ECO_SECTOR_*, ECO_AGGREGATE_*, ECO_ISIC4_*, ECO_ISIC3_*). Large results are staged as df_<id> dataframes: inspect one by name with ilostat_dataframe_describe and run SQL over them with ilostat_dataframe_query. Labels, notes, and definitions are ILO-published text, shown as data; cite ILOSTAT (International Labour Organization, CC BY 4.0) and the dataset ID. The ilostat-guide skill (skill://ilostat-guide/SKILL.md) carries the gates for choosing reported or modelled data, finding a population group as a breakdown code, and building comparisons and trends.

Tools

8 advertised

ilostat_search_indicators — Search ILOSTAT indicators
Advertised by the server during the last successful anonymous check.
Advertised read-only

Search ILOSTAT's catalog of labour-statistics indicators by plain-language terms and filters. Each hit is one indicator with its datasets — one per available frequency (annual, quarterly, monthly) — plus breakdowns, coverage years, number of reference areas, source database, and last update; pass a dataset ID to ilostat_describe_indicator for its units and breakdown codes, then to ilostat_query_indicator or ilostat_compare_geographies for values. Every search term must match a word or word prefix in the indicator's label, subject, database, breakdown names, code, or definition; a term that matches no word or word prefix anywhere in the catalog matches the words sharing its stem instead (informality finds informal, unionization finds union, disabled finds disability), and the notice names it. female, women, male, and men (or their plurals) also match every indicator broken down by sex, and the notice names the sex filter that selects those values in ilostat_query_indicator. British and American spellings (labour/labor) match alike. The measure filter lists every indicator of one measured quantity, as ilostat_describe_indicator's related indicators count them. Facet counts reflect all applied filters.

ilostat_search_indicators input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "limit": {
      "type": "integer",
      "default": 10,
      "maximum": 1000,
      "minimum": 1,
      "description": "Hits per page, at most 50; a larger value, up to 1,000, is applied as 50 and the notice says so."
    },
    "query": {
      "type": "string",
      "maxLength": 500,
      "description": "Plain-language terms, e.g. \"youth unemployment\" or \"informal employment rate\". Case, accents, and punctuation are ignored, labor matches labour, and a trailing plural s is tolerated; a term no catalog word starts with is matched by its stem (-ity, -ization, -ive, -ment, -ing, -ed, -ly, a plural s, and a silent e dropped, -ies read as y, -ble and -bly read as -bil). Omit to browse by filters (results then order by indicator code)."
    },
    "cursor": {
      "type": "string",
      "maxLength": 256,
      "description": "Opaque continuation token: the previous page's next_cursor, passed unchanged."
    },
    "measure": {
      "type": "string",
      "maxLength": 32,
      "description": "Measure code, exactly as ilostat_describe_indicator's measure.code gives it (e.g. EMP_TEMP_NB); case-insensitive. Keeps every indicator measuring that quantity, under any breakdown."
    },
    "subject": {
      "type": "string",
      "maxLength": 32,
      "description": "Subject code, e.g. LUU (unemployment and labour underutilization); case-insensitive. ilostat_list_reference topic subjects lists them."
    },
    "database": {
      "type": "string",
      "maxLength": 32,
      "description": "Source database code, e.g. LFS or ILOEST (the ILO modelled estimates); case-insensitive. ilostat_list_reference topic databases lists them."
    },
    "breakdown": {
      "type": "string",
      "maxLength": 32,
      "description": "Classification type the indicator is broken down by, e.g. AGE, ECO, GEO, SEX; case-insensitive. ilostat_list_reference topic classification_types lists them."
    },
    "frequency": {
      "enum": [
        "A",
        "Q",
        "M"
      ],
      "type": "string",
      "description": "Keep only datasets of this frequency: A annual, Q quarterly, M monthly. Narrows each hit's datasets; an indicator with none left drops out."
    },
    "aggregates_only": {
      "type": "boolean",
      "default": false,
      "description": "Keep only datasets carrying World, regional, or income-group rows, dropping indicators with none."
    }
  },
  "additionalProperties": false
}
ilostat_search_indicators output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "hits",
        "total",
        "facets",
        "catalog_as_of",
        "truncated",
        "shown",
        "cap"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "cap": {
      "type": "number",
      "description": "The limit applied to this page."
    },
    "hits": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "indicator",
          "label",
          "subject",
          "database",
          "breakdowns",
          "has_aggregates",
          "datasets"
        ],
        "properties": {
          "label": {
            "type": "string",
            "description": "Indicator label as ILOSTAT publishes it."
          },
          "subject": {
            "type": "object",
            "required": [
              "code",
              "label"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Subject code."
              },
              "label": {
                "type": "string",
                "description": "Subject label."
              }
            },
            "description": "Subject code and label.",
            "additionalProperties": false
          },
          "database": {
            "type": "object",
            "required": [
              "code",
              "label"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Source database code."
              },
              "label": {
                "type": "string",
                "description": "Source database label."
              }
            },
            "description": "Source database code and label.",
            "additionalProperties": false
          },
          "datasets": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "dataset_id",
                "frequency",
                "data_start",
                "data_end",
                "n_ref_area",
                "n_records",
                "last_update",
                "has_aggregates"
              ],
              "properties": {
                "data_end": {
                  "type": "number",
                  "description": "Last year with data (can include projection years)."
                },
                "frequency": {
                  "type": "string",
                  "description": "A (annual), Q (quarterly), or M (monthly)."
                },
                "n_records": {
                  "type": "number",
                  "description": "Observations an unfiltered best-source download returns."
                },
                "data_start": {
                  "type": "number",
                  "description": "First year with data."
                },
                "dataset_id": {
                  "type": "string",
                  "description": "Dataset ID — the indicator code plus _A, _Q, or _M — to pass to ilostat_describe_indicator, ilostat_query_indicator, or ilostat_compare_geographies."
                },
                "n_ref_area": {
                  "type": "number",
                  "description": "Reference areas with data."
                },
                "last_update": {
                  "type": "string",
                  "description": "Last upstream update, ISO 8601 without zone offset."
                },
                "has_aggregates": {
                  "type": "boolean",
                  "description": "Whether this dataset carries World, regional, or income-group rows."
                }
              },
              "description": "One dataset of the indicator at one frequency.",
              "additionalProperties": false
            },
            "description": "The datasets that pass the filters, annual first."
          },
          "indicator": {
            "type": "string",
            "description": "Indicator code (dataset IDs add _A, _Q, or _M)."
          },
          "breakdowns": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Breakdown names (e.g. [\"sex\", \"age\"]); empty when none."
          },
          "match_scope": {
            "enum": [
              "label",
              "metadata",
              "definition"
            ],
            "type": "string",
            "description": "Where every term matched (a sex word beside other terms is left out): label (tier 1), label plus subject, database, breakdowns, and code (tier 2), or the definition text too (tier 3). Absent when browsing without a query."
          },
          "classification": {
            "type": "string",
            "description": "Breakdown classification (e.g. SEX_AGE); absent when the indicator has none."
          },
          "has_aggregates": {
            "type": "boolean",
            "description": "Whether any listed dataset carries World, regional, or income-group rows."
          }
        },
        "description": "One indicator hit.",
        "additionalProperties": false
      },
      "description": "This page of hits. With a query: tier, then more reference areas first, then code. Without: by code."
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "unknown_filter_code",
                "invalid_cursor",
                "catalog_unavailable"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `unknown_filter_code`: database, subject, breakdown, or measure is not an ILOSTAT code. `invalid_cursor`: cursor does not decode. `catalog_unavailable`: No catalog snapshot has loaded and the load failed, or the first load has not finished within 30 s. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "shown": {
      "type": "number",
      "description": "Hits returned on this page."
    },
    "total": {
      "type": "number",
      "description": "Indicators matched after all filters."
    },
    "facets": {
      "type": "object",
      "required": [
        "databases",
        "frequencies",
        "subjects"
      ],
      "properties": {
        "subjects": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "code",
              "label",
              "count"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Facet code."
              },
              "count": {
                "type": "number",
                "description": "Matching indicators with this value."
              },
              "label": {
                "type": "string",
                "description": "Facet label."
              }
            },
            "description": "One facet value and its indicator count.",
            "additionalProperties": false
          },
          "description": "Matching indicators per subject."
        },
        "databases": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "code",
              "label",
              "count"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Facet code."
              },
              "count": {
                "type": "number",
                "description": "Matching indicators with this value."
              },
              "label": {
                "type": "string",
                "description": "Facet label."
              }
            },
            "description": "One facet value and its indicator count.",
            "additionalProperties": false
          },
          "description": "Matching indicators per source database."
        },
        "frequencies": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "code",
              "count"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Frequency code (A, Q, M)."
              },
              "count": {
                "type": "number",
                "description": "Matching indicators with a dataset at this frequency."
              }
            },
            "description": "One frequency and its indicator count.",
            "additionalProperties": false
          },
          "description": "Matching indicators per frequency."
        }
      },
      "description": "Counts over the fully filtered match set, not just this page.",
      "additionalProperties": false
    },
    "notice": {
      "type": "string",
      "description": "That a limit past the page cap was applied as the cap, why the query was browsed by filters alone, which terms were matched by stem and as which catalog words (check those hits are on topic), the sex filter a sex word names, how to widen a search that matched nothing, that the cursor starts past the last match, and how to reach the remaining pages — whichever apply, joined."
    },
    "truncated": {
      "type": "boolean",
      "description": "True when more hits remain beyond this page."
    },
    "next_cursor": {
      "type": "string",
      "description": "Pass as cursor to get the next page; absent on the last page."
    },
    "catalog_as_of": {
      "type": "string",
      "description": "ISO timestamp the searched catalog was last confirmed current."
    }
  },
  "additionalProperties": false
}
ilostat_search_indicators annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true
}
ilostat_describe_indicator — Describe an ILOSTAT dataset
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Explain one ILOSTAT dataset before comparing numbers: its definition, unit and multiplier, frequency variants and coverage, the sex and breakdown codes in use across its frequencies (the total code of each breakdown marked), the reference areas it covers, whether it carries World/regional/income-group aggregates, and how its observations are classed as reported, modelled, or projected. Accepts a dataset ID (UNE_DEAP_SEX_AGE_RT_A) or a bare indicator code (UNE_DEAP_SEX_AGE_RT), which describes every frequency. An unknown code returns found: false with guidance.

ilostat_describe_indicator input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "dataset_id"
  ],
  "properties": {
    "dataset_id": {
      "type": "string",
      "pattern": "^[A-Z0-9_]+( *[+,] *[A-Z0-9_]+)*$",
      "maxLength": 200,
      "description": "One dataset ID (indicator code plus _A, _Q, or _M, e.g. UNE_DEAP_SEX_AGE_RT_A) or a bare indicator code (UNE_DEAP_SEX_AGE_RT), as ilostat_search_indicators returns them. Case-insensitive; a DF_ prefix (the SDMX dataflow form) is stripped."
    }
  },
  "additionalProperties": false
}
ilostat_describe_indicator output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "found",
        "catalog_as_of"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "cap": {
      "type": "number",
      "description": "The most related indicators listed."
    },
    "unit": {
      "type": "object",
      "required": [
        "measure",
        "type",
        "multiplier"
      ],
      "properties": {
        "type": {
          "type": "string",
          "description": "Unit type code (RT rate, NB number, …)."
        },
        "measure": {
          "type": "string",
          "description": "Unit code (PT percent, PS persons, LC local currency, …)."
        },
        "multiplier": {
          "type": "number",
          "description": "Power of ten values are expressed in: 0 units, 3 thousands, 6 millions."
        },
        "type_label": {
          "type": "string",
          "description": "Unit type label."
        },
        "measure_label": {
          "type": "string",
          "description": "Unit label."
        },
        "multiplier_label": {
          "type": "string",
          "description": "Multiplier label."
        }
      },
      "description": "Unit of the values, already in the multiplier scale; absent when unresolved.",
      "additionalProperties": false
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "catalog_unavailable"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `catalog_unavailable`: No catalog snapshot has loaded and the load failed, or the first load has not finished within 30 s. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "found": {
      "type": "boolean",
      "description": "False when no dataset or indicator has the code."
    },
    "label": {
      "type": "string",
      "description": "Indicator label as ILOSTAT publishes it."
    },
    "shown": {
      "type": "number",
      "description": "Related indicators listed."
    },
    "notice": {
      "type": "string",
      "description": "Where to find breakdown codes and units when the structure service did not supply them, and how to list every related indicator when the list is cut — whichever apply, joined."
    },
    "measure": {
      "type": "object",
      "required": [
        "code",
        "label"
      ],
      "properties": {
        "code": {
          "type": "string",
          "description": "Measure (the quantity measured, shared by breakdown variants) code."
        },
        "label": {
          "type": "string",
          "description": "Measure (the quantity measured, shared by breakdown variants) label."
        }
      },
      "description": "Measure (the quantity measured, shared by breakdown variants) code and label.",
      "additionalProperties": false
    },
    "subject": {
      "type": "object",
      "required": [
        "code",
        "label"
      ],
      "properties": {
        "code": {
          "type": "string",
          "description": "Subject code."
        },
        "label": {
          "type": "string",
          "description": "Subject label."
        }
      },
      "description": "Subject code and label.",
      "additionalProperties": false
    },
    "database": {
      "type": "object",
      "required": [
        "code",
        "label"
      ],
      "properties": {
        "code": {
          "type": "string",
          "description": "Source database code."
        },
        "label": {
          "type": "string",
          "description": "Source database label."
        }
      },
      "description": "Source database code and label.",
      "additionalProperties": false
    },
    "datasets": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "dataset_id",
          "frequency",
          "data_start",
          "data_end",
          "n_ref_area",
          "n_records",
          "n_records_all",
          "last_update",
          "has_aggregates"
        ],
        "properties": {
          "data_end": {
            "type": "number",
            "description": "Last year with data (can include projection years)."
          },
          "frequency": {
            "type": "string",
            "description": "A (annual), Q (quarterly), or M (monthly)."
          },
          "n_records": {
            "type": "number",
            "description": "Best-source observations an unfiltered download returns."
          },
          "data_start": {
            "type": "number",
            "description": "First year with data."
          },
          "dataset_id": {
            "type": "string",
            "description": "Dataset ID."
          },
          "n_ref_area": {
            "type": "number",
            "description": "Reference areas with data."
          },
          "last_update": {
            "type": "string",
            "description": "Last upstream update, ISO 8601 without zone offset."
          },
          "n_records_all": {
            "type": "number",
            "description": "Observations including secondary sources."
          },
          "has_aggregates": {
            "type": "boolean",
            "description": "Whether this dataset carries World, regional, or income-group rows."
          }
        },
        "description": "One frequency variant of the indicator.",
        "additionalProperties": false
      },
      "description": "Every frequency variant of the indicator, annual first."
    },
    "guidance": {
      "type": "string",
      "description": "On a miss: how to find a valid dataset ID."
    },
    "indicator": {
      "type": "string",
      "description": "Indicator code."
    },
    "ref_areas": {
      "type": "object",
      "required": [
        "countries",
        "aggregates",
        "count"
      ],
      "properties": {
        "count": {
          "type": "number",
          "description": "Reference areas with data."
        },
        "countries": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Country codes with data."
        },
        "aggregates": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "X-coded aggregate codes with data."
        }
      },
      "description": "Reference areas the indicator covers across its frequencies, from ILOSTAT's structure service; absent when structure_status is unavailable.",
      "additionalProperties": false
    },
    "truncated": {
      "type": "boolean",
      "description": "True when related_datasets lists fewer than related_total."
    },
    "basis_rule": {
      "type": "object",
      "required": [
        "modelled_source_label",
        "projection_after_year",
        "projection_rule",
        "database_is_modelled"
      ],
      "properties": {
        "edition": {
          "type": "string",
          "description": "The edition the cutoff derives from, e.g. Nov. 2025."
        },
        "projection_rule": {
          "enum": [
            "edition",
            "catalog_edition",
            "current_year"
          ],
          "type": "string",
          "description": "How the cutoff was set: the label's edition, the catalog's latest ILO modelled estimates edition, or the year before the current year."
        },
        "database_is_modelled": {
          "type": "boolean",
          "description": "Whether the whole database is the ILO modelled estimates (ILOEST)."
        },
        "modelled_source_label": {
          "type": "string",
          "description": "Source label that marks an observation as an ILO modelled estimate."
        },
        "projection_after_year": {
          "type": "number",
          "description": "Last year counted as an estimate; later modelled years are projections."
        }
      },
      "description": "How observations are classed reported, modelled_estimate, or projection.",
      "additionalProperties": false
    },
    "breakdowns": {
      "type": "object",
      "required": [
        "sex",
        "sex_codes"
      ],
      "properties": {
        "sex": {
          "type": "boolean",
          "description": "Whether the dataset has a sex breakdown."
        },
        "classif1": {
          "type": "object",
          "required": [
            "type",
            "codes"
          ],
          "properties": {
            "type": {
              "type": "string",
              "description": "Classification type of classif1 (e.g. AGE, ECO, DCL)."
            },
            "codes": {
              "type": "array",
              "items": {
                "type": "object",
                "required": [
                  "code",
                  "label",
                  "is_total"
                ],
                "properties": {
                  "code": {
                    "type": "string",
                    "description": "Code to pass as classif1."
                  },
                  "label": {
                    "type": "string",
                    "description": "Code label."
                  },
                  "is_total": {
                    "type": "boolean",
                    "description": "Whether the code is the total of its breakdown."
                  }
                },
                "description": "One breakdown code.",
                "additionalProperties": false
              },
              "description": "Codes ILOSTAT's structure service lists for this breakdown that ilostat_query_indicator accepts as classif1; classification group headers excluded. The list covers every frequency of the indicator, so a code may have no rows in one dataset."
            },
            "type_label": {
              "type": "string",
              "description": "Classification type label."
            }
          },
          "description": "The classif1 breakdown.",
          "additionalProperties": false
        },
        "classif2": {
          "type": "object",
          "required": [
            "type",
            "codes"
          ],
          "properties": {
            "type": {
              "type": "string",
              "description": "Classification type of classif2 (e.g. AGE, ECO, DCL)."
            },
            "codes": {
              "type": "array",
              "items": {
                "type": "object",
                "required": [
                  "code",
                  "label",
                  "is_total"
                ],
                "properties": {
                  "code": {
                    "type": "string",
                    "description": "Code to pass as classif2."
                  },
                  "label": {
                    "type": "string",
                    "description": "Code label."
                  },
                  "is_total": {
                    "type": "boolean",
                    "description": "Whether the code is the total of its breakdown."
                  }
                },
                "description": "One breakdown code.",
                "additionalProperties": false
              },
              "description": "Codes ILOSTAT's structure service lists for this breakdown that ilostat_query_indicator accepts as classif2; classification group headers excluded. The list covers every frequency of the indicator, so a code may have no rows in one dataset."
            },
            "type_label": {
              "type": "string",
              "description": "Classification type label."
            }
          },
          "description": "The classif2 breakdown.",
          "additionalProperties": false
        },
        "sex_codes": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Sex codes the dataset uses (SEX_T total)."
        }
      },
      "description": "Breakdown codes in use, from ILOSTAT's structure service; absent when structure_status is unavailable.",
      "additionalProperties": false
    },
    "dataset_id": {
      "type": "string",
      "description": "The dataset requested, when a dataset ID (not a bare indicator code) was given."
    },
    "definition": {
      "type": "string",
      "description": "ILOSTAT definition of the indicator, HTML stripped; links kept as \"text (url)\"."
    },
    "attribution": {
      "type": "string",
      "description": "Citation to keep with any use of the data."
    },
    "catalog_as_of": {
      "type": "string",
      "description": "ISO timestamp the catalog was last confirmed current."
    },
    "default_slice": {
      "type": "object",
      "properties": {
        "sex": {
          "type": "string",
          "description": "Default sex code."
        },
        "classif1": {
          "type": "string",
          "description": "Default classif1 code."
        },
        "classif2": {
          "type": "string",
          "description": "Default classif2 code."
        }
      },
      "description": "The dataset's total codes from its default view — the slice ilostat_compare_geographies uses when sex, classif1, or classif2 is omitted; a breakdown with no total (deciles) is left out.",
      "additionalProperties": false
    },
    "related_total": {
      "type": "number",
      "description": "How many other indicators share this measure. ilostat_search_indicators with measure set to measure.code lists them all."
    },
    "has_aggregates": {
      "type": "boolean",
      "description": "Whether the requested dataset (or, for an indicator code, any of its datasets) carries World, regional, or income-group rows."
    },
    "related_datasets": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "indicator",
          "label"
        ],
        "properties": {
          "label": {
            "type": "string",
            "description": "Indicator label."
          },
          "indicator": {
            "type": "string",
            "description": "Indicator code."
          },
          "classification": {
            "type": "string",
            "description": "Its breakdown classification."
          }
        },
        "description": "An indicator measuring the same quantity.",
        "additionalProperties": false
      },
      "description": "The first 20 other indicators sharing this measure under other breakdowns, by code; related_total counts all of them."
    },
    "structure_status": {
      "enum": [
        "complete",
        "unavailable"
      ],
      "type": "string",
      "description": "unavailable when ILOSTAT's structure service has no entry for the indicator or cannot be reached; breakdowns, default_slice, unit, and ref_areas are then absent."
    }
  },
  "additionalProperties": false
}
ilostat_describe_indicator annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true
}
ilostat_query_indicator — Query ILOSTAT observations
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Fetch observations for up to 3 ILOSTAT datasets per call, filtered by reference area or area group, sex, breakdown codes (classif1, classif2), source, and period; datasets past the first 3 come back as remaining_dataset_ids for another call. Rows keep their source, observation status, decoded notes, and a basis — reported, modelled_estimate, or projection — and the response echoes every filter applied, including the best-source default. Codes are checked against ILOSTAT's dictionaries before the request is sent: ilostat_list_reference lists valid codes and ilostat_describe_indicator lists the codes a dataset actually uses. A result larger than the inline preview is staged in full as a df_<id> dataframe for SQL through ilostat_dataframe_describe and ilostat_dataframe_query when this deployment enables dataframes. A request with no filters at all is refused when the dataset exceeds the row ceiling, and a filtered request that still exceeds it is refused with guidance to narrow it.

ilostat_query_indicator input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "dataset_ids"
  ],
  "properties": {
    "sex": {
      "type": "array",
      "items": {
        "enum": [
          "SEX_T",
          "SEX_M",
          "SEX_F",
          "SEX_O"
        ],
        "type": "string"
      },
      "maxItems": 4,
      "description": "Sex codes SEX_T, SEX_M, SEX_F, SEX_O; T/M/F/O and total/both/male/female/other are accepted."
    },
    "time": {
      "type": "string",
      "pattern": "^\\d{4}(Q[1-4]|M(0[1-9]|1[0-2]))?$",
      "description": "One exact period: YYYY (on a quarterly or monthly dataset, every period of that year), YYYYQn, or YYYYMmm; 2024-Q2, 2024 Q2, and 2025-03 are normalized. Not combinable with time_from, time_to, or latest_only."
    },
    "sources": {
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 64
      },
      "maxItems": 100,
      "description": "Source codes (e.g. BA:453); ilostat_list_reference topic sources with ref_area lists an area's sources. Without source_selection, setting sources switches it to all, since a secondary source matches nothing under best."
    },
    "time_to": {
      "type": "string",
      "pattern": "^\\d{4}$",
      "description": "Last year (YYYY), not before time_from."
    },
    "classif1": {
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 64
      },
      "maxItems": 100,
      "description": "Codes of the first breakdown (e.g. AGE_YTHADULT_YGE15); case-insensitive. ilostat_describe_indicator lists the codes a dataset uses."
    },
    "classif2": {
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 64
      },
      "maxItems": 100,
      "description": "Codes of the second breakdown, for datasets that have one; case-insensitive. ilostat_describe_indicator lists them."
    },
    "ref_areas": {
      "type": "array",
      "items": {
        "type": "string",
        "pattern": "^[A-Z0-9]{3}$"
      },
      "maxItems": 300,
      "description": "Reference areas (up to 300): ISO3 country codes (USA) or X-coded aggregates (X01 World); case-insensitive, ILO_GEO_ forms accepted. Aggregates need a dataset with has_aggregates true. Omit for every area."
    },
    "time_from": {
      "type": "string",
      "pattern": "^\\d{4}$",
      "description": "First year (YYYY); upstream filters by year only."
    },
    "area_group": {
      "type": "string",
      "pattern": "^[A-Z0-9]{3}$",
      "description": "X01 for every country, an ILO region or subregion, or a World Bank income group (X06, X56, X02, …); expands to its member countries, unioned with ref_areas. ilostat_list_reference topic area_groups lists the codes."
    },
    "dataset_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "pattern": "^[A-Z0-9_]+$",
        "maxLength": 64
      },
      "maxItems": 100,
      "minItems": 1,
      "description": "Dataset IDs, up to 100 — an indicator code plus _A, _Q, or _M (UNE_DEAP_SEX_AGE_RT_A), as ilostat_search_indicators returns them. Case-insensitive; a DF_ prefix (the SDMX dataflow form) is stripped, a bare indicator code resolves when it has one frequency, an element holding + or , joined IDs is split, and duplicates are dropped. Every ID is checked; the first 3 distinct datasets are queried and the rest come back as remaining_dataset_ids for another call."
    },
    "latest_only": {
      "type": "boolean",
      "default": false,
      "description": "Only each series' latest period — a series is one dataset, reference area, sex, classif1, and classif2 code — with every row at that period (one per source under source_selection all or secondary; the latest quarter or month on sub-annual datasets); combines with time_from/time_to. When the request's full history is too large or too slow to read in one call, it falls back to the latest period per area and dataset, which can miss a series that ends earlier; applied_filters.latest_mode says which ran, and the notice says so. time_from or classif1 narrow it back under; sex or fewer ref_areas alone may still read too much and fall back."
    },
    "source_selection": {
      "enum": [
        "best",
        "all",
        "secondary"
      ],
      "type": "string",
      "description": "best (default): the preferred source per area and period; all: secondary sources too, each row flagged best_source; secondary: secondary sources only. Defaults to all when sources is set."
    }
  },
  "additionalProperties": false
}
ilostat_query_indicator output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "datasets",
        "row_count",
        "rows",
        "legend",
        "summary",
        "attribution",
        "applied_filters",
        "truncated",
        "shown",
        "cap"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "cap": {
      "type": "number",
      "description": "Inline preview budget, in serialized characters."
    },
    "rows": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "dataset_id",
          "ref_area",
          "source",
          "period",
          "notes",
          "basis"
        ],
        "properties": {
          "sex": {
            "type": "string",
            "description": "Sex code; absent when the dataset has no sex breakdown."
          },
          "basis": {
            "enum": [
              "reported",
              "modelled_estimate",
              "projection"
            ],
            "type": "string",
            "description": "reported (national or institutional source), modelled_estimate (ILO modelled, up to the cutoff), or projection (ILO modelled, after it)."
          },
          "notes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Note codes (legend.notes decodes them)."
          },
          "value": {
            "type": "number",
            "description": "Value in the dataset unit; absent when upstream sent none."
          },
          "period": {
            "type": "string",
            "description": "Period: YYYY, YYYYQn, or YYYYMmm."
          },
          "source": {
            "type": "string",
            "description": "Source code (legend.source decodes it)."
          },
          "classif1": {
            "type": "string",
            "description": "First breakdown code, when the dataset has one."
          },
          "classif2": {
            "type": "string",
            "description": "Second breakdown code, when the dataset has one."
          },
          "ref_area": {
            "type": "string",
            "description": "Reference area code (legend.ref_area decodes it)."
          },
          "dataset_id": {
            "type": "string",
            "description": "Dataset ID."
          },
          "obs_status": {
            "type": "string",
            "description": "Observation status flag (legend.obs_status decodes it)."
          },
          "best_source": {
            "type": "boolean",
            "description": "Whether this is the preferred source; set only when secondary sources were requested."
          }
        },
        "description": "One observation.",
        "additionalProperties": false
      },
      "description": "Inline preview rows; the staged dataframe holds every row when the result is larger."
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "unknown_dataset",
                "unknown_code",
                "unknown_area_group",
                "aggregates_unavailable",
                "invalid_period",
                "request_too_broad",
                "result_too_large",
                "dataset_retired",
                "upstream_busy",
                "catalog_unavailable"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `unknown_dataset`: Any dataset ID in dataset_ids, queried or not, is not in the catalog, or a bare indicator code has several frequencies. `unknown_code`: A ref_areas, sex, classif1, classif2, or sources value is not in the ILOSTAT dictionaries. `unknown_area_group`: area_group is not X01, an ILO region or subregion, or a World Bank income group. `aggregates_unavailable`: An X-coded aggregate was requested from a dataset that has no aggregate rows. `invalid_period`: A sub-annual time on a dataset of another frequency, time combined with a range or latest_only, or time_from after time_to. `request_too_broad`: No filters at all and the unfiltered size exceeds the row ceiling. `result_too_large`: The filtered result passed the row ceiling while streaming. `dataset_retired`: Upstream reports a catalog dataset ID as deprecated or invalid. `upstream_busy`: The server-side pacer shed the call, or the ILOSTAT API answered 429 or a challenge page. `catalog_unavailable`: No catalog snapshot has loaded and the load failed, or the first load has not finished within 30 s. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "shown": {
      "type": "number",
      "description": "Rows returned inline."
    },
    "legend": {
      "type": "object",
      "required": [
        "ref_area",
        "source",
        "sex",
        "classif1",
        "classif2",
        "obs_status",
        "notes"
      ],
      "properties": {
        "sex": {
          "type": "object",
          "description": "Sex code → label, for every code in rows.",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "string"
          }
        },
        "notes": {
          "type": "object",
          "description": "Note code → label, for every code in rows.",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "string"
          }
        },
        "source": {
          "type": "object",
          "description": "Source code → label, for every code in rows.",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "string"
          }
        },
        "classif1": {
          "type": "object",
          "description": "classif1 code → label, for every code in rows.",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "string"
          }
        },
        "classif2": {
          "type": "object",
          "description": "classif2 code → label, for every code in rows.",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "string"
          }
        },
        "ref_area": {
          "type": "object",
          "description": "Reference area code → label, for every code in rows.",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "string"
          }
        },
        "obs_status": {
          "type": "object",
          "description": "Observation status code → label, for every code in rows.",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "string"
          }
        }
      },
      "description": "Labels for every code in rows.",
      "additionalProperties": false
    },
    "notice": {
      "type": "string",
      "description": "Datasets left for another call, a latest_only fallback to the latest period per area and dataset, filters that could not narrow a dataset, a unit the structure service could not supply, why nothing matched, where the full result is staged, or why reading stopped early."
    },
    "summary": {
      "type": "object",
      "required": [
        "ref_areas",
        "basis_counts",
        "complete"
      ],
      "properties": {
        "complete": {
          "type": "boolean",
          "description": "False when reading stopped early at the inline preview, so the counts cover only the rows read."
        },
        "ref_areas": {
          "type": "number",
          "description": "Distinct reference areas in the rows read."
        },
        "period_max": {
          "type": "string",
          "description": "Latest period; absent on zero rows."
        },
        "period_min": {
          "type": "string",
          "description": "Earliest period; absent on zero rows."
        },
        "basis_counts": {
          "type": "object",
          "required": [
            "reported",
            "modelled_estimate",
            "projection"
          ],
          "properties": {
            "reported": {
              "type": "number",
              "description": "Values from a national or institutional source."
            },
            "projection": {
              "type": "number",
              "description": "ILO modelled values after the cutoff."
            },
            "modelled_estimate": {
              "type": "number",
              "description": "ILO modelled estimates up to the cutoff."
            }
          },
          "description": "Values per basis.",
          "additionalProperties": false
        }
      },
      "description": "Summary over every row read, not just the preview.",
      "additionalProperties": false
    },
    "datasets": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "dataset_id",
          "label",
          "frequency",
          "database",
          "last_update",
          "has_aggregates",
          "projection_after_year",
          "projection_rule"
        ],
        "properties": {
          "unit": {
            "type": "object",
            "required": [
              "measure",
              "type",
              "multiplier"
            ],
            "properties": {
              "type": {
                "type": "string",
                "description": "Unit type code (RT rate, NB number, …)."
              },
              "measure": {
                "type": "string",
                "description": "Unit code (PT percent, PS persons, LC local currency, …)."
              },
              "multiplier": {
                "type": "number",
                "description": "Power of ten values are expressed in: 0 units, 3 thousands, 6 millions."
              },
              "type_label": {
                "type": "string",
                "description": "Unit type label."
              },
              "measure_label": {
                "type": "string",
                "description": "Unit label."
              },
              "multiplier_label": {
                "type": "string",
                "description": "Multiplier label."
              }
            },
            "description": "Unit of the values, already in the multiplier scale; absent when unresolved.",
            "additionalProperties": false
          },
          "label": {
            "type": "string",
            "description": "Dataset label as ILOSTAT publishes it."
          },
          "edition": {
            "type": "string",
            "description": "The edition the cutoff derives from, e.g. Nov. 2025."
          },
          "database": {
            "type": "object",
            "required": [
              "code",
              "label"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Database code."
              },
              "label": {
                "type": "string",
                "description": "Database label."
              }
            },
            "description": "Source database.",
            "additionalProperties": false
          },
          "frequency": {
            "type": "string",
            "description": "A (annual), Q (quarterly), or M (monthly)."
          },
          "dataset_id": {
            "type": "string",
            "description": "Dataset ID."
          },
          "last_update": {
            "type": "string",
            "description": "Last upstream update, ISO 8601 without zone offset."
          },
          "has_aggregates": {
            "type": "boolean",
            "description": "Whether the dataset carries World, regional, or income-group rows."
          },
          "projection_rule": {
            "enum": [
              "edition",
              "catalog_edition",
              "current_year"
            ],
            "type": "string",
            "description": "How the cutoff was set: the label's edition, the catalog's latest ILO modelled estimates edition, or the year before the current year."
          },
          "projection_after_year": {
            "type": "number",
            "description": "Last year counted as an estimate; modelled rows after it are classed projection."
          }
        },
        "description": "One requested dataset and how its values are classed.",
        "additionalProperties": false
      },
      "description": "The queried datasets, in request order."
    },
    "dataframe": {
      "type": "object",
      "required": [
        "name",
        "row_count",
        "expires_at"
      ],
      "properties": {
        "name": {
          "type": "string",
          "description": "Staged dataframe name (df_XXXXX_XXXXX) for ilostat_dataframe_query SQL."
        },
        "evicted": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Dataframes dropped, oldest first, to keep this tenant within 1,000,000 staged rows and 100 dataframes; present only when staging this one evicted any."
        },
        "row_count": {
          "type": "number",
          "description": "Rows staged."
        },
        "expires_at": {
          "type": "string",
          "description": "ISO 8601 expiry of the staged dataframe."
        }
      },
      "description": "The staged dataframe holding the full result; present only when staged.",
      "additionalProperties": false
    },
    "row_count": {
      "type": "number",
      "description": "Rows the request returned — exact unless reading stopped early at the inline preview (summary.complete false), when it counts the rows read."
    },
    "truncated": {
      "type": "boolean",
      "description": "True when reading stopped at the inline preview and more rows exist."
    },
    "attribution": {
      "type": "string",
      "description": "Citation to keep with any use of the data."
    },
    "applied_filters": {
      "type": "object",
      "required": [
        "dataset_ids",
        "latest_only",
        "source_selection",
        "best_source"
      ],
      "properties": {
        "sex": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Sex codes sent."
        },
        "time": {
          "type": "string",
          "description": "Exact period sent."
        },
        "sources": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Source codes sent."
        },
        "time_to": {
          "type": "string",
          "description": "Last year sent."
        },
        "classif1": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "classif1 codes sent."
        },
        "classif2": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "classif2 codes sent."
        },
        "ref_areas": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Reference areas given, normalized."
        },
        "time_from": {
          "type": "string",
          "description": "First year sent."
        },
        "area_group": {
          "type": "object",
          "required": [
            "code",
            "label",
            "member_count"
          ],
          "properties": {
            "code": {
              "type": "string",
              "description": "Area group code."
            },
            "label": {
              "type": "string",
              "description": "Area group label."
            },
            "member_count": {
              "type": "number",
              "description": "Member countries it expanded to."
            }
          },
          "description": "The area group and how many countries it expanded to.",
          "additionalProperties": false
        },
        "best_source": {
          "enum": [
            "yes",
            "all",
            "no"
          ],
          "type": "string",
          "description": "The upstream best_source value sent."
        },
        "dataset_ids": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Datasets queried — at most 3."
        },
        "latest_mode": {
          "enum": [
            "per_series",
            "latest_year"
          ],
          "type": "string",
          "description": "How latest_only was answered: per_series, each series' own latest period; latest_year, the fallback to the latest period per area and dataset, which can miss a series that ends earlier. Absent without latest_only."
        },
        "latest_only": {
          "type": "boolean",
          "description": "Whether only each series' latest period was requested."
        },
        "ref_area_count": {
          "type": "number",
          "description": "Areas sent upstream: ref_areas plus the area_group members."
        },
        "source_selection": {
          "enum": [
            "best",
            "all",
            "secondary"
          ],
          "type": "string",
          "description": "Source selection applied (all when sources were given without one)."
        }
      },
      "description": "Every parameter sent upstream, defaults included.",
      "additionalProperties": false
    },
    "remaining_dataset_ids": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Requested datasets past the first 3, as canonical IDs in request order; not fetched in this call. Pass them as dataset_ids with the same filters to get them. Absent when every requested dataset was queried."
    }
  },
  "additionalProperties": false
}
ilostat_query_indicator annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true
}
ilostat_get_country_profile — Get an ILOSTAT labour-market profile
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Build a headline labour-market profile for one reference area: labour force participation, employment-to-population ratio, unemployment and youth unemployment rates, youth NEET rate, informal employment rate, employment level, labour income share, and working poverty rate. Each indicator shows its latest reported value (from a national or institutional source, with its source and notes) and, separately, its latest ILO modelled estimate that is not a projection, each with its dataset, period, and status — a missing reported value stays missing and is never filled from the model. Accepts a country (ISO3, e.g. KEN) or an X-coded aggregate (X01 World, regions, income groups), for which only modelled values exist.

ilostat_get_country_profile input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "ref_area"
  ],
  "properties": {
    "sex": {
      "enum": [
        "SEX_T",
        "SEX_M",
        "SEX_F"
      ],
      "type": "string",
      "default": "SEX_T",
      "description": "SEX_T (default), SEX_M, or SEX_F; T/M/F and total/both/male/female are accepted. Indicators without a sex breakdown (labour income share) are unaffected."
    },
    "ref_area": {
      "type": "string",
      "pattern": "^[A-Z0-9]{3}$",
      "description": "One reference area with annual data: an ISO3 country code (KEN) or an X-coded aggregate (X01 World, X06, X02); ILO_GEO_ forms accepted, case-insensitive. ilostat_list_reference topic ref_areas lists them."
    }
  },
  "additionalProperties": false
}
ilostat_get_country_profile output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "ref_area",
        "sex",
        "indicators",
        "reported_missing",
        "modelled_cutoff_year",
        "catalog_as_of",
        "attribution"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "sex": {
      "type": "string",
      "description": "Sex code profiled."
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "unknown_area",
                "upstream_busy",
                "catalog_unavailable"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `unknown_area`: ref_area is not an ILOSTAT reference area with annual data. `upstream_busy`: The server-side pacer shed the call, or the ILOSTAT API answered 429 or a challenge page. `catalog_unavailable`: No catalog snapshot has loaded and the load failed, or the first load has not finished within 30 s. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "notice": {
      "type": "string",
      "description": "Which indicators have no reported value, and which of those have an ILO modelled estimate instead."
    },
    "ref_area": {
      "type": "object",
      "required": [
        "code",
        "label",
        "kind"
      ],
      "properties": {
        "code": {
          "type": "string",
          "description": "Reference area code."
        },
        "kind": {
          "enum": [
            "country",
            "aggregate"
          ],
          "type": "string",
          "description": "country or X-coded aggregate."
        },
        "label": {
          "type": "string",
          "description": "Reference area label."
        },
        "region": {
          "type": "object",
          "required": [
            "code",
            "label"
          ],
          "properties": {
            "code": {
              "type": "string",
              "description": "ILO region code (X-coded)."
            },
            "label": {
              "type": "string",
              "description": "ILO region label."
            }
          },
          "description": "ILO region the area belongs to.",
          "additionalProperties": false
        },
        "subregion": {
          "type": "object",
          "required": [
            "code",
            "label"
          ],
          "properties": {
            "code": {
              "type": "string",
              "description": "ILO broad subregion code (X-coded)."
            },
            "label": {
              "type": "string",
              "description": "ILO broad subregion label."
            }
          },
          "description": "ILO broad subregion the area belongs to.",
          "additionalProperties": false
        },
        "income_group": {
          "type": "object",
          "required": [
            "code",
            "label"
          ],
          "properties": {
            "code": {
              "type": "string",
              "description": "World Bank income group code (X-coded)."
            },
            "label": {
              "type": "string",
              "description": "World Bank income group label."
            }
          },
          "description": "World Bank income group the area belongs to.",
          "additionalProperties": false
        }
      },
      "description": "The area profiled.",
      "additionalProperties": false
    },
    "indicators": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "key",
          "label",
          "unit"
        ],
        "properties": {
          "key": {
            "type": "string",
            "description": "Headline key, e.g. unemployment_rate."
          },
          "unit": {
            "type": "string",
            "description": "Unit of both values (% or thousands)."
          },
          "label": {
            "type": "string",
            "description": "Headline label."
          },
          "modelled": {
            "type": "object",
            "required": [
              "dataset_id",
              "period",
              "basis"
            ],
            "properties": {
              "basis": {
                "type": "string",
                "const": "modelled_estimate",
                "description": "Always modelled_estimate: projections are excluded."
              },
              "value": {
                "type": "number",
                "description": "Value; absent when upstream sent none."
              },
              "period": {
                "type": "string",
                "description": "Period of the value."
              },
              "edition": {
                "type": "string",
                "description": "Modelled estimates edition, e.g. Nov. 2025."
              },
              "dataset_id": {
                "type": "string",
                "description": "Modelled dataset the value comes from."
              },
              "obs_status": {
                "type": "string",
                "description": "Observation status flag."
              },
              "obs_status_label": {
                "type": "string",
                "description": "Status flag label."
              }
            },
            "description": "Latest non-projected ILO modelled estimate; absent when none exists.",
            "additionalProperties": false
          },
          "reported": {
            "type": "object",
            "required": [
              "dataset_id",
              "period",
              "source",
              "notes"
            ],
            "properties": {
              "notes": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "code"
                  ],
                  "properties": {
                    "code": {
                      "type": "string",
                      "description": "Note code."
                    },
                    "label": {
                      "type": "string",
                      "description": "Note label."
                    }
                  },
                  "description": "One note attached to the value.",
                  "additionalProperties": false
                },
                "description": "Notes attached to the value."
              },
              "value": {
                "type": "number",
                "description": "Value; absent when upstream sent none."
              },
              "period": {
                "type": "string",
                "description": "Period of the value."
              },
              "source": {
                "type": "string",
                "description": "Source code."
              },
              "dataset_id": {
                "type": "string",
                "description": "Dataset the value comes from."
              },
              "obs_status": {
                "type": "string",
                "description": "Observation status flag."
              },
              "source_label": {
                "type": "string",
                "description": "Source label."
              },
              "obs_status_label": {
                "type": "string",
                "description": "Status flag label."
              }
            },
            "description": "Latest reported value; absent when none exists.",
            "additionalProperties": false
          }
        },
        "description": "One headline indicator.",
        "additionalProperties": false
      },
      "description": "The headline indicators, in a fixed order."
    },
    "attribution": {
      "type": "string",
      "description": "Citation to keep with any use of the data."
    },
    "catalog_as_of": {
      "type": "string",
      "description": "ISO timestamp the catalog was last confirmed current."
    },
    "reported_missing": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Keys with no reported value, including those that have no reported dataset."
    },
    "modelled_cutoff_year": {
      "type": "number",
      "description": "Latest year the modelled values could come from; later modelled years are projections."
    }
  },
  "additionalProperties": false
}
ilostat_get_country_profile annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true
}
ilostat_compare_geographies — Compare areas on an ILOSTAT dataset
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Compare reference areas on one ILOSTAT dataset and one slice — a sex code plus breakdown codes, defaulting to the dataset's totals — giving each area's value at a common period or at its latest non-projected period, optional change over N years, and a rank, with each value's period, source, status, and basis (reported, modelled_estimate, or projection). A change carries the earlier value's source, basis, status, and notes, and flags whether the source or basis differs or the series breaks between the two values. Areas without a value are listed separately with the reason, and the response flags mixed periods and mixed bases rather than hiding them. Select areas by code list, by group (X01 for every country, an ILO region or subregion, or a World Bank income group), or both; X-coded aggregates require a dataset with aggregates.

ilostat_compare_geographies input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "dataset_id"
  ],
  "properties": {
    "sex": {
      "enum": [
        "SEX_T",
        "SEX_M",
        "SEX_F",
        "SEX_O"
      ],
      "type": "string",
      "description": "Sex code SEX_T, SEX_M, SEX_F, or SEX_O; T/M/F/O and total/both/male/female/other are accepted. Defaults to SEX_T on a dataset with a sex breakdown; refused on one without."
    },
    "sort": {
      "enum": [
        "value_desc",
        "value_asc",
        "ref_area"
      ],
      "type": "string",
      "default": "value_desc",
      "description": "Row order: value_desc (default), value_asc, or ref_area. rank is always by value, highest first."
    },
    "period": {
      "type": "string",
      "pattern": "^\\d{4}(Q[1-4]|M(0[1-9]|1[0-2]))?$",
      "description": "A common period, YYYY, YYYYQn, or YYYYMmm matching the dataset frequency (2024-Q2 and 2025-03 are normalized). Omit to compare each area at its latest period."
    },
    "classif1": {
      "type": "string",
      "maxLength": 64,
      "description": "First breakdown code, case-insensitive. Defaults to the dataset's total code; required when the breakdown has no total (deciles); refused on a dataset without the breakdown. ilostat_describe_indicator lists the dataset's codes and marks its totals."
    },
    "classif2": {
      "type": "string",
      "maxLength": 64,
      "description": "Second breakdown code; same defaults and rules as classif1."
    },
    "ref_areas": {
      "type": "array",
      "items": {
        "type": "string",
        "pattern": "^[A-Z0-9]{3}$"
      },
      "maxItems": 300,
      "description": "Reference areas (up to 300): ISO3 codes (USA) or X-coded aggregates (X01 World); case-insensitive, ILO_GEO_ forms accepted. At least one of ref_areas or area_group is required."
    },
    "area_group": {
      "type": "string",
      "pattern": "^[A-Z0-9]{3}$",
      "description": "X01 for every country, an ILO region or subregion, or a World Bank income group (X06, X56, X02, …); expands to its member countries. The group's own aggregate is compared only when listed in ref_areas. ilostat_list_reference topic area_groups lists the codes."
    },
    "dataset_id": {
      "type": "string",
      "pattern": "^[A-Z0-9_]+$",
      "maxLength": 64,
      "description": "One dataset ID (UNE_DEAP_SEX_AGE_RT_A), as ilostat_search_indicators returns it; case-insensitive, a DF_ prefix (the SDMX dataflow form) stripped, a bare indicator code resolved when it has one frequency."
    },
    "change_years": {
      "type": "integer",
      "maximum": 30,
      "minimum": 1,
      "description": "Adds each value's change from the same sub-period this many years earlier, in the dataset unit."
    },
    "lookback_years": {
      "type": "integer",
      "default": 10,
      "maximum": 50,
      "minimum": 1,
      "description": "Latest mode: an area's latest value must fall within this many years of the current year."
    },
    "include_projections": {
      "type": "boolean",
      "default": false,
      "description": "Latest mode: let projections (ILO modelled values after the cutoff) be an area's latest value."
    }
  },
  "additionalProperties": false
}
ilostat_compare_geographies output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "dataset",
        "slice",
        "mode",
        "include_projections",
        "rows",
        "legend",
        "missing",
        "comparability",
        "attribution",
        "applied_filters",
        "truncated",
        "shown",
        "cap"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "cap": {
      "type": "number",
      "description": "Inline preview budget, in serialized characters."
    },
    "mode": {
      "enum": [
        "latest",
        "period"
      ],
      "type": "string",
      "description": "latest: each area's latest value; period: every area at one period."
    },
    "rows": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "rank",
          "ref_area",
          "kind",
          "value",
          "period",
          "basis",
          "source",
          "notes"
        ],
        "properties": {
          "kind": {
            "enum": [
              "country",
              "aggregate"
            ],
            "type": "string",
            "description": "country or X-coded aggregate."
          },
          "rank": {
            "type": "number",
            "description": "Rank by value, highest first; ties share a rank."
          },
          "basis": {
            "enum": [
              "reported",
              "modelled_estimate",
              "projection"
            ],
            "type": "string",
            "description": "reported, modelled_estimate, or projection."
          },
          "label": {
            "type": "string",
            "description": "Reference area label."
          },
          "notes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Note codes (legend.notes decodes them)."
          },
          "value": {
            "type": "number",
            "description": "Value in the dataset unit."
          },
          "change": {
            "type": "object",
            "required": [
              "from_period",
              "from_value",
              "delta",
              "from_source",
              "from_basis",
              "from_notes",
              "source_changed",
              "basis_changed",
              "break_in_series"
            ],
            "properties": {
              "delta": {
                "type": "number",
                "description": "value − from_value, in the dataset unit."
              },
              "from_basis": {
                "enum": [
                  "reported",
                  "modelled_estimate",
                  "projection"
                ],
                "type": "string",
                "description": "Basis of the earlier value: reported, modelled_estimate, or projection."
              },
              "from_notes": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Note codes of the earlier value (legend.notes decodes them)."
              },
              "from_value": {
                "type": "number",
                "description": "The value at the earlier period."
              },
              "from_period": {
                "type": "string",
                "description": "The earlier period."
              },
              "from_source": {
                "type": "string",
                "description": "Source code of the earlier value."
              },
              "basis_changed": {
                "type": "boolean",
                "description": "True when the earlier value has another basis."
              },
              "source_changed": {
                "type": "boolean",
                "description": "True when the earlier value comes from another source."
              },
              "break_in_series": {
                "type": [
                  "boolean",
                  "null"
                ],
                "description": "True when a break in series (status B or an I11 note) is marked on the value or on an observation of its source after from_period: the series' method changed within the span. A break marked on the earlier value alone came before the span and does not count. null when only the two periods were read (notice says so) and the value marks no break: a break between them is unknown."
              },
              "from_obs_status": {
                "type": "string",
                "description": "Status flag of the earlier value (legend.obs_status decodes it)."
              },
              "from_source_label": {
                "type": "string",
                "description": "Source label of the earlier value."
              }
            },
            "description": "Change over change_years with the earlier value's provenance; absent when the earlier value is missing. delta is like-for-like only when source_changed, basis_changed, and break_in_series are all false.",
            "additionalProperties": false
          },
          "period": {
            "type": "string",
            "description": "Period of the value."
          },
          "source": {
            "type": "string",
            "description": "Source code."
          },
          "ref_area": {
            "type": "string",
            "description": "Reference area code."
          },
          "obs_status": {
            "type": "string",
            "description": "Observation status flag (legend.obs_status decodes it)."
          },
          "source_label": {
            "type": "string",
            "description": "Source label."
          }
        },
        "description": "One area with a value.",
        "additionalProperties": false
      },
      "description": "Areas with a value, in the requested order; the staged dataframe holds all when larger."
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "unknown_dataset",
                "unknown_code",
                "unknown_area_group",
                "areas_required",
                "aggregates_unavailable",
                "invalid_slice",
                "invalid_period",
                "dataset_retired",
                "structure_unavailable",
                "upstream_busy",
                "catalog_unavailable"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `unknown_dataset`: dataset_id is not in the catalog, or a bare indicator code has several frequencies. `unknown_code`: A ref_areas, sex, classif1, or classif2 value is not in the ILOSTAT dictionaries. `unknown_area_group`: area_group is not X01, an ILO region or subregion, or a World Bank income group. `areas_required`: Neither ref_areas nor area_group was given. `aggregates_unavailable`: An X-coded aggregate was requested from a dataset that has no aggregate rows. `invalid_slice`: A breakdown has no total code and no value was given, or sex/classif1/classif2 names a breakdown the dataset lacks. `invalid_period`: period is of a frequency other than the dataset's. `dataset_retired`: Upstream reports a catalog dataset ID as deprecated or invalid. `structure_unavailable`: classif1 or classif2 was left to its default and the ILOSTAT structure service could not supply the dataset total codes. `upstream_busy`: The server-side pacer shed the call, or the ILOSTAT API answered 429 or a challenge page. `catalog_unavailable`: No catalog snapshot has loaded and the load failed, or the first load has not finished within 30 s. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "shown": {
      "type": "number",
      "description": "Rows returned inline."
    },
    "slice": {
      "type": "object",
      "required": [
        "defaulted"
      ],
      "properties": {
        "sex": {
          "type": "string",
          "description": "Sex code compared."
        },
        "classif1": {
          "type": "string",
          "description": "classif1 code compared."
        },
        "classif2": {
          "type": "string",
          "description": "classif2 code compared."
        },
        "defaulted": {
          "type": "array",
          "items": {
            "enum": [
              "sex",
              "classif1",
              "classif2"
            ],
            "type": "string"
          },
          "description": "Which slice codes were filled from the dataset's totals."
        }
      },
      "description": "The one series compared per area.",
      "additionalProperties": false
    },
    "legend": {
      "type": "object",
      "required": [
        "obs_status",
        "notes"
      ],
      "properties": {
        "notes": {
          "type": "object",
          "description": "Note code → label, for every note code in rows.",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "string"
          }
        },
        "obs_status": {
          "type": "object",
          "description": "Observation status code → label, for every status flag in rows.",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "string"
          }
        }
      },
      "description": "Labels for the status flags and note codes in rows.",
      "additionalProperties": false
    },
    "notice": {
      "type": "string",
      "description": "Mixed periods, mixed bases, changes that are not like-for-like, missing areas, a unit or area list the structure service could not supply, where the full comparison is staged, or why the inline rows stop early."
    },
    "period": {
      "type": "string",
      "description": "Period mode: the period compared."
    },
    "dataset": {
      "type": "object",
      "required": [
        "dataset_id",
        "label",
        "frequency",
        "database",
        "last_update",
        "has_aggregates",
        "projection_after_year",
        "projection_rule"
      ],
      "properties": {
        "unit": {
          "type": "object",
          "required": [
            "measure",
            "type",
            "multiplier"
          ],
          "properties": {
            "type": {
              "type": "string",
              "description": "Unit type code (RT rate, NB number, …)."
            },
            "measure": {
              "type": "string",
              "description": "Unit code (PT percent, PS persons, LC local currency, …)."
            },
            "multiplier": {
              "type": "number",
              "description": "Power of ten values are expressed in: 0 units, 3 thousands, 6 millions."
            },
            "type_label": {
              "type": "string",
              "description": "Unit type label."
            },
            "measure_label": {
              "type": "string",
              "description": "Unit label."
            },
            "multiplier_label": {
              "type": "string",
              "description": "Multiplier label."
            }
          },
          "description": "Unit of the values, already in the multiplier scale; absent when unresolved.",
          "additionalProperties": false
        },
        "label": {
          "type": "string",
          "description": "Dataset label as ILOSTAT publishes it."
        },
        "edition": {
          "type": "string",
          "description": "The edition the cutoff derives from, e.g. Nov. 2025."
        },
        "database": {
          "type": "object",
          "required": [
            "code",
            "label"
          ],
          "properties": {
            "code": {
              "type": "string",
              "description": "Database code."
            },
            "label": {
              "type": "string",
              "description": "Database label."
            }
          },
          "description": "Source database.",
          "additionalProperties": false
        },
        "frequency": {
          "type": "string",
          "description": "A (annual), Q (quarterly), or M (monthly)."
        },
        "dataset_id": {
          "type": "string",
          "description": "Dataset ID."
        },
        "last_update": {
          "type": "string",
          "description": "Last upstream update, ISO 8601 without zone offset."
        },
        "has_aggregates": {
          "type": "boolean",
          "description": "Whether the dataset carries World, regional, or income-group rows."
        },
        "projection_rule": {
          "enum": [
            "edition",
            "catalog_edition",
            "current_year"
          ],
          "type": "string",
          "description": "How the cutoff was set: the label's edition, the catalog's latest ILO modelled estimates edition, or the year before the current year."
        },
        "projection_after_year": {
          "type": "number",
          "description": "Last year counted as an estimate; modelled rows after it are classed projection."
        }
      },
      "description": "One requested dataset and how its values are classed.",
      "additionalProperties": false
    },
    "missing": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "ref_area",
          "reason"
        ],
        "properties": {
          "label": {
            "type": "string",
            "description": "Reference area label."
          },
          "reason": {
            "enum": [
              "no_value_in_window",
              "no_value_for_period",
              "not_covered"
            ],
            "type": "string",
            "description": "no_value_in_window (latest mode), no_value_for_period (period mode), or not_covered (absent from the dataset's area list; never given when that list is unavailable, which notice says)."
          },
          "ref_area": {
            "type": "string",
            "description": "Reference area code."
          }
        },
        "description": "One area without a value.",
        "additionalProperties": false
      },
      "description": "Requested areas with no value, and why."
    },
    "dataframe": {
      "type": "object",
      "required": [
        "name",
        "row_count",
        "expires_at"
      ],
      "properties": {
        "name": {
          "type": "string",
          "description": "Staged dataframe name (df_XXXXX_XXXXX) for ilostat_dataframe_query SQL."
        },
        "evicted": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Dataframes dropped, oldest first, to keep this tenant within 1,000,000 staged rows and 100 dataframes; present only when staging this one evicted any."
        },
        "row_count": {
          "type": "number",
          "description": "Rows staged."
        },
        "expires_at": {
          "type": "string",
          "description": "ISO 8601 expiry of the staged dataframe."
        }
      },
      "description": "The staged dataframe holding the full result; present only when staged.",
      "additionalProperties": false
    },
    "truncated": {
      "type": "boolean",
      "description": "True when the inline rows stop before the last area — also when a dataframe holds the full comparison."
    },
    "attribution": {
      "type": "string",
      "description": "Citation to keep with any use of the data."
    },
    "window_from": {
      "type": "number",
      "description": "Latest mode: the first year requested — lookback_years before the current year, and change_years further back to reach the change base. A latest value still falls within lookback_years."
    },
    "change_years": {
      "type": "number",
      "description": "Years the change is measured over, when requested."
    },
    "comparability": {
      "type": "object",
      "required": [
        "periods",
        "mixed_periods",
        "basis_counts",
        "distinct_sources"
      ],
      "properties": {
        "periods": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Distinct periods of the values, newest first."
        },
        "basis_counts": {
          "type": "object",
          "required": [
            "reported",
            "modelled_estimate",
            "projection"
          ],
          "properties": {
            "reported": {
              "type": "number",
              "description": "Values from a national or institutional source."
            },
            "projection": {
              "type": "number",
              "description": "ILO modelled values after the cutoff."
            },
            "modelled_estimate": {
              "type": "number",
              "description": "ILO modelled estimates up to the cutoff."
            }
          },
          "description": "Values per basis.",
          "additionalProperties": false
        },
        "mixed_periods": {
          "type": "boolean",
          "description": "True when the values span more than one period."
        },
        "distinct_sources": {
          "type": "number",
          "description": "Distinct sources behind the values."
        }
      },
      "description": "What makes the current values more or less comparable, over every area; each change's baseline is compared by its own source_changed, basis_changed, and break_in_series.",
      "additionalProperties": false
    },
    "applied_filters": {
      "type": "object",
      "required": [
        "dataset_id",
        "ref_area_count",
        "best_source"
      ],
      "properties": {
        "sex": {
          "type": "string",
          "description": "Sex code sent."
        },
        "time": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Exact periods sent: period mode without change_years, or the period and its change base when the years between could not be read within the call's size and time limits."
        },
        "time_to": {
          "type": "number",
          "description": "Last year sent: the period's year, in period mode with change_years."
        },
        "classif1": {
          "type": "string",
          "description": "classif1 code sent."
        },
        "classif2": {
          "type": "string",
          "description": "classif2 code sent."
        },
        "ref_areas": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Reference areas given, normalized."
        },
        "time_from": {
          "type": "number",
          "description": "First year sent: latest mode's window start (no end year is sent), or period mode's change base year."
        },
        "area_group": {
          "type": "object",
          "required": [
            "code",
            "label",
            "member_count"
          ],
          "properties": {
            "code": {
              "type": "string",
              "description": "Area group code."
            },
            "label": {
              "type": "string",
              "description": "Area group label."
            },
            "member_count": {
              "type": "number",
              "description": "Member countries it expanded to."
            }
          },
          "description": "The area group and how many countries it expanded to.",
          "additionalProperties": false
        },
        "dataset_id": {
          "type": "string",
          "description": "Dataset compared."
        },
        "best_source": {
          "type": "string",
          "const": "upstream default (yes)",
          "description": "best_source is never sent, so upstream returns the preferred source."
        },
        "ref_area_count": {
          "type": "number",
          "description": "Areas compared: ref_areas plus the area_group members."
        }
      },
      "description": "Every parameter sent upstream.",
      "additionalProperties": false
    },
    "include_projections": {
      "type": "boolean",
      "description": "Whether a projection could be an area's latest value."
    }
  },
  "additionalProperties": false
}
ilostat_compare_geographies annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true
}
ilostat_list_reference — List ILOSTAT reference codes
Advertised by the server during the last successful anonymous check.
Advertised read-only

Decode ILOSTAT's code vocabulary: reference areas (ISO3 countries and X-coded aggregates, with World Bank income group and ILO region), the groups that area_group accepts (X01 for every country, ILO regions and subregions, World Bank income groups; exact-code lookups list their member countries), databases, subjects, sex codes, breakdown codes for classif1/classif2 with their classification types, per-country data sources, observation status flags, note codes, and frequencies. Filter by text or look up exact codes; long topics page with a cursor. These are ILOSTAT-wide vocabularies; ilostat_describe_indicator lists the sex and breakdown codes one dataset actually uses.

ilostat_list_reference input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "topic"
  ],
  "properties": {
    "codes": {
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 64
      },
      "maxItems": 100,
      "description": "Exact codes to look up (up to 100; case-insensitive, and ILO_GEO_ forms accepted for ref_areas and area_groups). Codes the topic lacks are listed in not_found. With topic area_groups, each group found also lists its member countries."
    },
    "limit": {
      "type": "integer",
      "default": 50,
      "maximum": 10000,
      "minimum": 1,
      "description": "Entries per page, at most 500; a larger value, up to 10,000, is applied as 500 and the notice says so."
    },
    "topic": {
      "enum": [
        "ref_areas",
        "area_groups",
        "databases",
        "subjects",
        "sexes",
        "classifications",
        "classification_types",
        "sources",
        "obs_status",
        "notes",
        "frequencies"
      ],
      "type": "string",
      "description": "Vocabulary to list: ref_areas, area_groups (the X codes area_group accepts), databases, subjects, sexes, classifications (classif1/classif2 codes), classification_types, sources, obs_status, notes, or frequencies."
    },
    "cursor": {
      "type": "string",
      "maxLength": 256,
      "description": "Opaque continuation token: the previous page's next_cursor, passed unchanged."
    },
    "filter": {
      "type": "string",
      "maxLength": 200,
      "description": "Text filter: every word must match a word or word prefix of the code or label (case, accents, and punctuation ignored; labor matches labour). Omit to list the whole topic."
    },
    "ref_area": {
      "type": "string",
      "pattern": "^[A-Z0-9]{3}$",
      "description": "Topic sources only: list the sources of this reference area (ISO3 or X code; case-insensitive, ILO_GEO_ forms accepted)."
    },
    "classification_type": {
      "type": "string",
      "maxLength": 32,
      "description": "Topic classifications only: keep codes of this classification type, the code prefix (AGE, ECO, EDU, …)."
    }
  },
  "additionalProperties": false
}
ilostat_list_reference output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "topic",
        "entries",
        "total",
        "catalog_as_of",
        "truncated",
        "shown",
        "cap"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "cap": {
      "type": "number",
      "description": "The limit applied to this page."
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "unknown_code",
                "param_not_for_topic",
                "invalid_cursor",
                "catalog_unavailable"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `unknown_code`: ref_area is not an ILOSTAT reference area. `param_not_for_topic`: ref_area with a topic other than sources, or classification_type with a topic other than classifications. `invalid_cursor`: cursor does not decode. `catalog_unavailable`: No catalog snapshot has loaded and the load failed, or the first load has not finished within 30 s. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "shown": {
      "type": "number",
      "description": "Entries returned on this page."
    },
    "topic": {
      "enum": [
        "ref_areas",
        "area_groups",
        "databases",
        "subjects",
        "sexes",
        "classifications",
        "classification_types",
        "sources",
        "obs_status",
        "notes",
        "frequencies"
      ],
      "type": "string",
      "description": "The topic listed."
    },
    "total": {
      "type": "number",
      "description": "Entries matching the filters, across all pages."
    },
    "notice": {
      "type": "string",
      "description": "That a limit past the page cap was applied as the cap, why a filter with no searchable word was not applied, why nothing matched, that the cursor starts past the last entry, and how to reach the remaining pages — whichever apply, joined."
    },
    "entries": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "code",
          "label"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "The code other ILOSTAT tools take."
          },
          "kind": {
            "enum": [
              "country",
              "aggregate"
            ],
            "type": "string",
            "description": "ref_areas: country, or an X-coded aggregate (World, region, income group)."
          },
          "slot": {
            "enum": [
              "classif1",
              "classif2",
              "both"
            ],
            "type": "string",
            "description": "classifications: the query parameter slot the code is used in."
          },
          "label": {
            "type": "string",
            "description": "English label published by ILOSTAT."
          },
          "members": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "code"
              ],
              "properties": {
                "code": {
                  "type": "string",
                  "description": "ISO3 code of the member country."
                },
                "label": {
                  "type": "string",
                  "description": "Country name published by ILOSTAT."
                }
              },
              "description": "One member country.",
              "additionalProperties": false
            },
            "description": "area_groups looked up by exact codes only: the member countries, by code. A listing without codes gives member_count alone."
          },
          "data_end": {
            "type": "number",
            "description": "ref_areas: last year with data, any frequency."
          },
          "ref_area": {
            "type": "string",
            "description": "sources: the reference area the source belongs to."
          },
          "note_type": {
            "type": "string",
            "description": "notes: note_source, note_indicator, or note_classif."
          },
          "data_start": {
            "type": "number",
            "description": "ref_areas: first year with data, any frequency."
          },
          "ilo_region": {
            "type": "string",
            "description": "ref_areas: ILO region, as its X code."
          },
          "frequencies": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "ref_areas: frequencies with data for the area (A annual, Q quarterly, M monthly)."
          },
          "group_types": {
            "type": "array",
            "items": {
              "enum": [
                "world",
                "region",
                "subregion_broad",
                "subregion_detailed",
                "income_group"
              ],
              "type": "string"
            },
            "description": "area_groups: which grouping levels use the code (world is X01, every country); one code can serve several."
          },
          "source_type": {
            "type": "string",
            "description": "sources: the label prefix before \" - \" (LFS, PC, ADM, ILO, OE, …)."
          },
          "income_group": {
            "type": "string",
            "description": "ref_areas: World Bank income group, as its X code."
          },
          "member_count": {
            "type": "number",
            "description": "area_groups: member countries."
          },
          "dataset_count": {
            "type": "number",
            "description": "Datasets using the code: per database, subject, or frequency; for ref_areas, datasets with data for the area summed over frequencies."
          },
          "ilo_region_label": {
            "type": "string",
            "description": "ref_areas: ILO region label."
          },
          "income_group_label": {
            "type": "string",
            "description": "ref_areas: income group label."
          },
          "classification_type": {
            "type": "string",
            "description": "classifications: the code prefix naming its classification type (AGE, ECO, …)."
          },
          "ilo_subregion_broad": {
            "type": "string",
            "description": "ref_areas: broad ILO subregion, as its X code."
          },
          "ilo_subregion_detailed": {
            "type": "string",
            "description": "ref_areas: detailed ILO subregion, as its X code."
          },
          "ilo_subregion_broad_label": {
            "type": "string",
            "description": "ref_areas: broad ILO subregion label."
          },
          "ilo_subregion_detailed_label": {
            "type": "string",
            "description": "ref_areas: detailed ILO subregion label."
          }
        },
        "description": "One decoded code; fields beyond code and label depend on the topic.",
        "additionalProperties": false
      },
      "description": "This page of decoded codes, ordered by code — except sexes, which keep the ILOSTAT dictionary's order (SEX_T first), and frequencies, listed annual, quarterly, monthly."
    },
    "not_found": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Requested codes the topic does not contain; present only when codes missed."
    },
    "truncated": {
      "type": "boolean",
      "description": "True when more entries remain beyond this page."
    },
    "next_cursor": {
      "type": "string",
      "description": "Pass as cursor to get the next page; absent on the last page."
    },
    "catalog_as_of": {
      "type": "string",
      "description": "ISO timestamp the in-memory catalog was last confirmed current."
    }
  },
  "additionalProperties": false
}
ilostat_list_reference annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true
}
ilostat_dataframe_query — Query staged ILOSTAT dataframes
Advertised by the server during the last successful anonymous check.
Advertised read-only

Run a single-statement SELECT against the df_<id> dataframes staged by ilostat_query_indicator and ilostat_compare_geographies or stored by an earlier register_as. Inspect a dataframe with ilostat_dataframe_describe first; its column schema is what the SQL has to match. Read-only: writes, DDL, DROP, COPY, PRAGMA, ATTACH, file references, file-reading table functions, and functions that read engine settings or name a table from a string are rejected, and system catalogs (information_schema, pg_catalog, sqlite_master, duckdb_*) are denied. Breakdown versions overlap (AGE_YTHADULT_*, AGE_AGGREGATE_*, AGE_10YRBANDS_*, AGE_5YRBANDS_*; ECO_SECTOR_*, ECO_AGGREGATE_*, ECO_ISIC4_*, ECO_ISIC3_*), so filter to one version before summing. Optional register_as stores the result as a new dataframe with a fresh TTL.

ilostat_dataframe_query input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "sql"
  ],
  "properties": {
    "sql": {
      "type": "string",
      "maxLength": 20000,
      "minLength": 1,
      "description": "One SELECT over df_<id> tables (DuckDB SQL: joins, aggregates, window functions, CTEs), at most 20,000 characters. BIGINT results such as COUNT or SUM of integers serialize as strings; CAST to DOUBLE for inline arithmetic."
    },
    "preview": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 0,
      "description": "Rows returned inline; defaults to row_limit, and a larger value is applied as row_limit. Inline rows also stop at a size budget (applied_limits.preview_chars). Set lower when register_as keeps the full result."
    },
    "row_limit": {
      "type": "integer",
      "maximum": 1000000,
      "minimum": 1,
      "description": "Cap on rows materialized; defaults to 1,000, or the per-call cap when that is lower. The per-call cap is 10,000, or the lower cap the deployment sets; a larger value, up to 1,000,000, is applied as that cap. A query matching more stops at the cap and row_count_capped is true; register_as keeps the full result."
    },
    "register_as": {
      "type": "string",
      "pattern": "^df_[A-Z0-9]{5}_[A-Z0-9]{5}$",
      "description": "Store the result as a new dataframe under this name (df_XXXXX_XXXXX: letters and digits, five in each part; stored uppercased after df_) with a fresh TTL, to chain analyses. A result over 1,000,000 rows is refused, and storing one can evict the oldest dataframes, which evicted names."
    }
  },
  "additionalProperties": false
}
ilostat_dataframe_query output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "columns",
        "row_count",
        "row_count_capped",
        "rows",
        "truncated",
        "shown",
        "cap"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "cap": {
      "type": "number",
      "description": "The row cap that bound: preview when lower than row_limit, else row_limit."
    },
    "rows": {
      "type": "array",
      "items": {
        "type": "object",
        "propertyNames": {
          "type": "string"
        },
        "additionalProperties": {}
      },
      "description": "Result rows keyed by the names in columns, bounded by preview, row_limit, and an inline size budget; rows stop before the first that would pass the budget, and a value is never clipped. BIGINT values arrive as strings."
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "canvas_unavailable",
                "system_catalog_access",
                "missing_table",
                "invalid_sql",
                "sql_execution_error",
                "register_as_clash",
                "register_as_too_large",
                "non_select_statement",
                "multi_statement",
                "denied_function",
                "sql_read_only",
                "plan_operator_not_allowed"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `canvas_unavailable`: The DataCanvas DuckDB engine cannot load in this deployment. `system_catalog_access`: The SQL references a system catalog. `missing_table`: A referenced df_<id> does not exist or has expired. `invalid_sql`: The SELECT fails to prepare: an unknown column or an invalid expression. `sql_execution_error`: The SELECT prepared but failed on the data. `register_as_clash`: register_as names an existing dataframe. `register_as_too_large`: The register_as result holds more than 1,000,000 rows. `non_select_statement`: The SQL is not a SELECT. `multi_statement`: The SQL holds more than one statement, or a PIVOT with no IN list, which DuckDB expands into several. `denied_function`: The SQL calls a file-reading or external table function, a function that reads engine settings (current_setting, current_schema, which an unqualified column of that name also reads as), or one that runs SQL or names a table from a string (query_table, query() over anything but one string literal, query() nested more than 4 deep). `sql_read_only`: The SQL names a file in place of a table, or attempts a write the engine refuses. `plan_operator_not_allowed`: The plan uses an operator outside the read-only allowlist, such as range(). Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "shown": {
      "type": "number",
      "description": "Rows returned inline."
    },
    "notice": {
      "type": "string",
      "description": "Guidance when the query returned no rows, a cap withheld some, or a limit was applied below the value sent."
    },
    "columns": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Column names in projection order."
    },
    "evicted": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Dataframes dropped, oldest first, to keep this tenant within 1,000,000 staged rows and 100 dataframes; present only when storing the result evicted any."
    },
    "row_count": {
      "type": "number",
      "description": "Rows the query produced. With register_as this is the exact count of the stored dataframe, which row_limit does not bound; otherwise at most row_limit, and when row_count_capped is true it is the cap, not a total."
    },
    "truncated": {
      "type": "boolean",
      "description": "True when a cap withheld rows from this response."
    },
    "expires_at": {
      "type": "string",
      "description": "ISO 8601 expiry of the new dataframe."
    },
    "registered_as": {
      "type": "string",
      "description": "The new dataframe name, when register_as stored the result."
    },
    "applied_limits": {
      "type": "object",
      "required": [
        "row_limit",
        "preview",
        "preview_chars"
      ],
      "properties": {
        "preview": {
          "type": "number",
          "description": "Inline rows applied: preview, at most the applied row_limit."
        },
        "row_limit": {
          "type": "number",
          "description": "Row cap applied: row_limit (default 1,000), or the per-call cap when that is lower. With register_as it bounds the inline rows, never the stored result."
        },
        "preview_chars": {
          "type": "number",
          "description": "Inline size budget applied, in characters; rows stop before the first that would pass it."
        }
      },
      "description": "The limits this call ran under, after any clamp.",
      "additionalProperties": false
    },
    "row_count_capped": {
      "type": "boolean",
      "description": "True when the query matched more rows than row_limit; never true with register_as, which stores every row."
    }
  },
  "additionalProperties": false
}
ilostat_dataframe_query annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true
}
ilostat_dataframe_describe — Describe staged ILOSTAT dataframes
Advertised by the server during the last successful anonymous check.
Advertised read-only

Describe the df_<id> dataframes staged by ilostat_query_indicator and ilostat_compare_geographies or stored by ilostat_dataframe_query register_as: the tool and parameters that produced each, the datasets it holds (label, last update, and the unit with its measure, type, and multiplier — values stay in the published scale the multiplier names), coverage, basis counts, attribution, creation and expiry times, row count, and column schema. Pass name for one dataframe. Without it, every staged dataframe is listed, except on a deployment whose callers share one canvas, where listing is off and only the exact name works. Read the schema here before writing SQL for ilostat_dataframe_query.

ilostat_dataframe_describe input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "name": {
      "type": "string",
      "pattern": "^df_[A-Z0-9]{5}_[A-Z0-9]{5}$",
      "description": "One dataframe name as the producing tool returned it (df_XXXXX_XXXXX: letters and digits, five in each part; case-insensitive, as in SQL). Omit to list every staged dataframe; a deployment whose callers share one canvas refuses the listing and needs the name."
    }
  },
  "additionalProperties": false
}
ilostat_dataframe_describe output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "dataframes"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "canvas_unavailable",
                "listing_unavailable"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `canvas_unavailable`: The DataCanvas DuckDB engine cannot load in this deployment. `listing_unavailable`: name is omitted where every caller shares one canvas (HTTP with auth none). Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "notice": {
      "type": "string",
      "description": "Guidance when the named dataframe does not exist."
    },
    "dataframes": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "name",
          "source_tool",
          "query_params",
          "created_at",
          "expires_at",
          "row_count",
          "datasets",
          "attribution",
          "column_schema"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Dataframe name, the table to use in SQL."
          },
          "coverage": {
            "type": "object",
            "required": [
              "ref_areas"
            ],
            "properties": {
              "ref_areas": {
                "type": "number",
                "description": "Distinct reference areas."
              },
              "period_max": {
                "type": "string",
                "description": "Latest period."
              },
              "period_min": {
                "type": "string",
                "description": "Earliest period."
              }
            },
            "description": "Areas and periods covered; absent for a dataframe derived by SQL.",
            "additionalProperties": false
          },
          "datasets": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "dataset_id",
                "label",
                "last_update"
              ],
              "properties": {
                "unit": {
                  "type": "string",
                  "description": "Unit label (its code when unlabelled), when resolved."
                },
                "label": {
                  "type": "string",
                  "description": "Dataset label."
                },
                "unit_type": {
                  "type": "string",
                  "description": "Unit type code (RT rate, NB number, …), when resolved."
                },
                "dataset_id": {
                  "type": "string",
                  "description": "Dataset ID."
                },
                "last_update": {
                  "type": "string",
                  "description": "Last upstream update of the dataset."
                },
                "unit_measure": {
                  "type": "string",
                  "description": "Unit code (PT percent, PS persons, …), when resolved."
                },
                "unit_multiplier": {
                  "type": "number",
                  "description": "Power of ten the values are published in (0 units, 3 thousands, 6 millions), as in the staged unit_multiplier column; values are never rescaled. Absent when the unit did not resolve."
                },
                "unit_type_label": {
                  "type": "string",
                  "description": "Unit type label."
                },
                "unit_multiplier_label": {
                  "type": "string",
                  "description": "Multiplier label."
                }
              },
              "description": "One dataset the dataframe holds.",
              "additionalProperties": false
            },
            "description": "Datasets the rows come from."
          },
          "row_count": {
            "type": "number",
            "description": "Rows staged."
          },
          "created_at": {
            "type": "string",
            "description": "ISO 8601 creation time."
          },
          "expires_at": {
            "type": "string",
            "description": "ISO 8601 expiry."
          },
          "attribution": {
            "type": "string",
            "description": "Citation to keep with any use of the data."
          },
          "source_tool": {
            "type": "string",
            "description": "Tool that produced it."
          },
          "basis_counts": {
            "type": "object",
            "required": [
              "reported",
              "modelled_estimate",
              "projection"
            ],
            "properties": {
              "reported": {
                "type": "number",
                "description": "Values from a national or institutional source."
              },
              "projection": {
                "type": "number",
                "description": "ILO modelled values after the cutoff."
              },
              "modelled_estimate": {
                "type": "number",
                "description": "ILO modelled estimates up to the cutoff."
              }
            },
            "description": "Rows per basis; absent for a dataframe derived by SQL.",
            "additionalProperties": false
          },
          "query_params": {
            "type": "object",
            "description": "How the dataframe was produced: the producing tool's applied_filters, or {sql, derived_from} for a dataframe stored by ilostat_dataframe_query register_as.",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {}
          },
          "column_schema": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "name",
                "type",
                "nullable"
              ],
              "properties": {
                "name": {
                  "type": "string",
                  "description": "Column name."
                },
                "type": {
                  "type": "string",
                  "description": "Column type (VARCHAR, INTEGER, DOUBLE, BOOLEAN, …)."
                },
                "nullable": {
                  "type": "boolean",
                  "description": "Whether the column permits NULL."
                }
              },
              "description": "One column.",
              "additionalProperties": false
            },
            "description": "Columns the SQL can reference."
          }
        },
        "description": "One staged dataframe.",
        "additionalProperties": false
      },
      "description": "Staged dataframes, newest first; empty when none."
    }
  },
  "additionalProperties": false
}
ilostat_dataframe_describe annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true
}

Prompts

0 advertised

No prompt definitions available.

Resources

1 advertised

ilostat-guide

Advertised by the server during the last successful anonymous check.

Gates for answering labour-market questions with the ilostat_* tools of ilostat-mcp-server — choosing reported vs ILO modelled data, finding youth, women, a sector, or a currency as a breakdown code, one classification version per sum, rates that do not add, mixed definitions, source changes and breaks in trends, and SQL over staged df_ dataframes. Use before comparing countries, building a trend, or aggregating ILOSTAT values.

ilostat-guide URI
skill://ilostat-guide/SKILL.md

MIME type: text/markdown

io.modelcontextprotocol/skills

Advertised by the server during the last successful anonymous check.

io.modelcontextprotocol/skills URI template
skill://{+path}

90-day uptime

A lightweight connection check about every six hours, sampled on hosts with many listings. It shows the server answered, not that its tools work.

Too few checks for a percentage yet (1 of 1 answered).

  1. 2026-11-07: 1 of 1 checks answered

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
680 ms
95th percentile latency
680 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 680 ms · metadata changed · 8 tool(s), 1 resource(s), 1 resource template(s), 0 prompt(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http ilostat-mcp-server-caseyjhand https://ilostat.caseyjhand.com/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add ilostat-mcp-server-caseyjhand --url https://ilostat.caseyjhand.com/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable ilostat-mcp-server-caseyjhand in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "ilostat-mcp-server-caseyjhand": {
      "url": "https://ilostat.caseyjhand.com/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "ilostat-mcp-server-caseyjhand": {
      "type": "streamableHttp",
      "url": "https://ilostat.caseyjhand.com/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start ilostat-mcp-server-caseyjhand and inspect its tools.
VS Code configuration
{
  "servers": {
    "ilostat-mcp-server-caseyjhand": {
      "type": "http",
      "url": "https://ilostat.caseyjhand.com/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http ilostat-mcp-server-caseyjhand https://ilostat.caseyjhand.com/mcp

Claude Desktop

Open Claude Settings > Connectors > Add custom connector, enter this server URL and enable it for the conversation. This is a manual remote-connector handoff, not a desktop JSON configuration.
Claude Desktop configuration
https://ilostat.caseyjhand.com/mcp

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "ilostat-mcp-server-caseyjhand": {
      "serverUrl": "https://ilostat.caseyjhand.com/mcp"
    }
  }
}

Let your agent find its tools

Find servers like ilostat-mcp-server from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.