eurostat-mcp-server
Server Details
Search and query the Eurostat catalogue — EU economy, demography, trade, and NUTS regional data.
- Status
- Healthy
- Uptime
- 99.9% over 41 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- cyanheads/eurostat-mcp-server
- GitHub Stars
- 7
- Server Listing
- eurostat-mcp-server
TDQS
Scored across 8 tools
Each tool has a distinct role: browse for navigation, search for discovery, get_info and get_dimension_values for metadata, query and download for data retrieval (differentiated by slice vs bulk), and dataframe_describe/query for post-staging analysis. No two tools overlap in purpose; even the similar query/download pair is clearly separated by intent and endpoint.
All tools follow the same pattern: eurostat_ + verb + noun, using snake_case consistently. Verbs are descriptive (browse, search, get, query, download, describe) and nouns are clear (themes, datasets, info, dimension_values, dataframe). No mixed conventions or vague names.
Eight tools is well within the ideal range (3-15) for a data-access server. Each tool serves a necessary step in the workflow: discovery, metadata exploration, data fetching (two complementary methods), and SQL-based analysis. No redundant or missing tools that would bloat or thin the surface.
The set covers the full lifecycle: discover (browse, search), inspect metadata (get_info, get_dimension_values), retrieve data (query for slices, download for bulk), and analyze/query staged tables (dataframe_describe/query). It also handles edge cases like large datasets and SQL joins, leaving no obvious gaps for the intended domain.
Available Tools
8 toolseurostat_browse_themesBrowse Eurostat Theme HierarchyARead-onlyIdempotentInspect
Navigate the Eurostat theme tree. Without theme_code returns the top-level theme folders (Economy, Population, Transport, etc.) — the practical starting points. With a theme_code returns its immediate children: subtheme folders and datasets in that branch. Use this for structured discovery when you know the domain but not the dataset code, or to drill down from a broad topic to a specific dataset. Pair with eurostat_search_datasets for keyword-based discovery. The tree is the dissemination table of contents plus the Comext host's DS-* collections: detailed trade under ext_go_detail (inside ext_go, "International trade in goods") and PRODCOM under prom (inside icts, "Industry, trade and services"). A collection on neither, such as the legacy PRODCOM DS-056120, is not disseminated and appears nowhere in the tree.
| Name | Required | Description | Default |
|---|---|---|---|
| theme_code | No | Folder code to expand (e.g., "economy", "reg"). Omit to list the top-level theme folders. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| items | No | Immediate children of the requested theme, or the root themes if theme_code was omitted. |
| nextStep | No | Suggested next action based on these results. Populated when there is a clear follow-up call. |
| itemCount | No | Number of items returned in this level. |
| themeCode | No | Folder code that was browsed, or omitted for root. |
| parentPath | No | Breadcrumb from root to the requested theme (e.g., ["Database by themes", "Economy and finance"]). Empty when browsing root. |
| otherPlacements | No | Breadcrumbs of the other branches that file this same theme_code. Eurostat lists a few folder codes in more than one branch; the items above come from the first one the catalogue lists, which never has fewer children than the branches named here but can list different ones. theme_code takes a bare code, so those branches cannot be addressed directly — browse down to them from the root instead. Omitted when the code has a single placement — the normal case. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint true, so the safety and repeatability profile is covered. The description adds meaningful behavioral context beyond those annotations: it specifies that without theme_code the tool returns top-level theme folders, with theme_code it returns immediate children, and that the tree is a combination of the dissemination table of contents plus special Comext collections. It does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core navigation behavior and then layers in usage guidance, alternative tools, and important caveats. Every sentence earns its place: the special-collection detail explains why some datasets may not appear in the tree, and the explicit sibling pairing prevents agent confusion. It is dense but not rambling.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only navigation tool with one optional parameter and an output schema, the description is complete. It explains the two invocation modes, gives examples, names the sibling tool for alternative discovery, and clarifies coverage limitations that could otherwise cause an agent to assume a missing dataset is an error. The annotations cover the safe, idempotent nature of the operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameter is already documented as a folder code to expand with examples like 'economy' and 'reg'. The description adds value by explaining the behavioral difference between omitting theme_code and providing it, and by clarifying that the result includes both subtheme folders and datasets in that branch. This pushes it slightly above the baseline for high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Navigate the Eurostat theme tree.' It clearly distinguishes the tool from siblings by stating this is for structured discovery when you know the domain but not the dataset code, and explicitly contrasts it with eurostat_search_datasets for keyword-based discovery. It also explains the two modes (top-level without theme_code, children with theme_code), leaving no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit instructions: use this tool for structured discovery or drilling down from a broad topic, and pair it with eurostat_search_datasets when keyword-driven discovery is more appropriate. It also covers edge cases by explaining which collections appear in the tree and which do not, such as the legacy PRODCOM DS-056120 not being disseminated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
eurostat_dataframe_describeDescribe Eurostat DataframesARead-onlyIdempotentInspect
List the tables staged on a Eurostat dataframe canvas, with their row counts and column names and types. Call this before eurostat_dataframe_query to learn the table and column names to write SQL against. The canvas_id comes from a eurostat_query_dataset or eurostat_download_dataset response that reported a staged table. Three tools stage tables, and they write different columns, so read the columns reported here rather than assuming. The two observation stagers keep every column flat: eurostat_query_dataset gives each dimension a code column named after the dimension (e.g. "geo") plus a label companion (e.g. "geo_label"); eurostat_download_dataset gives code columns only — the bulk endpoint carries no labels — plus a "time" column. Both write the same five measure columns — obs_value, obs_flag, obs_flag_label, conf_status, conf_status_label — carrying the same codes for the same observation, so their tables join on dimension codes and time and compare like with like. A table staged from a DS-* dataset (Comext detailed trade, PRODCOM) adds obs_value_text, holding a value Eurostat published as text, such as a PRODCOM quantity unit. eurostat_get_dimension_values, given a canvas_id, stages one dimension's value list as two columns, code and label, which labels a download's code column through a join (e.g. d.geo = g.code).
| Name | Required | Description | Default |
|---|---|---|---|
| canvas_id | Yes | Canvas identifier returned as canvasId by eurostat_query_dataset, eurostat_download_dataset, or eurostat_get_dimension_values. Identifies the workspace holding the staged tables. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| notice | No | Guidance when the canvas holds no tables. Omitted when it holds at least one. |
| tables | No | Tables staged on this canvas. Empty when nothing has been staged yet, or when every staged table has expired. |
| canvasId | No | Canvas identifier the tables were read from. |
| expiresAt | No | ISO 8601 timestamp when the canvas expires. Every call on it slides this forward. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so the safety profile is covered. The description adds meaningful behavioral context beyond that: it reports metadata only, names the source of valid canvas_ids, and clarifies that returned columns vary by staging tool. It does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but highly information-dense, and the first sentence front-loads the core purpose. Each subsequent sentence contributes needed differentiation about the staging tools and column schemas; however, the length could have been tightened by moving some staging details into the parameter or output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only metadata tool, the description is complete: it states what is returned, when to call it, where the input comes from, and why relying on it matters. The presence of an output schema means the description does not need to enumerate return fields, and nothing necessary for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and both the schema and description describe canvas_id similarly as an identifier returned by the staging tools. The description adds a small amount of usage nuance by insisting the canvas_id must come from a response that reported a staged table, but this mostly repeats the schema's meaning rather than enriching it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: "List the tables staged on a Eurostat dataframe canvas, with their row counts and column names and types." It also distinguishes itself from eurostat_dataframe_query by framing itself as the precursor that supplies table and column names for SQL.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says to call this before eurostat_dataframe_query to learn table and column names. It also explains where canvas_id comes from and warns that the three staging tools write different columns, telling the agent to read the reported columns rather than assume.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
eurostat_dataframe_queryQuery Eurostat DataframesARead-onlyIdempotentInspect
Run a read-only SQL SELECT against tables staged on a Eurostat dataframe canvas — the way to reach observations past the 5,000-row inline cap of eurostat_query_dataset and past the inline preview of a eurostat_download_dataset bulk download, and to aggregate, group, or join across staged tables without re-fetching from Eurostat. Call eurostat_dataframe_describe first for the table and column names, which differ between the tools that stage them. Only a single SELECT statement runs: statement chaining, non-SELECT verbs, and functions that read files or external data are rejected. Columns are flat — every dimension is a code column named after the dimension, the measure is obs_value, the observation flag is obs_flag / obs_flag_label and the confidentiality marker is conf_status / conf_status_label; a "_label" companion per dimension exists only on tables eurostat_query_dataset staged. Both observation stagers write the same five measure columns with the same codes, so join their tables on dimension codes and time and compare obs_flag or conf_status across them directly; a DS-* table also carries obs_value_text, a value published as text (e.g. a PRODCOM unit "KG"). A value list eurostat_get_dimension_values staged has two columns, code and label: join it to the code column of a download (e.g. JOIN df_x g ON d.geo = g.code) to label that table.
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | A single read-only SELECT statement. Reference tables by the names eurostat_dataframe_describe reports. Example: SELECT geo, geo_label, AVG(obs_value) AS mean FROM df_a1b2c3d4 WHERE time >= '2020' GROUP BY geo, geo_label ORDER BY mean DESC. | |
| canvas_id | Yes | Canvas identifier returned as canvasId by eurostat_query_dataset, eurostat_download_dataset, or eurostat_get_dimension_values. Identifies the workspace holding the staged tables. |
Output Schema
| Name | Required | Description |
|---|---|---|
| rows | No | Result rows, each keyed by column name. Bounded by the canvas row limit. 64-bit integer results — COUNT(*) among them — arrive as strings so values outside the JSON number range survive intact; cast to DOUBLE in the SQL if a number is wanted. |
| error | No | Present when the call failed. Absent on success. |
| columns | No | Column names in projection order. |
| canvasId | No | Canvas identifier the query ran against. |
| rowCount | No | Rows materialized into this response. Equals the full result size unless truncated is true. |
| truncated | No | True when the result exceeded the canvas row limit and was cut short. Add a LIMIT, an aggregate, or a narrower WHERE clause to see the rest. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint and idempotentHint annotations, the description discloses important behavioral traits: statement chaining and non-SELECT verbs are rejected, columns are flat with specific names, and the measure/observation/confidentiality columns are standardized across stagers. This gives the agent a detailed model of how queries will behave and what data shape to expect.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense and fairly long, but every sentence carries operational information needed to invoke the tool correctly. It is front-loaded with purpose and constraints, and the later detail about column layouts and join semantics is justified by the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and the presence of annotations and an output schema, the description is remarkably complete. It covers prerequisites (call dataframe_describe first), query restrictions, table schemas, cross-stager join semantics, and the value-list helper table, so an agent has enough context to both select and correctly invoke this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already describes both parameters with 100% coverage, so the baseline is 3. The description adds meaningful semantics beyond the schema by explaining that SQL must be a single SELECT, that table names come from dataframe_describe and differ by stager, and how to join dimension value tables. This goes beyond repeating the schema fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: run a read-only SQL SELECT against staged Eurostat dataframe tables. It clearly differentiates the tool from siblings by naming the capabilities it alone provides, such as exceeding the 5,000-row cap of eurostat_query_dataset and aggregating/joining staged tables without re-fetching.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly identifies when to use this tool versus alternatives: to get past the 5,000-row cap, past download previews, and to aggregate, group, or join staged data. It also instructs calling eurostat_dataframe_describe first and states the hard constraint that only a single SELECT statement is allowed, giving clear operational guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
eurostat_download_datasetDownload Eurostat DatasetARead-onlyIdempotentInspect
Download a Eurostat dataset in bulk through the SDMX 2.1 TSV endpoint and stage every observation as a SQL table on the dataframe canvas — the route to a whole dataset, where eurostat_query_dataset is the route to a slice of one. The TSV wire format is roughly half the bytes of the JSON-stat body eurostat_query_dataset reads, so it reaches datasets that would otherwise time out, and it is expanded here into one row per observation. Filters take the same dimension-code map eurostat_query_dataset uses and are applied server-side by Eurostat; call eurostat_get_dataset_info first for the dimension codes and eurostat_get_dimension_values for their values. Narrow with since_period/until_period rather than asking for the most recent N periods — the TSV layout keeps a column for every period whichever is requested, so a period range is what actually shrinks the response. Transfers are bounded by a byte budget enforced while streaming: when it is spent the download stops and budgetExceeded is set, leaving a prefix of the dataset rather than an error. Only preview_limit rows come back inline. When a table is staged, call eurostat_dataframe_describe first to confirm its columns, then eurostat_dataframe_query; without a canvas, rows past the preview are not retained.
| Name | Required | Description | Default |
|---|---|---|---|
| filters | No | Dimension filters as a map of dimension code → array of accepted values, applied by Eurostat before the body is sent. Example: {"unit": ["CP_MEUR"], "na_item": ["B1G"], "geo": ["DE", "FR"]}. Omit a dimension or pass an empty array to accept every value for it. Dimension codes match in any case ("GEO" is geo). Do not put "time" here — use since_period/until_period. Naming a dimension the dataset does not have is rejected with the dataset's dimension list rather than silently ignored. | |
| canvas_id | No | Reuse an existing dataframe canvas so this download lands beside earlier results and can be joined against them. Pass the canvasId a previous eurostat_download_dataset or eurostat_query_dataset response returned; omit to start a fresh canvas. Ignored on deployments without a dataframe canvas. A download that carries no observations fails as no_results and leaves the canvas untouched. | |
| dataset_code | Yes | Dataset code (e.g., "nama_10_gdp"). Required. A DS-* code — Comext detailed trade or PRODCOM, in any case — is served by the Comext host, which refuses an unfiltered download of its large collections as extraction_too_big: filter it, including freq on the trade flows, which mix annual and monthly series. | |
| since_period | No | Start of the period range, inclusive, sent as startPeriod. Accepted forms: YYYY, YYYY-MM, YYYY-MM-DD, YYYY-Qn (1–4), YYYY-Sn (1–2), YYYY-Tn (1–3), YYYY-Mnn (01–12), YYYY-Wnn (a week the year has, up to 53) or YYYY-Dnnn (a day the year has, up to 366) (e.g., "2020", "2023-Q1", "2024-01"). Extra leading zeros after the letter are dropped ("2020-W001" is sent as "2020-W01"), a day of the year is sent as three digits ("2026-D1" as "2026-D001"), YYYY-A1 is sent as YYYY, and a period of another frequency is mapped onto the dataset's own. A malformed or non-existent period (e.g., "2020-13") is rejected as invalid_period. The most effective way to shrink a bulk response: it removes period columns from the TSV rather than blanking their cells. | |
| until_period | No | End of the period range, inclusive (e.g., "2024"), sent as endPeriod, in the same forms as since_period. Omit for data through the latest available period. The range must hold at least one day: a since_period that starts after until_period ends is rejected as invalid_period, while pairs of different frequencies are fine ("2020-06" to "2020"). | |
| preview_limit | No | How many observations to echo inline, from the start of the download. Caps at 500. The full download is on the canvas table when one was staged; this is orientation, not the result set. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| notice | No | Guidance on every download: the staged table with the required eurostat_dataframe_describe then eurostat_dataframe_query sequence (or, without a canvas, what was returned inline and what was discarded), preceded by byte-budget disclosure when the budget stopped the transfer and by the inline-preview length when preview_limit returns fewer rows than were downloaded. |
| canvasId | No | Dataframe canvas holding the staged download. Pass to eurostat_dataframe_describe, eurostat_dataframe_query, or a later staging call. Omitted when nothing was staged. |
| rowCount | No | Observations expanded from the download — one per populated cell, counting those Eurostat reports as unavailable. |
| bytesRead | No | Decoded TSV bytes read from Eurostat — after gzip decompression when the body arrived compressed, so it measures the payload rather than the wire. |
| tableName | No | Canvas table holding every downloaded observation. Call eurostat_dataframe_describe with canvasId first to confirm the table and columns, then eurostat_dataframe_query. Omitted when this deployment runs without a dataframe canvas, in which case only the inline preview survives the call. |
| compressed | No | True when Eurostat sent the body gzip-compressed. It does so without a Content-Encoding header on large responses, so this reports what the stream actually carried. |
| totalCount | No | Observations the download produced — equal to rowCount. The inline observations array holds only the first preview_limit of them; budgetExceeded, not this count, says whether the download is the whole dataset. |
| datasetCode | No | Dataset code as provided. |
| periodRange | No | Period coverage of the rows actually downloaded. Narrower than the dataset when budgetExceeded is true or a period range was applied. |
| appliedQuery | No | The bulk request as the server built it. |
| missingCount | No | Downloaded observations carrying no numeric value (obs_value is null). |
| observations | No | The first preview_limit observations of the download, in the order Eurostat streamed them. A prefix of the staged table, not a sample. |
| budgetExceeded | No | True when the byte budget stopped the transfer before the dataset ended, making the rows a prefix rather than the whole thing. Narrow with filters or a period range, or raise EUROSTAT_BULK_MAX_BYTES. |
| dimensionsUsed | No | Dimension codes carried by the downloaded rows, in the order Eurostat keys them (e.g., ["freq", "unit", "na_item", "geo"]). Read from the TSV header, so it reflects the response rather than metadata. The period lives in the separate "time" column. |
| stagedRowCount | No | Rows written to the canvas table. Matches rowCount. Omitted alongside tableName. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, so the safety profile is covered. The description goes beyond this to disclose the byte budget and budgetExceeded behavior, the preview_limit as orientation only, the canvas retention rule (rows past preview not retained without a canvas), and error conditions like extraction_too_big and no_results. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Despite its length, every sentence earns its place. The structure front-loads the core purpose and contrast, then systematically covers filters, periods, budget, preview, and canvas usage. There is no fluff or repetition; it is dense but tightly organized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (6 params, nested filters, multiple error modes, a byte budget, and a canvas workflow), the description covers everything an agent needs: the full workflow, the rationale for period ranges, the Comext caveat, and post-download steps. An output schema exists, so return-value details are unnecessary.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
While schema coverage is 100%, the description adds substantial meaning: filters are case-insensitive, 'time' must not be placed there, unknown dimensions are rejected with the dimension list; period forms and normalization (leading zeros, YYYY-A1 mapping) are detailed; preview_limit is clarified as orientation, not the result set. This enriches each parameter beyond the schema's own descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-resource pair ('Download a Eurostat dataset in bulk through the SDMX 2.1 TSV endpoint') and immediately distinguishes it from its sibling eurostat_query_dataset ('the route to a whole dataset' vs 'the route to a slice of one'). It names the wire format, the staging behavior, and the contrast, leaving no ambiguity about what the tool does and how it differs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to use this tool versus alternatives ('the route to a whole dataset, where eurostat_query_dataset is the route to a slice of one') and provides a clear workflow: call eurostat_get_dataset_info first for codes, eurostat_get_dimension_values for values, then after staging use eurostat_dataframe_describe and eurostat_dataframe_query. It also gives specific advice on period narrowing and the byte budget, leaving no guesswork.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
eurostat_get_dataset_infoGet Eurostat Dataset InfoARead-onlyIdempotentInspect
Fetch metadata for a Eurostat dataset: dimensions with valid values, time range, observation count, and last-update date. Call this before eurostat_query_dataset or eurostat_download_dataset to discover what dimension codes are valid (unit, na_item, geo, etc.); eurostat_download_dataset builds its positional filter key from this dimension list, so a filter naming a dimension absent here is rejected outright. Returns up to 10 sample values per dimension for orientation; use eurostat_get_dimension_values to list the full set for large dimensions. A DS-* code (detailed trade and PRODCOM, in any case) is read from the Comext dissemination host, which reports no period coverage or observation count, so timeRange and obsCount come back unreported; the first call on a large Comext collection downloads its full structure (23 MB for DS-045409) and takes longer, and repeat calls within the hour reuse it.
| Name | Required | Description | Default |
|---|---|---|---|
| dataset_code | Yes | Dataset code (e.g., "nama_10_gdp", or "DS-045409" for a Comext collection). Use eurostat_search_datasets or eurostat_browse_themes to find codes. |
Output Schema
| Name | Required | Description |
|---|---|---|
| code | No | Dataset code as provided. |
| error | No | Present when the call failed. Absent on success. |
| label | No | Human-readable dataset title. |
| obsCount | No | Total number of observations in the full dataset (all periods). Omitted when Eurostat does not report it — an omitted count is unknown, not zero. |
| timeRange | No | Overall data coverage period for this dataset. Each bound is omitted when Eurostat does not report it — an omitted bound is unknown, not empty. |
| dimensions | No | All dimensions of the dataset with their valid codes and labels. |
| lastUpdated | No | ISO 8601 timestamp of the most recent data update. Omitted when Eurostat does not report it. |
| metadataUrl | No | URL to the ESMS HTML metadata page for this dataset. Omitted when not provided by Eurostat. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent/openWorld annotations, the description discloses important behavioral traits: sample-value limits, missing timeRange/obsCount for DS-* codes, a 23 MB first-call download for large Comext collections, and one-hour caching. This materially helps an agent anticipate latency and incomplete results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: purpose, usage routing, sample-value behavior, and DS-* caveats. It front-loads the core purpose and keeps related caveats grouped, making it easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter metadata tool with an output schema and strong annotations, the description covers all necessary operational context: when to call it, what it returns, how it differs from related tools, and special-case behavior. Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already fully describes dataset_code with examples, so the baseline is 3. The description adds meaningful semantic nuance by explaining that DS-* codes route to the Comext host and behave differently, which goes beyond the schema's basic type and example.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Fetch metadata for a Eurostat dataset' and enumerates the exact contents (dimensions, valid values, time range, observation count, last-update date). It also distinguishes itself from siblings by explicitly naming eurostat_query_dataset, eurostat_download_dataset, and eurostat_get_dimension_values.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: 'Call this before eurostat_query_dataset or eurostat_download_dataset.' It also provides an alternative for a different need: 'use eurostat_get_dimension_values to list the full set for large dimensions.' This is clear routing with no ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
eurostat_get_dimension_valuesGet Eurostat Dimension ValuesARead-onlyIdempotentInspect
List the valid values for a specific dimension in a Eurostat dataset (e.g., all unit codes for nama_10_gdp, all geo codes for a regional dataset). Use this when eurostat_get_dataset_info returns more values than the 10-item sample, or to confirm exact codes before querying. For the "geo" dimension, use geo_level to filter by NUTS hierarchy (country, nuts1, nuts2, nuts3). An invalid code matches nothing: eurostat_query_dataset names it in unmatchedValues, or in its no_results error when the query matched nothing at all, and Eurostat rejects it as a fault on eurostat_download_dataset; use this tool to verify codes first. At most 2,000 values come back inline — a longer list, such as the 37,069 CN8 product codes of DS-045409 or a daily time dimension, is cut there and says so. Pass canvas_id to also stage the whole list, whatever its length, as a two-column code/label table on that dataframe canvas: search it with SQL, or join it to a eurostat_download_dataset table, whose columns carry dimension codes only.
| Name | Required | Description | Default |
|---|---|---|---|
| canvas_id | No | Also stage the values on this dataframe canvas as a table with two columns, code and label, holding every value the dimension lists — past the inline cap too — at the geo_level requested, country when it is omitted. Pass the canvasId a eurostat_download_dataset or eurostat_query_dataset response returned, then search the staged table with SQL or join it to a download on the dimension column (e.g., d.geo = g.code). Omit to return the values inline only: this tool never starts a canvas. Ignored on deployments without a dataframe canvas. | |
| dimension | Yes | Dimension code to retrieve values for (e.g., "unit", "na_item", "geo"). Use eurostat_get_dataset_info to see available dimensions. | |
| geo_level | No | NUTS hierarchy level filter — applies only when dimension is "geo"; passing it with any other dimension is rejected. Options: "aggregate" (EU/EA codes), "country" (2-letter codes, default), "nuts1" (3-char), "nuts2" (4-char), "nuts3" (5-char). | |
| dataset_code | Yes | Dataset code (e.g., "nama_10_gdp", or "DS-045409" for a Comext collection). |
Output Schema
| Name | Required | Description |
|---|---|---|
| cap | No | The inline cap applied. Present alongside truncated. |
| error | No | Present when the call failed. Absent on success. |
| shown | No | Values returned inline. Present alongside truncated. |
| notice | No | Where the values past the inline cap are: the staged table when canvas_id was passed, or how to stage them. Present alongside truncated. |
| values | No | Dataset-available values for this dimension, in Eurostat's order — for geo, the subset at geoLevel. Holds every value up to 2,000; past that, the first 2,000, with truncated set and the whole list on the canvas table when canvas_id was passed. |
| canvasId | No | Dataframe canvas the values were staged on — the canvas_id supplied. Omitted when nothing was staged: canvas_id was omitted, this deployment runs without a dataframe canvas, or the dimension lists no values. |
| geoLevel | No | Effective NUTS hierarchy level for the geo value set. Present only for the geo dimension; country is reported when geo_level was omitted. |
| tableName | No | Canvas table holding every value as two VARCHAR columns, code and label. Call eurostat_dataframe_describe with canvasId first to confirm it, then join it in eurostat_dataframe_query. Omitted alongside canvasId. |
| truncated | No | True when the dimension lists more values than the inline cap and values holds only the first of them. Omitted when values holds every one. |
| totalCount | No | Number of distinct values the dimension lists, after geoLevel filtering for geo — all of them, including any past the inline cap. |
| dimensionCode | No | The dimension code that was queried. |
| dimensionLabel | No | Human-readable dimension name. |
| stagedRowCount | No | Rows written to the canvas table. Equals totalCount. Omitted alongside tableName. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already carry readOnlyHint/idempotentHint/openWorldHint. On top of that the description discloses non-obvious behavior: the 2,000-value inline cap with truncation notice, that canvas_id staging captures the full list past the cap, and that this tool never starts a canvas. This adds genuine value beyond structured fields; only near-exhaustive detail keeps it from a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then usage, then behavioral constraints; every sentence earns its place. It is slightly dense and the geo-level detail partly duplicates schema text, but no sentence is filler and the logical ordering (why, when, constraints, side-effects) is strong.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Thorough for a complex tool with 4 params and an output schema: covers error-propagation paths into query/download siblings, the truncation policy, the staging/join workflow, and the geo filtering constraint. Nothing an agent needs to decide between inline vs canvas use or to handle long lists is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description meaningfully extends the schema: it explains the canvas_id staging interplay with the inline cap, the geo_level rejection when applied to non-geo dimensions, and the default geo_level of 'country'. These go beyond what the schema states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Begins with a specific verb+resource ('List the valid values for a specific dimension in a Eurostat dataset') with concrete examples (unit codes for nama_10_gdp, geo codes). It clearly distinguishes itself from eurostat_get_dataset_info (10-item sample) via explicit contrast, so an agent can tell them apart without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use triggers: when get_dataset_info returns more than its 10-item sample, or to confirm exact codes before querying. It also names the downstream consequences of invalid codes across siblings (unmatchedValues in query_dataset, fault on download_dataset) and routes the agent to this tool to verify first, fully resolving alternative selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
eurostat_query_datasetQuery Eurostat DatasetARead-onlyIdempotentInspect
Fetch statistical data from a Eurostat dataset with dimension filters. Returns a deterministic inline prefix of decoded observations with dimension codes and labels, numeric values, an OBS_FLAG status (e.g., "p" = provisional, "e" = estimated) and a separate CONF_STATUS confidentiality marker (e.g., "C" = confidential, which is usually why a value is null). preview_limit controls only that prefix; filters and period controls reduce the matched result itself. Call eurostat_get_dataset_info first to discover valid dimension codes and values. Apply filters to keep the result set manageable — large unfiltered queries may trigger an async response error. Use filters.geo for specific country/region codes, or geo_level for NUTS hierarchy filtering (mutually exclusive). Use last_n_periods for the N most recent periods without knowing the end date. Matches above 5,000 observations are staged whole when this deployment runs a dataframe canvas: call eurostat_dataframe_describe first, then eurostat_dataframe_query. Matches at or below 5,000 are never staged. When the target is a whole dataset rather than a slice, eurostat_download_dataset reads the SDMX bulk endpoint instead and is the cheaper route.
| Name | Required | Description | Default |
|---|---|---|---|
| lang | No | Language for labels in the response. Default is "EN". Options: "EN", "FR", "DE". | EN |
| filters | No | Dimension filters as a map of dimension code → array of valid values. Example: {"unit": ["CP_MEUR"], "na_item": ["B1GQ"], "geo": ["DE", "FR"]}. An empty array is treated as no filter for that dimension and is dropped from the request. Dimension codes match in any case ("GEO" is geo). Do not include "geo" here if using geo_level. A value that matches nothing contributes no rows rather than an error; the response names it in unmatchedValues, or in the no_results error when nothing matched at all. eurostat_get_dimension_values lists the valid values. | |
| canvas_id | No | Reuse an existing dataframe canvas, so a result staged by this call lands beside earlier ones and can be joined against them. Pass the canvasId a previous eurostat_query_dataset or eurostat_download_dataset response returned; omit to start a fresh canvas. Ignored on deployments without a dataframe canvas and when the match is at or below 5,000 observations. | |
| geo_level | No | Filter by NUTS hierarchy level. Mutually exclusive with a "geo" key in filters. Options: "aggregate" (EU/EA totals), "country" (41 member/candidate states), "nuts1" (127 major regions), "nuts2" (309 basic regions), "nuts3" (1,343 small regions). | |
| dataset_code | Yes | Dataset code (e.g., "nama_10_gdp"). Required. A DS-* code — Comext detailed trade or PRODCOM, in any case — is served by the Comext host: filter freq on its trade flows, which mix annual and monthly series, and note that product, reporter and partner carry aggregates (TOTAL, EU27_2020) that double-count when summed with their members. | |
| since_period | No | Start of the time range, inclusive. Accepted forms: YYYY, YYYY-MM, YYYY-MM-DD, YYYY-Qn (1–4), YYYY-Sn (1–2), YYYY-Tn (1–3), YYYY-Mnn (01–12), YYYY-Wnn (a week the year has, up to 53) or YYYY-Dnnn (a day the year has, up to 366) (e.g., "2020", "2023-Q1", "2024-01"). Extra leading zeros after the letter are dropped ("2020-Q01" is sent as "2020-Q1"), a day of the year is sent as three digits ("2026-D1" as "2026-D001"), and YYYY-A1 is sent as YYYY. A period of another frequency is mapped onto the dataset's own, so "2020-01" works on annual data. A malformed or non-existent period (e.g., "2020-13") is rejected as invalid_period. Mutually exclusive with last_n_periods. | |
| until_period | No | End of the time range, inclusive (e.g., "2024"), in the same forms as since_period. Omit for data through the latest available period. The range must hold at least one day: a since_period that starts after until_period ends is rejected as invalid_period, while pairs of different frequencies are fine ("2020-06" to "2020"). Mutually exclusive with last_n_periods. | |
| preview_limit | No | How many matched observations to return inline, from the deterministic start of the JSON-stat cell order. Default 50; maximum 500. This changes only the inline prefix: it does not reduce obsCount, missingObsCount, timeRange, the upstream response, or the rows staged when the match exceeds 5,000. Use filters or period controls to reduce the match itself. | |
| last_n_periods | No | Return only the N most recent periods. N counts back from the dataset's latest period, not from the latest period published for this slice, so a slice that lags the rest of the dataset can come back empty — raise N, or use until_period ending at a period the slice has published. Mutually exclusive with since_period and until_period. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| notice | No | Guidance when a filter value matched nothing, when preview_limit omits matched rows, or when the match was staged — names the unmatched values, distinguishes the inline prefix from filters that reduce the match and, when staged, gives the describe-then-query sequence. Omitted when every filter value matched and the preview contains the whole match. |
| canvasId | No | Dataframe canvas holding the staged result. Pass to eurostat_dataframe_describe, eurostat_dataframe_query, or a later eurostat_query_dataset call. Omitted when nothing was staged. |
| obsCount | No | Total number of observations matched (before any cap). |
| tableName | No | Canvas table holding every matched observation in flat form — one code column per dimension plus a "_label" companion, then obs_value, obs_flag, obs_flag_label, conf_status, conf_status_label. A DS-* table also carries obs_value_text, the valueText of each row. Call eurostat_dataframe_describe with canvasId first to confirm the table and columns, then eurostat_dataframe_query. Omitted when nothing was staged: either the match was at or below 5,000 observations, or this deployment runs without a dataframe canvas. |
| timeRange | No | Time coverage of everything matched — the same set obsCount counts, so it can reach periods absent from observations when truncated is true. Each bound is omitted when neither the match nor Eurostat report it — an omitted bound is unknown, not empty. |
| truncated | No | True only when the match exceeded the 5,000-observation staging threshold. Independent of preview_limit: observations can be a shorter prefix while truncated is false. When tableName is set, call eurostat_dataframe_describe first and then eurostat_dataframe_query; when it is absent, use filters or period controls to reduce the match. |
| datasetCode | No | Dataset code as provided. |
| datasetLabel | No | Human-readable dataset title. |
| observations | No | The first preview_limit decoded observations in deterministic JSON-stat cell order — the leading combinations of the dataset dimensions, neither a sample nor necessarily the most recent periods. This prefix is independent of the 5,000-observation staging threshold. When tableName is set, the table holds every matched row; otherwise use filters or a period range to reduce the match itself. |
| appliedFilters | No | Effective query parameters applied to the Eurostat API. |
| dimensionsUsed | No | Ordered list of dimension codes present in the response (e.g., ["freq", "unit", "na_item", "geo", "time"]). |
| stagedRowCount | No | Rows written to the canvas table. Matches obsCount. Omitted alongside tableName when nothing was staged. |
| missingObsCount | No | Number of matched observations carrying no numeric value, counted across everything matched rather than only the returned rows. Covers both unavailable and withheld cells — a slice can be wholly confidential, so this equalling obsCount does not mean the data is absent. |
| unmatchedValues | No | Filter values that matched nothing in the dataset, keyed by dimension code and spelled as sent (matching ignores case). The observations cover only the values that did match. Omitted when every filter value matched. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, the description discloses the deterministic inline prefix, OBS_FLAG and CONF_STATUS semantics, the fact that preview_limit only affects the prefix, the 5,000-observation staging threshold, and the possibility of async response errors. This adds substantial behavioral context without contradicting annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well front-loaded: purpose and return contract appear immediately, followed by workflow and routing guidance. Some sentences repeat schema details, but the staging threshold, async error warning, and sibling alternates justify their presence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 9 parameters, an output schema, and annotations present, the description still adds the missing workflow context: how to discover valid filters, how to avoid large-query failures, what happens at the 5,000 threshold, and when to prefer a sibling tool. An agent has what it needs to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already carries detailed parameter meaning. The description reinforces key semantics such as preview_limit only controlling the prefix and geo/geo_level mutual exclusivity, but it does not materially add parameter-level information beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
First sentence states a specific verb, resource, and mechanism: 'Fetch statistical data from a Eurostat dataset with dimension filters.' It also distinguishes this tool from eurostat_download_dataset by naming the whole-dataset alternative, so an agent can tell them apart.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit routing: call eurostat_get_dataset_info first, apply filters to avoid async errors, use filters.geo vs geo_level, use last_n_periods without knowing the end date, and switch to eurostat_dataframe_describe/query or eurostat_download_dataset under specific conditions. Named alternatives and clear conditions make this very actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
eurostat_search_datasetsSearch Eurostat DatasetsARead-onlyIdempotentInspect
Search the Eurostat catalogue by keyword. Returns matching datasets with codes, descriptions, period coverage, and theme breadcrumbs. Use this to discover dataset codes before calling eurostat_get_dataset_info, then eurostat_query_dataset for a slice of a dataset or eurostat_download_dataset for the whole of one. Results are limited to datasets and predefined tables — folders are excluded. The catalogue joins two sources: the dissemination table of contents, and the Comext host's dataflow list, which adds the DS-* collections — detailed trade by CN8, HS, SITC, BEC and CPA, and PRODCOM — filed under "International trade in goods - detailed data (Comext)" and "Statistics on the production of manufactured goods (PRODCOM)". Comext entries report a last-update date but no period coverage or observation count. A collection on neither list, such as the legacy PRODCOM DS-056120, is not disseminated and cannot be reached through this server.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size — maximum datasets returned per page (1–100). Default is 20. To retrieve matches beyond one page, pass the returned nextCursor back as cursor; the page size is fixed by this first call. | |
| query | Yes | Search terms — at least one non-whitespace token is required. Split on whitespace into tokens; every token must match (AND), case-insensitively, somewhere across the dataset label, theme breadcrumb, or code. Word order does not matter, so "business demography NUTS 3" or "regional economic accounts" resolve without naming a label verbatim. | |
| cursor | No | Opaque pagination cursor from a previous call's nextCursor. Omit for the first page; pass it back — with the same query — to fetch the next page of matches over a stable order. A cursor is bound to the query that produced it and to the catalogue snapshot in effect at that time, so reusing one with a different query, or after the catalogue refreshes, is rejected rather than silently paging a different result set. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| query | No | Search terms as submitted. |
| datasets | No | Matching datasets for the current page, up to the requested limit. |
| nextStep | No | Suggested next action based on these results. Populated when there is a clear follow-up call. |
| truncated | No | True when more matches remain beyond this page — pass nextCursor as cursor to fetch them. |
| nextCursor | No | Opaque cursor for the next page of matches. Pass it back as cursor with the same query; it stops working once the catalogue refreshes. Omitted on the last page. |
| totalMatches | No | Total distinct dataset codes matching the query across all pages, before the page limit. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint. The description goes further: explains the catalogue merges two sources, notes that Comext entries lack period coverage/observation count, warns that some collections are not disseminated, and clarifies pagination stability via cursor. This adds substantial behavioral context beyond the annotations without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than average but every sentence earns its place. It front-loads the purpose and workflow, then layers behavioral nuances. There is no filler or repetition; each clause adds actionable detail. The structure flows logically from purpose to usage to edge cases, making it easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (catalogue search with pagination, two data sources, exclusions) and the presence of an output schema, the description covers all necessary aspects: what is returned, how to use it in a workflow, limitations, and parameter semantics. An agent has everything needed to invoke it correctly and interpret results, without gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although the schema already documents all 3 parameters at 100% coverage, the description adds meaningful semantics: query tokenization rules (AND, case-insensitive, matching across label/breadcrumb/code) and cursor binding to query and catalogue snapshot. This goes well beyond the schema's basic field types, helping the agent craft effective queries and handle pagination correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource ('Search the Eurostat catalogue by keyword') and immediately lists the returned fields (codes, descriptions, period coverage, theme breadcrumbs). It explicitly distinguishes itself from siblings by stating it is the discovery step before get_info/query/download, and contrasts with browsing by theme. No ambiguity about what this tool does or how it differs from the 7 siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit workflow: use this to find codes, then call eurostat_get_dataset_info, then query or download. It also states exclusions (folders excluded) and caveats (legacy collections like DS-056120 not reachable). This tells the agent exactly when to use it and when not to, referencing alternative tools directly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
7 tool updates
- Changed
eurostat_dataframe_describe1 field changed- changed
Input schema / properties / canvas_id / descriptionPrevious value: -"Canvas identifier returned as canvasId by eurostat_query_dataset or eurostat_download_dataset. Identifies the workspace holding the staged tables."New value: +"Canvas identifier returned as canvasId by eurostat_query_dataset, eurostat_download_dataset, or eurostat_get_dimension_values. Identifies the workspace holding the staged tables."
- Changed
eurostat_dataframe_query1 field changed- changed
Input schema / properties / canvas_id / descriptionPrevious value: -"Canvas identifier returned as canvasId by eurostat_query_dataset or eurostat_download_dataset. Identifies the workspace holding the staged tables."New value: +"Canvas identifier returned as canvasId by eurostat_query_dataset, eurostat_download_dataset, or eurostat_get_dimension_values. Identifies the workspace holding the staged tables."
- Changed
eurostat_download_dataset5 fields changed- changed
Input schema / properties / canvas_id / descriptionPrevious value: -"Reuse an existing dataframe canvas so this download lands beside earlier results and can be joined against them. Pass the canvasId a previous eurostat_download_dataset or eurostat_query_dataset response returned; omit to start a fresh canvas. Ignored on deployments without a dataframe canvas."New value: +"Reuse an existing dataframe canvas so this download lands beside earlier results and can be joined against them. Pass the canvasId a previous eurostat_download_dataset or eurostat_query_dataset response returned; omit to start a fresh canvas. Ignored on deployments without a dataframe canvas. A download that carries no observations fails as no_results and leaves the canvas untouched." - changed
Input schema / properties / dataset_code / descriptionPrevious value: -"Dataset code (e.g., \"nama_10_gdp\"). Required."New value: +"Dataset code (e.g., \"nama_10_gdp\"). Required. A DS-* code — Comext detailed trade or PRODCOM, in any case — is served by the Comext host, which refuses an unfiltered download of its large collections as extraction_too_big: filter it, including freq on the trade flows, which mix annual and monthly series." - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code is not available for dissemination (HTTP 404, SDMX faultcode 100). `invalid_dimension`: A filter names a dimension the dataset does not have, or a value or period range Eurostat rejects (SDMX faultcode 150). `filter_arity`: Eurostat rejected the positional dimension key because it carried the wrong number of positions (SDMX faultcode 140, INVALID_QUERY_NB_FILTERS), meaning the dataset structure has changed since the metadata call. `invalid_period`: since_period or until_period is not a period literal, or names a month, quarter, semester, trimester, week or day that does not exist, or since_period starts after until_period ends. Checked before any request — the bulk endpoint would otherwise roll an out-of-range period into a neighbouring one, and answer an inverted range with the whole series — and SDMX faultcode 140 TIME_PERIOD_FILTER_SPEC_INVALID maps here too. `async_queued`: Eurostat answered HTTP 200 with a SOAP syncResponse queue ticket (status SUBMITTED) instead of data, because the extraction was too costly to serve synchronously. `no_results`: The download completed but carried no populated observation cells. `upstream_fault`: The SDMX endpoint returned a fault this server does not model, or a body that is not a TSV table. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code is not available for dissemination (HTTP 404, SDMX faultcode 100). `invalid_dimension`: A filter names a dimension the dataset does not have, or a value or period range Eurostat rejects (SDMX faultcode 150). `filter_arity`: Eurostat rejected the positional dimension key because it carried the wrong number of positions (SDMX faultcode 140, INVALID_QUERY_NB_FILTERS), meaning the dataset structure has changed since the metadata call. `invalid_period`: since_period or until_period is not a period literal, or names a month, quarter, semester, trimester, week or day that does not exist, or since_period starts after until_period ends. Checked before any request — the bulk endpoint would otherwise roll an out-of-range period into a neighbouring one, and answer an inverted range with the whole series — and SDMX faultcode 140 TIME_PERIOD_FILTER_SPEC_INVALID maps here too. `async_queued`: Eurostat answered HTTP 200 with a SOAP syncResponse queue ticket (status SUBMITTED) instead of data, because the extraction was too costly to serve synchronously. `no_results`: The download completed but carried no populated observation cells. Nothing is staged, and no canvas is created or touched. `extraction_too_big`: Eurostat refused the extraction as too large (SDMX faultcode 413, HTTP 413): past its 5,000,000-row extraction limit, or an unfiltered download of a large DS-* Comext collection, which Eurostat serves only filtered. Covers every dataset, on either host. `upstream_fault`: The SDMX endpoint returned a fault this server does not model, or a body that is not a TSV table. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "not_found", - "invalid_dimension", - "filter_arity", - "invalid_period", - "async_queued", - "no_results", - "upstream_fault", - "canvas_not_found" -]New value: +[ + "not_found", + "invalid_dimension", + "filter_arity", + "invalid_period", + "async_queued", + "no_results", + "extraction_too_big", + "upstream_fault", + "canvas_not_found" +] - changed
Output schema / properties / observations / items / descriptionPrevious value: -"One observation as a flat row: one column per dimension holding its code, \"time\" for the period, then obs_value, obs_flag, obs_flag_label, conf_status, conf_status_label. A label column is null when Eurostat publishes no label for that code."New value: +"One observation as a flat row: one column per dimension holding its code, \"time\" for the period, then obs_value, obs_flag, obs_flag_label, conf_status, conf_status_label. A label column is null when Eurostat publishes no label for that code. Rows of a DS-* dataset also carry obs_value_text after obs_value: a value Eurostat published as text, such as a PRODCOM quantity unit (\"KG\"), kept verbatim with obs_value null; a PRODCOM \":C\" arrives as conf_status \"C\" instead."
- Changed
eurostat_get_dataset_info3 fields changed- changed
Input schema / properties / dataset_code / descriptionPrevious value: -"Dataset code (e.g., \"nama_10_gdp\"). Use eurostat_search_datasets or eurostat_browse_themes to find codes."New value: +"Dataset code (e.g., \"nama_10_gdp\", or \"DS-045409\" for a Comext collection). Use eurostat_search_datasets or eurostat_browse_themes to find codes." - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code does not exist or is not available for dissemination. `async_response`: Eurostat returned an async response (query too large for the API). Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code does not exist or is not available for dissemination. `upstream_fault`: Eurostat returned a dataset structure or content constraint this server cannot read: malformed, truncated, not XML, or missing the requested dataset's dataflow. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "not_found", - "async_response" -]New value: +[ + "not_found", + "upstream_fault" +]
- Changed
eurostat_get_dimension_values13 fields changed- added
Input schema / properties / canvas_idAdded value: +{ + "description": "Also stage the values on this dataframe canvas as a table with two columns, code and label, holding every value the dimension lists — past the inline cap too — at the geo_level requested, country when it is omitted. Pass the canvasId a eurostat_download_dataset or eurostat_query_dataset response returned, then search the staged table with SQL or join it to a download on the dimension column (e.g., d.geo = g.code). Omit to return the values inline only: this tool never starts a canvas. Ignored on deployments without a dataframe canvas.", + "pattern": "^[A-Za-z0-9_-]{10}$", + "type": "string" +} - changed
Input schema / properties / dataset_code / descriptionPrevious value: -"Dataset code (e.g., \"nama_10_gdp\")."New value: +"Dataset code (e.g., \"nama_10_gdp\", or \"DS-045409\" for a Comext collection)." - added
Output schema / properties / canvasIdAdded value: +{ + "description": "Dataframe canvas the values were staged on — the canvas_id supplied. Omitted when nothing was staged: canvas_id was omitted, this deployment runs without a dataframe canvas, or the dimension lists no values.", + "type": "string" +} - added
Output schema / properties / capAdded value: +{ + "description": "The inline cap applied. Present alongside truncated.", + "type": "number" +} - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code or dimension code does not exist. `async_response`: Eurostat returned an asynchronous-response condition. `no_results`: The dataset has no geo values at the effective geo_level. `conflicting_params`: geo_level was combined with a dimension other than \"geo\", where it has no effect. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code or dimension code does not exist. `no_results`: The dataset has no geo values at the effective geo_level. `conflicting_params`: geo_level was combined with a dimension other than \"geo\", where it has no effect. `upstream_fault`: Eurostat returned a dataset structure or content constraint this server cannot read: malformed, truncated, not XML, or missing the requested dataset's dataflow. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "not_found", - "async_response", - "no_results", - "conflicting_params" -]New value: +[ + "not_found", + "no_results", + "conflicting_params", + "upstream_fault", + "canvas_not_found" +] - added
Output schema / properties / noticeAdded value: +{ + "description": "Where the values past the inline cap are: the staged table when canvas_id was passed, or how to stage them. Present alongside truncated.", + "type": "string" +} - added
Output schema / properties / shownAdded value: +{ + "description": "Values returned inline. Present alongside truncated.", + "type": "number" +} - added
Output schema / properties / stagedRowCountAdded value: +{ + "description": "Rows written to the canvas table. Equals totalCount. Omitted alongside tableName.", + "type": "number" +} - added
Output schema / properties / tableNameAdded value: +{ + "description": "Canvas table holding every value as two VARCHAR columns, code and label. Call eurostat_dataframe_describe with canvasId first to confirm it, then join it in eurostat_dataframe_query. Omitted alongside canvasId.", + "type": "string" +} - changed
Output schema / properties / totalCount / descriptionPrevious value: -"Total number of distinct values returned, after geoLevel filtering for geo."New value: +"Number of distinct values the dimension lists, after geoLevel filtering for geo — all of them, including any past the inline cap." - added
Output schema / properties / truncatedAdded value: +{ + "description": "True when the dimension lists more values than the inline cap and values holds only the first of them. Omitted when values holds every one.", + "type": "boolean" +} - changed
Output schema / properties / values / descriptionPrevious value: -"All dataset-available values for this dimension. For geo, this is the subset at geoLevel."New value: +"Dataset-available values for this dimension, in Eurostat's order — for geo, the subset at geoLevel. Holds every value up to 2,000; past that, the first 2,000, with truncated set and the whole list on the canvas table when canvas_id was passed."
- Changed
eurostat_query_dataset5 fields changed- changed
Input schema / properties / dataset_code / descriptionPrevious value: -"Dataset code (e.g., \"nama_10_gdp\"). Required."New value: +"Dataset code (e.g., \"nama_10_gdp\"). Required. A DS-* code — Comext detailed trade or PRODCOM, in any case — is served by the Comext host: filter freq on its trade flows, which mix annual and monthly series, and note that product, reporter and partner carry aggregates (TOTAL, EU27_2020) that double-count when summed with their members." - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code does not exist (HTTP 404 carrying Eurostat error id 100). `no_results`: The query matched no observation cells — including Eurostat HTTP-200 error id 100. The dataset is valid, but no cell carries a value or a status flag for that filter combination and period range. When Eurostat returns the empty table, the error names the filter values that matched nothing (data.unmatchedValues) and the selected periods that carry no value (data.matchedPeriods, the newest 24, with data.matchedPeriodCount counting all of them). `invalid_period`: since_period or until_period is not a period literal, or names a month, quarter, semester, trimester, week or day that does not exist, or since_period starts after until_period ends. Checked before any request; a period Eurostat itself rejects maps here too. `async_response`: Eurostat returned an async warning or HTTP-413 error array — the query matched too many observations. `invalid_dimension`: A dimension code in filters does not exist in this dataset (HTTP 400, Eurostat error id 150). `conflicting_params`: Mutually exclusive parameters were combined: \"geo\" filter + geo_level, or since_period/until_period + last_n_periods. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code does not exist (HTTP 404 carrying Eurostat error id 100). `no_results`: The query matched no observation cells — including Eurostat HTTP-200 error id 100. The dataset is valid, but no cell carries a value or a status flag for that filter combination and period range. When Eurostat returns the empty table, the error names the filter values that matched nothing (data.unmatchedValues) and the selected periods that carry no value (data.matchedPeriods, the newest 24, with data.matchedPeriodCount counting all of them). `invalid_period`: since_period or until_period is not a period literal, or names a month, quarter, semester, trimester, week or day that does not exist, or since_period starts after until_period ends. Checked before any request; a period Eurostat itself rejects maps here too. `async_response`: Eurostat returned an async warning or an HTTP-413 error array — the query matched too many observations, including an EXTRACTION_TOO_BIG refusal past Eurostat's 5,000,000-row limit. `invalid_dimension`: A dimension code in filters does not exist in this dataset (HTTP 400, Eurostat error id 150). `conflicting_params`: Mutually exclusive parameters were combined: \"geo\" filter + geo_level, or since_period/until_period + last_n_periods. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / observations / items / properties / value / descriptionPrevious value: -"Numeric observation value, or null when Eurostat reports none — either unavailable in the source data or withheld, in which case confStatus says so."New value: +"Numeric observation value, or null when Eurostat reports none — unavailable in the source data, withheld (confStatus says so), or published as text (valueText holds it)." - added
Output schema / properties / observations / items / properties / valueTextAdded value: +{ + "description": "A value Eurostat published as text rather than a number, verbatim — PRODCOM (DS-*) flag and unit indicators such as QNTUNIT publish a unit like \"KG\" — with value null. PRODCOM's \":C\" is decoded to confStatus \"C\" instead. Omitted for numeric and missing values.", + "type": "string" +} - changed
Output schema / properties / tableName / descriptionPrevious value: -"Canvas table holding every matched observation in flat form — one code column per dimension plus a \"_label\" companion, then obs_value, obs_flag, obs_flag_label, conf_status, conf_status_label. Call eurostat_dataframe_describe with canvasId first to confirm the table and columns, then eurostat_dataframe_query. Omitted when nothing was staged: either the match was at or below 5,000 observations, or this deployment runs without a dataframe canvas."New value: +"Canvas table holding every matched observation in flat form — one code column per dimension plus a \"_label\" companion, then obs_value, obs_flag, obs_flag_label, conf_status, conf_status_label. A DS-* table also carries obs_value_text, the valueText of each row. Call eurostat_dataframe_describe with canvasId first to confirm the table and columns, then eurostat_dataframe_query. Omitted when nothing was staged: either the match was at or below 5,000 observations, or this deployment runs without a dataframe canvas."
- Changed
eurostat_search_datasets1 field changed- changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `no_match`: No datasets matched the query string. `invalid_cursor`: The cursor is malformed, came from a different query, or came from a catalogue snapshot that has since refreshed. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `no_match`: No datasets matched the query string — including a query naming a DS-* code that neither the dissemination table of contents nor the Comext dataflow list carries, which is a collection Eurostat does not disseminate. `invalid_cursor`: The cursor is malformed, came from a different query, or came from a catalogue snapshot that has since refreshed. Other values are possible when a failure originates below the handler."
2 tool updates
- Changed
eurostat_download_dataset11 fields changed- changed
Input schema / properties / filters / descriptionPrevious value: -"Dimension filters as a map of dimension code → array of accepted values, applied by Eurostat before the body is sent. Example: {\"unit\": [\"CP_MEUR\"], \"na_item\": [\"B1G\"], \"geo\": [\"DE\", \"FR\"]}. Omit a dimension or pass an empty array to accept every value for it. Do not put \"time\" here — use since_period/until_period. Naming a dimension the dataset does not have is rejected with the dataset's dimension list rather than silently ignored."New value: +"Dimension filters as a map of dimension code → array of accepted values, applied by Eurostat before the body is sent. Example: {\"unit\": [\"CP_MEUR\"], \"na_item\": [\"B1G\"], \"geo\": [\"DE\", \"FR\"]}. Omit a dimension or pass an empty array to accept every value for it. Dimension codes match in any case (\"GEO\" is geo). Do not put \"time\" here — use since_period/until_period. Naming a dimension the dataset does not have is rejected with the dataset's dimension list rather than silently ignored." - changed
Input schema / properties / since_period / descriptionPrevious value: -"Start of the period range (e.g., \"2020\", \"2023-Q1\", \"2024-01\"), sent as startPeriod. The most effective way to shrink a bulk response: it removes period columns from the TSV rather than blanking their cells."New value: +"Start of the period range, inclusive, sent as startPeriod. Accepted forms: YYYY, YYYY-MM, YYYY-MM-DD, YYYY-Qn (1–4), YYYY-Sn (1–2), YYYY-Tn (1–3), YYYY-Mnn (01–12), YYYY-Wnn (a week the year has, up to 53) or YYYY-Dnnn (a day the year has, up to 366) (e.g., \"2020\", \"2023-Q1\", \"2024-01\"). Extra leading zeros after the letter are dropped (\"2020-W001\" is sent as \"2020-W01\"), a day of the year is sent as three digits (\"2026-D1\" as \"2026-D001\"), YYYY-A1 is sent as YYYY, and a period of another frequency is mapped onto the dataset's own. A malformed or non-existent period (e.g., \"2020-13\") is rejected as invalid_period. The most effective way to shrink a bulk response: it removes period columns from the TSV rather than blanking their cells." - changed
Input schema / properties / until_period / descriptionPrevious value: -"End of the period range (e.g., \"2024\"), sent as endPeriod. Omit for data through the latest available period."New value: +"End of the period range, inclusive (e.g., \"2024\"), sent as endPeriod, in the same forms as since_period. Omit for data through the latest available period. The range must hold at least one day: a since_period that starts after until_period ends is rejected as invalid_period, while pairs of different frequencies are fine (\"2020-06\" to \"2020\")." - changed
Output schema / anyOfPrevious value: -[ - { - "not": { - "required": [ - "error" - ] - }, - "required": [ - "datasetCode", - "dimensionsUsed", - "rowCount", - "missingCount", - "periodRange", - "bytesRead", - "compressed", - "budgetExceeded", - "observations", - "appliedQuery" - ] - }, - { - "required": [ - "error" - ] - } -]New value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "datasetCode", + "dimensionsUsed", + "rowCount", + "missingCount", + "periodRange", + "bytesRead", + "compressed", + "budgetExceeded", + "observations", + "totalCount", + "appliedQuery" + ] + }, + { + "required": [ + "error" + ] + } +] - removed
Output schema / properties / capRemoved value: -{ - "description": "The preview_limit applied to inline observations.", - "type": "number" -} - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code is not available for dissemination (HTTP 404, SDMX faultcode 100). `invalid_dimension`: A filter names a dimension the dataset does not have, or a value or period range Eurostat rejects (SDMX faultcode 150). `filter_arity`: Eurostat rejected the positional dimension key because it carried the wrong number of positions (SDMX faultcode 140), meaning the dataset structure has changed since the metadata call. `async_queued`: Eurostat answered HTTP 200 with a SOAP syncResponse queue ticket (status SUBMITTED) instead of data, because the extraction was too costly to serve synchronously. `no_results`: The download completed but carried no populated observation cells. `upstream_fault`: The SDMX endpoint returned a fault this server does not model, or a body that is not a TSV table. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code is not available for dissemination (HTTP 404, SDMX faultcode 100). `invalid_dimension`: A filter names a dimension the dataset does not have, or a value or period range Eurostat rejects (SDMX faultcode 150). `filter_arity`: Eurostat rejected the positional dimension key because it carried the wrong number of positions (SDMX faultcode 140, INVALID_QUERY_NB_FILTERS), meaning the dataset structure has changed since the metadata call. `invalid_period`: since_period or until_period is not a period literal, or names a month, quarter, semester, trimester, week or day that does not exist, or since_period starts after until_period ends. Checked before any request — the bulk endpoint would otherwise roll an out-of-range period into a neighbouring one, and answer an inverted range with the whole series — and SDMX faultcode 140 TIME_PERIOD_FILTER_SPEC_INVALID maps here too. `async_queued`: Eurostat answered HTTP 200 with a SOAP syncResponse queue ticket (status SUBMITTED) instead of data, because the extraction was too costly to serve synchronously. `no_results`: The download completed but carried no populated observation cells. `upstream_fault`: The SDMX endpoint returned a fault this server does not model, or a body that is not a TSV table. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "not_found", - "invalid_dimension", - "filter_arity", - "async_queued", - "no_results", - "upstream_fault", - "canvas_not_found" -]New value: +[ + "not_found", + "invalid_dimension", + "filter_arity", + "invalid_period", + "async_queued", + "no_results", + "upstream_fault", + "canvas_not_found" +] - changed
Output schema / properties / notice / descriptionPrevious value: -"Guidance for every staged result, including the required eurostat_dataframe_describe then eurostat_dataframe_query sequence, composed with byte-budget, no-canvas, or empty-result disclosure when applicable."New value: +"Guidance on every download: the staged table with the required eurostat_dataframe_describe then eurostat_dataframe_query sequence (or, without a canvas, what was returned inline and what was discarded), preceded by byte-budget disclosure when the budget stopped the transfer and by the inline-preview length when preview_limit returns fewer rows than were downloaded." - removed
Output schema / properties / shownRemoved value: -{ - "description": "Observations returned in the inline preview.", - "type": "number" -} - added
Output schema / properties / totalCountAdded value: +{ + "description": "Observations the download produced — equal to rowCount. The inline observations array holds only the first preview_limit of them; budgetExceeded, not this count, says whether the download is the whole dataset.", + "type": "number" +} - removed
Output schema / properties / truncatedRemoved value: -{ - "description": "True when the inline observation preview omits rows.", - "type": "boolean" -}
- Changed
eurostat_query_dataset8 fields changed- changed
Input schema / properties / filters / descriptionPrevious value: -"Dimension filters as a map of dimension code → array of valid values. Example: {\"unit\": [\"CP_MEUR\"], \"na_item\": [\"B1GQ\"], \"geo\": [\"DE\", \"FR\"]}. An empty array is treated as no filter for that dimension and is dropped from the request. Do not include \"geo\" here if using geo_level. Invalid dimension values silently return no data — verify with eurostat_get_dimension_values first."New value: +"Dimension filters as a map of dimension code → array of valid values. Example: {\"unit\": [\"CP_MEUR\"], \"na_item\": [\"B1GQ\"], \"geo\": [\"DE\", \"FR\"]}. An empty array is treated as no filter for that dimension and is dropped from the request. Dimension codes match in any case (\"GEO\" is geo). Do not include \"geo\" here if using geo_level. A value that matches nothing contributes no rows rather than an error; the response names it in unmatchedValues, or in the no_results error when nothing matched at all. eurostat_get_dimension_values lists the valid values." - changed
Input schema / properties / last_n_periods / descriptionPrevious value: -"Return only the N most recent periods. Mutually exclusive with since_period and until_period."New value: +"Return only the N most recent periods. N counts back from the dataset's latest period, not from the latest period published for this slice, so a slice that lags the rest of the dataset can come back empty — raise N, or use until_period ending at a period the slice has published. Mutually exclusive with since_period and until_period." - changed
Input schema / properties / since_period / descriptionPrevious value: -"Start of time range (e.g., \"2020\", \"2023-Q1\", \"2024-01\"). Mutually exclusive with last_n_periods."New value: +"Start of the time range, inclusive. Accepted forms: YYYY, YYYY-MM, YYYY-MM-DD, YYYY-Qn (1–4), YYYY-Sn (1–2), YYYY-Tn (1–3), YYYY-Mnn (01–12), YYYY-Wnn (a week the year has, up to 53) or YYYY-Dnnn (a day the year has, up to 366) (e.g., \"2020\", \"2023-Q1\", \"2024-01\"). Extra leading zeros after the letter are dropped (\"2020-Q01\" is sent as \"2020-Q1\"), a day of the year is sent as three digits (\"2026-D1\" as \"2026-D001\"), and YYYY-A1 is sent as YYYY. A period of another frequency is mapped onto the dataset's own, so \"2020-01\" works on annual data. A malformed or non-existent period (e.g., \"2020-13\") is rejected as invalid_period. Mutually exclusive with last_n_periods." - changed
Input schema / properties / until_period / descriptionPrevious value: -"End of time range (e.g., \"2024\"). Omit for data through the latest available period. Mutually exclusive with last_n_periods."New value: +"End of the time range, inclusive (e.g., \"2024\"), in the same forms as since_period. Omit for data through the latest available period. The range must hold at least one day: a since_period that starts after until_period ends is rejected as invalid_period, while pairs of different frequencies are fine (\"2020-06\" to \"2020\"). Mutually exclusive with last_n_periods." - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code does not exist (HTTP 404 carrying Eurostat error id 100). `no_results`: The query matched no observation cells — including Eurostat HTTP-200 error id 100. The dataset is valid, but no cell carries a value or a status flag for that filter combination and period range. `async_response`: Eurostat returned an async warning or HTTP-413 error array — the query matched too many observations. `invalid_dimension`: A dimension code in filters does not exist in this dataset (HTTP 400, Eurostat error id 150). `conflicting_params`: Mutually exclusive parameters were combined: \"geo\" filter + geo_level, or since_period/until_period + last_n_periods. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code does not exist (HTTP 404 carrying Eurostat error id 100). `no_results`: The query matched no observation cells — including Eurostat HTTP-200 error id 100. The dataset is valid, but no cell carries a value or a status flag for that filter combination and period range. When Eurostat returns the empty table, the error names the filter values that matched nothing (data.unmatchedValues) and the selected periods that carry no value (data.matchedPeriods, the newest 24, with data.matchedPeriodCount counting all of them). `invalid_period`: since_period or until_period is not a period literal, or names a month, quarter, semester, trimester, week or day that does not exist, or since_period starts after until_period ends. Checked before any request; a period Eurostat itself rejects maps here too. `async_response`: Eurostat returned an async warning or HTTP-413 error array — the query matched too many observations. `invalid_dimension`: A dimension code in filters does not exist in this dataset (HTTP 400, Eurostat error id 150). `conflicting_params`: Mutually exclusive parameters were combined: \"geo\" filter + geo_level, or since_period/until_period + last_n_periods. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "not_found", - "no_results", - "async_response", - "invalid_dimension", - "conflicting_params", - "canvas_not_found" -]New value: +[ + "not_found", + "no_results", + "invalid_period", + "async_response", + "invalid_dimension", + "conflicting_params", + "canvas_not_found" +] - changed
Output schema / properties / notice / descriptionPrevious value: -"Guidance when preview_limit omits matched rows or the match was staged — distinguishes the inline prefix from filters that reduce the match and, when staged, gives the describe-then-query sequence. Omitted when the preview contains the whole match."New value: +"Guidance when a filter value matched nothing, when preview_limit omits matched rows, or when the match was staged — names the unmatched values, distinguishes the inline prefix from filters that reduce the match and, when staged, gives the describe-then-query sequence. Omitted when every filter value matched and the preview contains the whole match." - added
Output schema / properties / unmatchedValuesAdded value: +{ + "additionalProperties": { + "items": { + "type": "string" + }, + "type": "array" + }, + "description": "Filter values that matched nothing in the dataset, keyed by dimension code and spelled as sent (matching ignores case). The observations cover only the values that did match. Omitted when every filter value matched.", + "propertyNames": { + "type": "string" + }, + "type": "object" +}
4 tool updates
- Changed
eurostat_dataframe_describe2 fields changed- removed
Input schema / properties / canvas_id / minLengthRemoved value: -1 - added
Input schema / properties / canvas_id / patternAdded value: +"^[A-Za-z0-9_-]{10}$"
- Changed
eurostat_dataframe_query2 fields changed- removed
Input schema / properties / canvas_id / minLengthRemoved value: -1 - added
Input schema / properties / canvas_id / patternAdded value: +"^[A-Za-z0-9_-]{10}$"
- Changed
eurostat_download_dataset2 fields changed- changed
Input schema / properties / canvas_id / descriptionPrevious value: -"Reuse an existing dataframe canvas so this download lands beside earlier results and can be joined against them. Pass a canvasId from a previous response; omit to start a fresh canvas. Ignored on deployments without a dataframe canvas."New value: +"Reuse an existing dataframe canvas so this download lands beside earlier results and can be joined against them. Pass the canvasId a previous eurostat_download_dataset or eurostat_query_dataset response returned; omit to start a fresh canvas. Ignored on deployments without a dataframe canvas." - added
Input schema / properties / canvas_id / patternAdded value: +"^[A-Za-z0-9_-]{10}$"
- Changed
eurostat_query_dataset2 fields changed- changed
Input schema / properties / canvas_id / descriptionPrevious value: -"Reuse an existing dataframe canvas, so a result staged by this call lands beside earlier ones and can be joined against them. Pass a canvasId from a previous response; omit to start a fresh canvas. Ignored on deployments without a dataframe canvas and when the match is at or below 5,000 observations."New value: +"Reuse an existing dataframe canvas, so a result staged by this call lands beside earlier ones and can be joined against them. Pass the canvasId a previous eurostat_query_dataset or eurostat_download_dataset response returned; omit to start a fresh canvas. Ignored on deployments without a dataframe canvas and when the match is at or below 5,000 observations." - added
Input schema / properties / canvas_id / patternAdded value: +"^[A-Za-z0-9_-]{10}$"
2 tool updates
- Changed
eurostat_download_dataset2 fields changed- removed
Output schema / properties / observations / items / additionalProperties / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / observations / items / additionalProperties / typeAdded value: +[ + "string", + "number", + "null" +]
- Changed
eurostat_query_dataset2 fields changed- removed
Output schema / properties / observations / items / properties / value / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / observations / items / properties / value / typeAdded value: +[ + "number", + "null" +]
5 tool updates
- Changed
eurostat_browse_themes2 fields changed- changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `not_found`: The provided theme_code does not exist as a folder in the TOC. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `not_found`: The provided theme_code does not exist in the TOC. `not_a_folder`: The provided theme_code identifies a dataset or table entry instead of a folder. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "not_found" -]New value: +[ + "not_found", + "not_a_folder" +]
- Changed
eurostat_download_dataset2 fields changed- changed
Output schema / properties / notice / descriptionPrevious value: -"Guidance when the download was cut short by the byte budget, when nothing could be staged, or when it returned no observations. Omitted otherwise."New value: +"Guidance for every staged result, including the required eurostat_dataframe_describe then eurostat_dataframe_query sequence, composed with byte-budget, no-canvas, or empty-result disclosure when applicable." - changed
Output schema / properties / tableName / descriptionPrevious value: -"Canvas table holding every downloaded observation. Omitted when this deployment runs without a dataframe canvas, in which case only the inline preview survives the call."New value: +"Canvas table holding every downloaded observation. Call eurostat_dataframe_describe with canvasId first to confirm the table and columns, then eurostat_dataframe_query. Omitted when this deployment runs without a dataframe canvas, in which case only the inline preview survives the call."
- Changed
eurostat_get_dataset_info2 fields changed- changed
Output schema / properties / dimensions / items / properties / sampleValues / descriptionPrevious value: -"First 10 dimension values for orientation. Use eurostat_get_dimension_values for the full list. Omitted alongside valuesCount when the value set could not be measured."New value: +"First 10 dataset-available values for orientation. Use eurostat_get_dimension_values for the full constrained list. Omitted alongside valuesCount when Eurostat does not supply a measurable value set." - changed
Output schema / properties / dimensions / items / properties / valuesCount / descriptionPrevious value: -"Number of distinct values in this dimension. For \"time\" this is the dataset's full period count; every other dimension is counted from the most recent period. Omitted when the value set could not be measured — only \"time\" can be, and an omitted count is unknown, not one. Call eurostat_get_dimension_values for that dimension to obtain it."New value: +"Number of dataset-available values in this dimension, taken from the dataset content constraint. For \"time\" this is the full period count. Omitted only when Eurostat does not supply a measurable value set."
- Changed
eurostat_get_dimension_values5 fields changed- changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code or dimension code does not exist. `async_response`: Eurostat returned an async warning — the dimension query matched too many observations. `conflicting_params`: geo_level was combined with a dimension other than \"geo\", where it has no effect. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code or dimension code does not exist. `async_response`: Eurostat returned an asynchronous-response condition. `no_results`: The dataset has no geo values at the effective geo_level. `conflicting_params`: geo_level was combined with a dimension other than \"geo\", where it has no effect. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "not_found", - "async_response", - "conflicting_params" -]New value: +[ + "not_found", + "async_response", + "no_results", + "conflicting_params" +] - added
Output schema / properties / geoLevelAdded value: +{ + "description": "Effective NUTS hierarchy level for the geo value set. Present only for the geo dimension; country is reported when geo_level was omitted.", + "enum": [ + "aggregate", + "country", + "nuts1", + "nuts2", + "nuts3" + ], + "type": "string" +} - changed
Output schema / properties / totalCount / descriptionPrevious value: -"Total number of distinct values returned."New value: +"Total number of distinct values returned, after geoLevel filtering for geo." - changed
Output schema / properties / values / descriptionPrevious value: -"All valid values for this dimension in the dataset."New value: +"All dataset-available values for this dimension. For geo, this is the subset at geoLevel."
- Changed
eurostat_query_dataset7 fields changed- changed
Input schema / properties / canvas_id / descriptionPrevious value: -"Reuse an existing dataframe canvas, so a result staged by this call lands beside earlier ones and can be joined against them. Pass a canvasId from a previous response; omit to start a fresh canvas. Ignored on deployments without a dataframe canvas, and when the result fits inline and nothing is staged."New value: +"Reuse an existing dataframe canvas, so a result staged by this call lands beside earlier ones and can be joined against them. Pass a canvasId from a previous response; omit to start a fresh canvas. Ignored on deployments without a dataframe canvas and when the match is at or below 5,000 observations." - added
Input schema / properties / preview_limitAdded value: +{ + "default": 50, + "description": "How many matched observations to return inline, from the deterministic start of the JSON-stat cell order. Default 50; maximum 500. This changes only the inline prefix: it does not reduce obsCount, missingObsCount, timeRange, the upstream response, or the rows staged when the match exceeds 5,000. Use filters or period controls to reduce the match itself.", + "maximum": 500, + "minimum": 1, + "type": "integer" +} - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code does not exist (HTTP 404, Eurostat error id 100). `no_results`: The query matched no observation cells — valid dataset, but no cell carries a value or a status flag for that filter combination and period range. `async_response`: Eurostat returned an async warning — the query matched too many observations. `invalid_dimension`: A dimension code in filters does not exist in this dataset (HTTP 400, Eurostat error id 150). `conflicting_params`: Mutually exclusive parameters were combined: \"geo\" filter + geo_level, or since_period/until_period + last_n_periods. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code does not exist (HTTP 404 carrying Eurostat error id 100). `no_results`: The query matched no observation cells — including Eurostat HTTP-200 error id 100. The dataset is valid, but no cell carries a value or a status flag for that filter combination and period range. `async_response`: Eurostat returned an async warning or HTTP-413 error array — the query matched too many observations. `invalid_dimension`: A dimension code in filters does not exist in this dataset (HTTP 400, Eurostat error id 150). `conflicting_params`: Mutually exclusive parameters were combined: \"geo\" filter + geo_level, or since_period/until_period + last_n_periods. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / notice / descriptionPrevious value: -"Guidance when the result was capped at 5,000 rows — where the rest of the match is, or how to narrow the query. Omitted for uncapped results."New value: +"Guidance when preview_limit omits matched rows or the match was staged — distinguishes the inline prefix from filters that reduce the match and, when staged, gives the describe-then-query sequence. Omitted when the preview contains the whole match." - changed
Output schema / properties / observations / descriptionPrevious value: -"Decoded observations, capped at 5,000 rows. Past the cap these are the first 5,000 the response enumerates — the leading combinations of the dataset dimensions, neither a sample nor the most recent periods. When tableName is set, these same rows and every row past the cap are staged on the dataframe canvas; when it is absent, narrow the query with dimension filters or a period range to choose which observations you get, or switch to eurostat_download_dataset when the whole dataset is what is wanted."New value: +"The first preview_limit decoded observations in deterministic JSON-stat cell order — the leading combinations of the dataset dimensions, neither a sample nor necessarily the most recent periods. This prefix is independent of the 5,000-observation staging threshold. When tableName is set, the table holds every matched row; otherwise use filters or a period range to reduce the match itself." - changed
Output schema / properties / tableName / descriptionPrevious value: -"Canvas table holding every matched observation in flat form — one code column per dimension plus a \"_label\" companion, then obs_value, obs_flag, obs_flag_label, conf_status, conf_status_label. The five measure columns match the ones eurostat_download_dataset stages, so the two tables join on dimension codes and time and compare like with like. Omitted when nothing was staged: either the result fit under the cap, or this deployment runs without a dataframe canvas."New value: +"Canvas table holding every matched observation in flat form — one code column per dimension plus a \"_label\" companion, then obs_value, obs_flag, obs_flag_label, conf_status, conf_status_label. Call eurostat_dataframe_describe with canvasId first to confirm the table and columns, then eurostat_dataframe_query. Omitted when nothing was staged: either the match was at or below 5,000 observations, or this deployment runs without a dataframe canvas." - changed
Output schema / properties / truncated / descriptionPrevious value: -"True when the result exceeded 5,000 observations, so the returned rows are a prefix of the match rather than all of it. When tableName is set, the whole match is on the canvas and reachable with eurostat_dataframe_query; when it is absent, narrowing the query with dimension filters, or downloading the dataset with eurostat_download_dataset, is what brings the rest into reach."New value: +"True only when the match exceeded the 5,000-observation staging threshold. Independent of preview_limit: observations can be a shorter prefix while truncated is false. When tableName is set, call eurostat_dataframe_describe first and then eurostat_dataframe_query; when it is absent, use filters or period controls to reduce the match."
8 tool updates
- Changed
eurostat_browse_themes6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "items", + "parentPath", + "itemCount" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `not_found`: The provided theme_code does not exist as a folder in the TOC. Other values are possible when a failure originates below the handler.", + "examples": [ + "not_found" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "items", - "parentPath", - "itemCount" -]
- Changed
eurostat_dataframe_describe6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "canvasId", + "expiresAt", + "tables" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `canvas_disabled`: This deployment runs without a dataframe canvas, so there is nothing to describe. `canvas_not_found`: The canvas_id is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler.", + "examples": [ + "canvas_disabled", + "canvas_not_found" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "canvasId", - "expiresAt", - "tables" -]
- Changed
eurostat_dataframe_query6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "canvasId", + "columns", + "rows", + "rowCount", + "truncated" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `canvas_disabled`: This deployment runs without a dataframe canvas, so there is nothing to query. `canvas_not_found`: The canvas_id is unknown or its lifetime has elapsed. `missing_table`: The SQL names a table that is not staged on this canvas, or that has expired. Other values are possible when a failure originates below the handler.", + "examples": [ + "canvas_disabled", + "canvas_not_found", + "missing_table" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "canvasId", - "columns", - "rows", - "rowCount", - "truncated" -]
- Changed
eurostat_download_dataset9 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "datasetCode", + "dimensionsUsed", + "rowCount", + "missingCount", + "periodRange", + "bytesRead", + "compressed", + "budgetExceeded", + "observations", + "appliedQuery" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / capAdded value: +{ + "description": "The preview_limit applied to inline observations.", + "type": "number" +} - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code is not available for dissemination (HTTP 404, SDMX faultcode 100). `invalid_dimension`: A filter names a dimension the dataset does not have, or a value or period range Eurostat rejects (SDMX faultcode 150). `filter_arity`: Eurostat rejected the positional dimension key because it carried the wrong number of positions (SDMX faultcode 140), meaning the dataset structure has changed since the metadata call. `async_queued`: Eurostat answered HTTP 200 with a SOAP syncResponse queue ticket (status SUBMITTED) instead of data, because the extraction was too costly to serve synchronously. `no_results`: The download completed but carried no populated observation cells. `upstream_fault`: The SDMX endpoint returned a fault this server does not model, or a body that is not a TSV table. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler.", + "examples": [ + "not_found", + "invalid_dimension", + "filter_arity", + "async_queued", + "no_results", + "upstream_fault", + "canvas_not_found" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - added
Output schema / properties / shownAdded value: +{ + "description": "Observations returned in the inline preview.", + "type": "number" +} - added
Output schema / properties / truncatedAdded value: +{ + "description": "True when the inline observation preview omits rows.", + "type": "boolean" +} - removed
Output schema / requiredRemoved value: -[ - "datasetCode", - "dimensionsUsed", - "rowCount", - "missingCount", - "periodRange", - "bytesRead", - "compressed", - "budgetExceeded", - "observations", - "appliedQuery" -]
- Changed
eurostat_get_dataset_info6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "code", + "label", + "dimensions", + "timeRange" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code does not exist or is not available for dissemination. `async_response`: Eurostat returned an async response (query too large for the API). Other values are possible when a failure originates below the handler.", + "examples": [ + "not_found", + "async_response" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "code", - "label", - "dimensions", - "timeRange" -]
- Changed
eurostat_get_dimension_values6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "dimensionCode", + "dimensionLabel", + "values", + "totalCount" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code or dimension code does not exist. `async_response`: Eurostat returned an async warning — the dimension query matched too many observations. `conflicting_params`: geo_level was combined with a dimension other than \"geo\", where it has no effect. Other values are possible when a failure originates below the handler.", + "examples": [ + "not_found", + "async_response", + "conflicting_params" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "dimensionCode", - "dimensionLabel", - "values", - "totalCount" -]
- Changed
eurostat_query_dataset6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "datasetCode", + "datasetLabel", + "dimensionsUsed", + "observations", + "obsCount", + "truncated", + "timeRange", + "missingObsCount", + "appliedFilters" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code does not exist (HTTP 404, Eurostat error id 100). `no_results`: The query matched no observation cells — valid dataset, but no cell carries a value or a status flag for that filter combination and period range. `async_response`: Eurostat returned an async warning — the query matched too many observations. `invalid_dimension`: A dimension code in filters does not exist in this dataset (HTTP 400, Eurostat error id 150). `conflicting_params`: Mutually exclusive parameters were combined: \"geo\" filter + geo_level, or since_period/until_period + last_n_periods. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler.", + "examples": [ + "not_found", + "no_results", + "async_response", + "invalid_dimension", + "conflicting_params", + "canvas_not_found" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "datasetCode", - "datasetLabel", - "dimensionsUsed", - "observations", - "obsCount", - "truncated", - "timeRange", - "missingObsCount", - "appliedFilters" -]
- Changed
eurostat_search_datasets6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "datasets", + "query", + "totalMatches", + "truncated" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `no_match`: No datasets matched the query string. `invalid_cursor`: The cursor is malformed, came from a different query, or came from a catalogue snapshot that has since refreshed. Other values are possible when a failure originates below the handler.", + "examples": [ + "no_match", + "invalid_cursor" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "datasets", - "query", - "totalMatches", - "truncated" -]
1 tool update
- Changed
eurostat_query_dataset7 fields changed- changed
Output schema / properties / missingObsCount / descriptionPrevious value: -"Number of matched observations with null value (missing data points in the source), counted across everything matched rather than only the returned rows."New value: +"Number of matched observations carrying no numeric value, counted across everything matched rather than only the returned rows. Covers both unavailable and withheld cells — a slice can be wholly confidential, so this equalling obsCount does not mean the data is absent." - changed
Output schema / properties / observations / items / descriptionPrevious value: -"A single decoded observation with dimension values, numeric value, and optional status."New value: +"A single decoded observation with dimension values, numeric value, and the optional OBS_FLAG and CONF_STATUS markers." - added
Output schema / properties / observations / items / properties / confStatusAdded value: +{ + "additionalProperties": false, + "description": "Eurostat CONF_STATUS for this observation — a different codelist from status. Present when Eurostat restricts the cell, which is usually why value is null. Omitted otherwise.", + "properties": { + "code": { + "description": "CONF_STATUS code: \"C\", \"N\", or \"P\".", + "type": "string" + }, + "label": { + "description": "Confidentiality description (e.g., \"confidential\", \"not for publication\").", + "type": "string" + } + }, + "required": [ + "code", + "label" + ], + "type": "object" +} - changed
Output schema / properties / observations / items / properties / status / descriptionPrevious value: -"Status flag for this observation. Omitted for normal observations."New value: +"Eurostat OBS_FLAG for this observation. Omitted for unflagged observations, and never carries a confidentiality code — that arrives in confStatus." - changed
Output schema / properties / observations / items / properties / status / properties / code / descriptionPrevious value: -"Status flag code (e.g., \"p\", \"e\", \"d\")."New value: +"OBS_FLAG code (e.g., \"p\", \"e\", \"d\")." - changed
Output schema / properties / observations / items / properties / value / descriptionPrevious value: -"Numeric observation value, or null when missing (flagged as unavailable in the source data)."New value: +"Numeric observation value, or null when Eurostat reports none — either unavailable in the source data or withheld, in which case confStatus says so." - changed
Output schema / properties / tableName / descriptionPrevious value: -"Canvas table holding every matched observation in flat form — one code column per dimension plus a \"_label\" companion, then obs_value, obs_flag, obs_flag_label. Omitted when nothing was staged: either the result fit under the cap, or this deployment runs without a dataframe canvas."New value: +"Canvas table holding every matched observation in flat form — one code column per dimension plus a \"_label\" companion, then obs_value, obs_flag, obs_flag_label, conf_status, conf_status_label. The five measure columns match the ones eurostat_download_dataset stages, so the two tables join on dimension codes and time and compare like with like. Omitted when nothing was staged: either the result fit under the cap, or this deployment runs without a dataframe canvas."
7 tool updates
- Changed
eurostat_dataframe_describe1 field changed- changed
Input schema / properties / canvas_id / descriptionPrevious value: -"Canvas identifier returned by eurostat_query_dataset as canvasId. Identifies the workspace holding the staged tables."New value: +"Canvas identifier returned as canvasId by eurostat_query_dataset or eurostat_download_dataset. Identifies the workspace holding the staged tables."
- Changed
eurostat_dataframe_query1 field changed- changed
Input schema / properties / canvas_id / descriptionPrevious value: -"Canvas identifier returned by eurostat_query_dataset as canvasId. Identifies the workspace holding the staged tables."New value: +"Canvas identifier returned as canvasId by eurostat_query_dataset or eurostat_download_dataset. Identifies the workspace holding the staged tables."
- Added
eurostat_download_dataset - Changed
eurostat_get_dataset_info1 field changed- changed
Output schema / properties / dimensions / items / properties / code / descriptionPrevious value: -"Dimension code (e.g., \"unit\", \"geo\", \"na_item\"). Use these as filter keys in eurostat_query_dataset."New value: +"Dimension code (e.g., \"unit\", \"geo\", \"na_item\"). Use these as filter keys in eurostat_query_dataset and eurostat_download_dataset."
- Changed
eurostat_get_dimension_values1 field changed- changed
Output schema / properties / values / items / properties / code / descriptionPrevious value: -"Dimension value code. Use these as filter values in eurostat_query_dataset."New value: +"Dimension value code. Use these as filter values in eurostat_query_dataset and eurostat_download_dataset."
- Changed
eurostat_query_dataset2 fields changed- changed
Output schema / properties / observations / descriptionPrevious value: -"Decoded observations, capped at 5,000 rows. Past the cap these are the first 5,000 the response enumerates — the leading combinations of the dataset dimensions, neither a sample nor the most recent periods. When tableName is set, these same rows and every row past the cap are staged on the dataframe canvas; when it is absent, narrow the query with dimension filters or a period range to choose which observations you get."New value: +"Decoded observations, capped at 5,000 rows. Past the cap these are the first 5,000 the response enumerates — the leading combinations of the dataset dimensions, neither a sample nor the most recent periods. When tableName is set, these same rows and every row past the cap are staged on the dataframe canvas; when it is absent, narrow the query with dimension filters or a period range to choose which observations you get, or switch to eurostat_download_dataset when the whole dataset is what is wanted." - changed
Output schema / properties / truncated / descriptionPrevious value: -"True when the result exceeded 5,000 observations, so the returned rows are a prefix of the match rather than all of it. When tableName is set, the whole match is on the canvas and reachable with eurostat_dataframe_query; when it is absent, narrowing the query with dimension filters is what brings the rest into reach."New value: +"True when the result exceeded 5,000 observations, so the returned rows are a prefix of the match rather than all of it. When tableName is set, the whole match is on the canvas and reachable with eurostat_dataframe_query; when it is absent, narrowing the query with dimension filters, or downloading the dataset with eurostat_download_dataset, is what brings the rest into reach."
- Changed
eurostat_search_datasets1 field changed- changed
Output schema / properties / datasets / items / properties / code / descriptionPrevious value: -"Dataset code (e.g., \"nama_10_gdp\"). Use this in eurostat_get_dataset_info and eurostat_query_dataset."New value: +"Dataset code (e.g., \"nama_10_gdp\"). Use this in eurostat_get_dataset_info, eurostat_query_dataset, and eurostat_download_dataset."
3 tool updates
- Added
eurostat_dataframe_describe - Added
eurostat_dataframe_query - Changed
eurostat_query_dataset7 fields changed- added
Input schema / properties / canvas_idAdded value: +{ + "description": "Reuse an existing dataframe canvas, so a result staged by this call lands beside earlier ones and can be joined against them. Pass a canvasId from a previous response; omit to start a fresh canvas. Ignored on deployments without a dataframe canvas, and when the result fits inline and nothing is staged.", + "type": "string" +} - added
Output schema / properties / canvasIdAdded value: +{ + "description": "Dataframe canvas holding the staged result. Pass to eurostat_dataframe_describe, eurostat_dataframe_query, or a later eurostat_query_dataset call. Omitted when nothing was staged.", + "type": "string" +} - changed
Output schema / properties / notice / descriptionPrevious value: -"Guidance when the result was truncated at 5,000 rows. Omitted for normal results."New value: +"Guidance when the result was capped at 5,000 rows — where the rest of the match is, or how to narrow the query. Omitted for uncapped results." - changed
Output schema / properties / observations / descriptionPrevious value: -"Decoded observations, capped at 5,000 rows. Past the cap these are the first 5,000 the response enumerates — the leading combinations of the dataset dimensions, neither a sample nor the most recent periods — so narrow the query with dimension filters or a period range to choose which observations you get."New value: +"Decoded observations, capped at 5,000 rows. Past the cap these are the first 5,000 the response enumerates — the leading combinations of the dataset dimensions, neither a sample nor the most recent periods. When tableName is set, these same rows and every row past the cap are staged on the dataframe canvas; when it is absent, narrow the query with dimension filters or a period range to choose which observations you get." - added
Output schema / properties / stagedRowCountAdded value: +{ + "description": "Rows written to the canvas table. Matches obsCount. Omitted alongside tableName when nothing was staged.", + "type": "number" +} - added
Output schema / properties / tableNameAdded value: +{ + "description": "Canvas table holding every matched observation in flat form — one code column per dimension plus a \"_label\" companion, then obs_value, obs_flag, obs_flag_label. Omitted when nothing was staged: either the result fit under the cap, or this deployment runs without a dataframe canvas.", + "type": "string" +} - changed
Output schema / properties / truncated / descriptionPrevious value: -"True when the result exceeded 5,000 observations and was capped. Apply dimension filters to get the full result."New value: +"True when the result exceeded 5,000 observations, so the returned rows are a prefix of the match rather than all of it. When tableName is set, the whole match is on the canvas and reachable with eurostat_dataframe_query; when it is absent, narrowing the query with dimension filters is what brings the rest into reach."
3 tool updates
- Changed
eurostat_browse_themes1 field changed- added
Output schema / properties / otherPlacementsAdded value: +{ + "description": "Breadcrumbs of the other branches that file this same theme_code. Eurostat lists a few folder codes in more than one branch; the items above come from the first one the catalogue lists, which never has fewer children than the branches named here but can list different ones. theme_code takes a bare code, so those branches cannot be addressed directly — browse down to them from the root instead. Omitted when the code has a single placement — the normal case.", + "items": { + "description": "Breadcrumb from root to one other folder carrying the requested code.", + "items": { + "type": "string" + }, + "type": "array" + }, + "type": "array" +}
- Changed
eurostat_get_dataset_info3 fields changed- changed
Output schema / properties / dimensions / items / properties / sampleValues / descriptionPrevious value: -"First 10 dimension values for orientation. Use eurostat_get_dimension_values for the full list."New value: +"First 10 dimension values for orientation. Use eurostat_get_dimension_values for the full list. Omitted alongside valuesCount when the value set could not be measured." - changed
Output schema / properties / dimensions / items / properties / valuesCount / descriptionPrevious value: -"Number of distinct values in this dimension. For \"time\" this is the dataset's full period count; every other dimension is counted from the most recent period."New value: +"Number of distinct values in this dimension. For \"time\" this is the dataset's full period count; every other dimension is counted from the most recent period. Omitted when the value set could not be measured — only \"time\" can be, and an omitted count is unknown, not one. Call eurostat_get_dimension_values for that dimension to obtain it." - changed
Output schema / properties / dimensions / items / requiredPrevious value: -[ - "code", - "label", - "valuesCount", - "sampleValues" -]New value: +[ + "code", + "label" +]
- Changed
eurostat_query_dataset5 fields changed- changed
Output schema / properties / missingObsCount / descriptionPrevious value: -"Number of observations with null value (missing data points in the source)."New value: +"Number of matched observations with null value (missing data points in the source), counted across everything matched rather than only the returned rows." - changed
Output schema / properties / observations / descriptionPrevious value: -"Decoded observations, capped at 5,000 rows. When truncated is true, apply dimension filters to narrow the result."New value: +"Decoded observations, capped at 5,000 rows. Past the cap these are the first 5,000 the response enumerates — the leading combinations of the dataset dimensions, neither a sample nor the most recent periods — so narrow the query with dimension filters or a period range to choose which observations you get." - changed
Output schema / properties / timeRange / descriptionPrevious value: -"Time coverage of the returned observations. Each bound is omitted when neither the observations nor Eurostat report it — an omitted bound is unknown, not empty."New value: +"Time coverage of everything matched — the same set obsCount counts, so it can reach periods absent from observations when truncated is true. Each bound is omitted when neither the match nor Eurostat report it — an omitted bound is unknown, not empty." - changed
Output schema / properties / timeRange / properties / end / descriptionPrevious value: -"Most recent period in this result. Omitted when the observations carry no time dimension and Eurostat reports no overall period."New value: +"Most recent period matched. Omitted when the match carries no time dimension and Eurostat reports no overall period." - changed
Output schema / properties / timeRange / properties / start / descriptionPrevious value: -"Earliest period in this result. Omitted when the observations carry no time dimension and Eurostat reports no overall period."New value: +"Earliest period matched. Omitted when the match carries no time dimension and Eurostat reports no overall period."
3 tool updates
- Changed
eurostat_get_dataset_info8 fields changed- changed
Output schema / properties / dimensions / items / properties / valuesCount / descriptionPrevious value: -"Number of distinct values in this dimension for the most recent period."New value: +"Number of distinct values in this dimension. For \"time\" this is the dataset's full period count; every other dimension is counted from the most recent period." - changed
Output schema / properties / lastUpdated / descriptionPrevious value: -"ISO 8601 timestamp of the most recent data update."New value: +"ISO 8601 timestamp of the most recent data update. Omitted when Eurostat does not report it." - changed
Output schema / properties / obsCount / descriptionPrevious value: -"Total number of observations in the full dataset (all periods)."New value: +"Total number of observations in the full dataset (all periods). Omitted when Eurostat does not report it — an omitted count is unknown, not zero." - changed
Output schema / properties / timeRange / descriptionPrevious value: -"Overall data coverage period for this dataset."New value: +"Overall data coverage period for this dataset. Each bound is omitted when Eurostat does not report it — an omitted bound is unknown, not empty." - changed
Output schema / properties / timeRange / properties / end / descriptionPrevious value: -"Most recent available period (e.g., \"2024\")."New value: +"Most recent available period (e.g., \"2024\"). Omitted when Eurostat does not report it." - changed
Output schema / properties / timeRange / properties / start / descriptionPrevious value: -"Earliest available period (e.g., \"1975\")."New value: +"Earliest available period (e.g., \"1975\"). Omitted when Eurostat does not report it." - removed
Output schema / properties / timeRange / requiredRemoved value: -[ - "start", - "end" -] - changed
Output schema / requiredPrevious value: -[ - "code", - "label", - "dimensions", - "timeRange", - "obsCount", - "lastUpdated" -]New value: +[ + "code", + "label", + "dimensions", + "timeRange" +]
- Changed
eurostat_get_dimension_values1 field changed- changed
Input schema / properties / geo_level / descriptionPrevious value: -"NUTS hierarchy level filter — only relevant when dimension is \"geo\". Options: \"aggregate\" (EU/EA codes), \"country\" (2-letter codes, default), \"nuts1\" (3-char), \"nuts2\" (4-char), \"nuts3\" (5-char)."New value: +"NUTS hierarchy level filter — applies only when dimension is \"geo\"; passing it with any other dimension is rejected. Options: \"aggregate\" (EU/EA codes), \"country\" (2-letter codes, default), \"nuts1\" (3-char), \"nuts2\" (4-char), \"nuts3\" (5-char)."
- Changed
eurostat_query_dataset6 fields changed- changed
Input schema / properties / filters / descriptionPrevious value: -"Dimension filters as a map of dimension code → array of valid values. Example: {\"unit\": [\"CP_MEUR\"], \"na_item\": [\"B1GQ\"], \"geo\": [\"DE\", \"FR\"]}. Do not include \"geo\" here if using geo_level. Invalid dimension values silently return no data — verify with eurostat_get_dimension_values first."New value: +"Dimension filters as a map of dimension code → array of valid values. Example: {\"unit\": [\"CP_MEUR\"], \"na_item\": [\"B1GQ\"], \"geo\": [\"DE\", \"FR\"]}. An empty array is treated as no filter for that dimension and is dropped from the request. Do not include \"geo\" here if using geo_level. Invalid dimension values silently return no data — verify with eurostat_get_dimension_values first." - changed
Output schema / properties / appliedFilters / properties / filters / descriptionPrevious value: -"Dimension filters that were applied."New value: +"Dimension filters actually sent to Eurostat. Empty arrays from the request are dropped and do not appear here." - changed
Output schema / properties / timeRange / descriptionPrevious value: -"Time coverage of the returned observations."New value: +"Time coverage of the returned observations. Each bound is omitted when neither the observations nor Eurostat report it — an omitted bound is unknown, not empty." - changed
Output schema / properties / timeRange / properties / end / descriptionPrevious value: -"Most recent period in this result."New value: +"Most recent period in this result. Omitted when the observations carry no time dimension and Eurostat reports no overall period." - changed
Output schema / properties / timeRange / properties / start / descriptionPrevious value: -"Earliest period in this result."New value: +"Earliest period in this result. Omitted when the observations carry no time dimension and Eurostat reports no overall period." - removed
Output schema / properties / timeRange / requiredRemoved value: -[ - "start", - "end" -]
2 tool updates
- Changed
eurostat_browse_themes2 fields changed- changed
Input schema / properties / theme_code / descriptionPrevious value: -"Folder code to expand (e.g., \"econ\", \"reg\"). Omit to list the top-level theme folders."New value: +"Folder code to expand (e.g., \"economy\", \"reg\"). Omit to list the top-level theme folders." - changed
Output schema / properties / parentPath / descriptionPrevious value: -"Breadcrumb from root to the requested theme (e.g., [\"Economy and finance\", \"National accounts\"]). Empty when browsing root."New value: +"Breadcrumb from root to the requested theme (e.g., [\"Database by themes\", \"Economy and finance\"]). Empty when browsing root."
- Changed
eurostat_search_datasets6 fields changed- changed
Input schema / properties / cursor / descriptionPrevious value: -"Opaque pagination cursor from a previous call's nextCursor. Omit for the first page; pass it back to fetch the next page of matches over a stable order."New value: +"Opaque pagination cursor from a previous call's nextCursor. Omit for the first page; pass it back — with the same query — to fetch the next page of matches over a stable order. A cursor is bound to the query that produced it and to the catalogue snapshot in effect at that time, so reusing one with a different query, or after the catalogue refreshes, is rejected rather than silently paging a different result set." - changed
Input schema / properties / query / descriptionPrevious value: -"Search terms. Split on whitespace into tokens; every token must match (AND), case-insensitively, somewhere across the dataset label, theme breadcrumb, or code. Word order does not matter, so \"business demography NUTS 3\" or \"regional economic accounts\" resolve without naming a label verbatim."New value: +"Search terms — at least one non-whitespace token is required. Split on whitespace into tokens; every token must match (AND), case-insensitively, somewhere across the dataset label, theme breadcrumb, or code. Word order does not matter, so \"business demography NUTS 3\" or \"regional economic accounts\" resolve without naming a label verbatim." - added
Input schema / properties / query / patternAdded value: +"\\S" - changed
Output schema / properties / datasets / items / properties / themePath / descriptionPrevious value: -"Breadcrumb path from root theme to this dataset (e.g., [\"Economy and finance\", \"National accounts\"]). Empty for top-level entries."New value: +"Breadcrumb path from root theme to this dataset (e.g., [\"Database by themes\", \"Economy and finance\"]). Eurostat files some datasets under several branches; this is the first branch that matched the query. Empty for top-level entries." - changed
Output schema / properties / nextCursor / descriptionPrevious value: -"Opaque cursor for the next page of matches. Pass it back as cursor. Omitted on the last page."New value: +"Opaque cursor for the next page of matches. Pass it back as cursor with the same query; it stops working once the catalogue refreshes. Omitted on the last page." - changed
Output schema / properties / totalMatches / descriptionPrevious value: -"Total datasets matching the query across all pages, before the page limit."New value: +"Total distinct dataset codes matching the query across all pages, before the page limit."
2 tool updates
- Changed
eurostat_browse_themes3 fields changed- changed
Input schema / properties / theme_code / descriptionPrevious value: -"Folder code to expand (e.g., \"econ\", \"reg\"). Omit to list the 11 top-level theme folders."New value: +"Folder code to expand (e.g., \"econ\", \"reg\"). Omit to list the top-level theme folders." - changed
Output schema / properties / items / descriptionPrevious value: -"Immediate children of the requested theme, or the 11 root themes if theme_code was omitted."New value: +"Immediate children of the requested theme, or the root themes if theme_code was omitted." - added
Output schema / properties / nextStepAdded value: +{ + "description": "Suggested next action based on these results. Populated when there is a clear follow-up call.", + "type": "string" +}
- Changed
eurostat_search_datasets9 fields changed- added
Input schema / properties / cursorAdded value: +{ + "description": "Opaque pagination cursor from a previous call's nextCursor. Omit for the first page; pass it back to fetch the next page of matches over a stable order.", + "type": "string" +} - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum number of results to return (1–100). Default is 20."New value: +"Page size — maximum datasets returned per page (1–100). Default is 20. To retrieve matches beyond one page, pass the returned nextCursor back as cursor; the page size is fixed by this first call." - changed
Input schema / properties / query / descriptionPrevious value: -"Search terms — case-insensitive substring match against dataset labels."New value: +"Search terms. Split on whitespace into tokens; every token must match (AND), case-insensitively, somewhere across the dataset label, theme breadcrumb, or code. Word order does not matter, so \"business demography NUTS 3\" or \"regional economic accounts\" resolve without naming a label verbatim." - changed
Output schema / properties / datasets / descriptionPrevious value: -"Matching datasets, up to the requested limit."New value: +"Matching datasets for the current page, up to the requested limit." - added
Output schema / properties / nextCursorAdded value: +{ + "description": "Opaque cursor for the next page of matches. Pass it back as cursor. Omitted on the last page.", + "type": "string" +} - added
Output schema / properties / nextStepAdded value: +{ + "description": "Suggested next action based on these results. Populated when there is a clear follow-up call.", + "type": "string" +} - changed
Output schema / properties / totalMatches / descriptionPrevious value: -"Total datasets matching the query before the limit."New value: +"Total datasets matching the query across all pages, before the page limit." - added
Output schema / properties / truncatedAdded value: +{ + "description": "True when more matches remain beyond this page — pass nextCursor as cursor to fetch them.", + "type": "boolean" +} - changed
Output schema / requiredPrevious value: -[ - "datasets", - "query", - "totalMatches" -]New value: +[ + "datasets", + "query", + "totalMatches", + "truncated" +]
Related MCP Connectors
Access European statistics: GDP, unemployment, inflation, population data.
Eurostat MCP — wraps Eurostat Statistical Data API (no auth required)
UK Office for National Statistics dataset catalogue + Beta JSON API
Query official statistics of Catalonia (Idescat): tables, metadata and JSON-stat data via MCP.
Related MCP Servers
- AlicenseAqualityBmaintenanceMCP server for Eurostat statistics, enabling seamless search, query, and analysis of over 8,900 EU datasets with support for SDMX, DuckDB SQL, NUTS regional filtering, and CSV export.121MIT
- FlicenseNot gradedqualityDmaintenanceExposes the Eurostat Statistics API, enabling LLMs to discover, explore, and retrieve official EU statistical data through search, dimension inspection, and data retrieval tools.3-
- FlicenseNot gradedqualityDmaintenanceEU economic statistics — GDP, inflation, unemployment, trade, population-
- AlicenseNot gradedqualityBmaintenanceEnables querying Eurostat statistical data through natural language or direct MCP tools, wrapping the Eurostat API without authentication.185 npmMIT
Glama MCP Gateway
Add one secure layer between your agents and this server.