Search / io.github.cyanheads/eurostat-mcp-server
eurostat-mcp-server
R0· no sign-inSearch and query the Eurostat catalogue — EU economy, demography, trade, and NUTS regional data.
v0.10.0 · active · repository · descriptor JSON · versions
Search / io.github.cyanheads/eurostat-mcp-server
R0· no sign-inSearch and query the Eurostat catalogue — EU economy, demography, trade, and NUTS regional data.
v0.10.0 · active · repository · descriptor JSON · versions
{
"mcpServers": {
"eurostat-mcp-server": {
"type": "http",
"url": "https://eurostat.caseyjhand.com/mcp"
}
}
}claude mcp add --transport http eurostat-mcp-server https://eurostat.caseyjhand.com/mcp[mcp_servers.eurostat-mcp-server]
url = "https://eurostat.caseyjhand.com/mcp"
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"eurostat-mcp-server": {
"type": "remote",
"url": "https://eurostat.caseyjhand.com/mcp",
"enabled": true
}
}
}{
"mcpServers": {
"eurostat-mcp-server": {
"type": "http",
"url": "https://eurostat.caseyjhand.com/mcp"
}
},
"deeplink": "cursor://anysphere.cursor-deeplink/mcp/install?name=eurostat-mcp-server&config=eyJ0eXBlIjoiaHR0cCIsInVybCI6Imh0dHBzOi8vZXVyb3N0YXQuY2FzZXlqaGFuZC5jb20vbWNwIn0%3D"
}{
"servers": {
"eurostat-mcp-server": {
"type": "http",
"url": "https://eurostat.caseyjhand.com/mcp"
}
}
}{
"mcpServers": {
"eurostat-mcp-server": {
"httpUrl": "https://eurostat.caseyjhand.com/mcp"
}
}
}extensions:
"eurostat-mcp-server":
enabled: true
name: "eurostat-mcp-server"
type: streamable_http
uri: "https://eurostat.caseyjhand.com/mcp"
timeout: 300
protocol.modernsupports 2026-07-28 (server/discover)protocol.statelessanswers without a sessionprotocol.transportstreamable HTTPprotocol.list_ttltools/list declares ttlMs 0, so clients re-fetch it on every useauth.prm, auth.as_metadata, auth.cimdno remote uses OAuthauth.secret_in_urlno templated URLtools.descriptionsevery tool has a descriptiontools.description_length5 tools have descriptions over 1,024 characters, which crowds the contexttools.schemasevery tool has an object input schematools.annotations8 of 8 tools declare readOnlyHint or destructiveHinttools.directory_hintsno tool declares all four of readOnlyHint, destructiveHint, idempotentHint and openWorldHint; missing: eurostat_search_datasets (destructiveHint); eurostat_get_dataset_info (destructiveHint); eurostat_get_dimension_values (destructiveHint); …tools.token_costabout 5,938 tokens to load every tooltools.api_dumptools are not a one-to-one API dumpstability.changes14 tool changes in 30 daysstability.rug_pull2 tools kept their name but changed most of their description in 30 days; review before trusting themdeps.known_vulns, deps.mcp_sdk_version, deps.resolvabledeps.dev does not know @cyanheads/[email protected], @cyanheads/[email protected]eurostat_download_datasetchangedinput schema, output schemaeurostat_query_datasetchangedinput schema, output schemaeurostat_get_dimension_valueschangeddescription, input schema, output schemaList 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.
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. To find one code in a long list, such as the 37,069 CN8 product codes of DS-045409, pass filter: words its code or label contains. A long list comes back a page at a time, each response held to 64,000 bytes; a page with more after it carries nextCursor — pass it back as cursor for the next page. 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.
eurostat_get_dataset_infochangedoutput schemaeurostat_browse_themeschangedoutput schemaeurostat_search_datasetschangedinput schema, output schemaeurostat_dataframe_querychangeddescription, input schemaRun 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 two stagers. 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 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.
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.
eurostat_dataframe_describechangeddescription, input schemaList 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. Every observation column is flat, but the two stagers write different dimension columns, so read the columns reported here rather than assuming: 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 tables from the two stagers join on dimension codes and time and compare like with like.
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).
eurostat_download_datasetchangedinput schema, output schemaeurostat_query_datasetchangedinput schema, output schemaShowing the latest 10. Full history: list_changes · trend: quality JSON.
Checks run on what our credential-free, read-only probes observe; tools are never called and no code audit is performed. How it is computed.
+repository +namespace-matches-repo +reachable +uptime-99% +updated-5d-ago
Derived from observable signals (official registry feed and our own credential-free probes); no code audit performed. How it is computed.
@cyanheads/[email protected] npmthis version is not known to the dependency resolver
@cyanheads/[email protected] npmthis version is not known to the dependency resolver
Dependency graphs from deps.dev; advisories from OSV.dev, including the GitHub Advisory Database and the PyPI Advisory Database; all CC BY 4.0. The graph is what a clean install of this version resolves today; nothing was installed or run. How it is checked.
| remote | auth | reachable | uptime 30d | p50 | protocol | last ok |
|---|---|---|---|---|---|---|
https://eurostat.caseyjhand.com/mcp streamable-http | none | yes | 99% | 180 ms | 2026-07-28 | 2026-10-19 |
| package | registry | version | runtime | secrets |
|---|---|---|---|---|
@cyanheads/eurostat-mcp-server | npm | 0.10.0 | npx | |
@cyanheads/eurostat-mcp-server | npm | 0.10.0 | npx |
eurostat_browse_themesread-only | 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. |
eurostat_dataframe_describeread-only | 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). |
eurostat_dataframe_queryread-only | 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. |
eurostat_download_datasetread-only | 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. |
eurostat_get_dataset_inforead-only | 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. |
eurostat_get_dimension_valuesread-only | 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. To find one code in a long list, such as the 37,069 CN8 product codes of DS-045409, pass filter: words its code or label contains. A long list comes back a page at a time, each response held to 64,000 bytes; a page with more after it carries nextCursor — pass it back as cursor for the next page. 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. |
eurostat_query_datasetread-only | 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. |
eurostat_search_datasetsread-only | 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. |
Schemas: list_tools.
And 136 more from this publisher.
{
"name": "io.github.cyanheads/eurostat-mcp-server",
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
"remotes": [
{
"url": "https://eurostat.caseyjhand.com/mcp",
"type": "streamable-http"
}
],
"version": "0.10.0",
"packages": [
{
"version": "0.10.0",
"transport": {
"type": "stdio"
},
"identifier": "@cyanheads/eurostat-mcp-server",
"runtimeHint": "npx",
"registryType": "npm",
"registryBaseUrl": "https://registry.npmjs.org",
"environmentVariables": [
{
"name": "MCP_LOG_LEVEL",
"format": "string",
"default": "info",
"description": "Sets the minimum log level for output (e.g., 'debug', 'info', 'warn')."
},
{
"name": "EUROSTAT_BASE_URL",
"format": "string",
"default": "https://ec.europa.eu/eurostat/api/dissemination",
"description": "Eurostat API base URL. Override when using a mirror or proxy."
},
{
"name": "EUROSTAT_COMEXT_BASE_URL",
"format": "string",
"default": "https://ec.europa.eu/eurostat/api/comext/dissemination",
"description": "Base URL of the Comext dissemination host, which serves every DS-* dataset code (detailed trade and PRODCOM). Override when using a mirror or proxy."
},
{
"name": "EUROSTAT_REQUEST_TIMEOUT_MS",
"format": "string",
"default": "30000",
"description": "HTTP request timeout in milliseconds for Eurostat API calls."
},
{
"name": "EUROSTAT_METADATA_TIMEOUT_MS",
"format": "string",
"default": "120000",
"description": "HTTP timeout for one dataset's SDMX dataflow structure, in milliseconds. Held separate from EUROSTAT_REQUEST_TIMEOUT_MS because the structure carries a label for every code the dataset uses: 23 MB, uncompressed, for DS-045409. Defaults to 2 minutes."
},
{
"name": "EUROSTAT_TOC_CACHE_TTL_MS",
"format": "string",
"default": "43200000",
"description": "How long a fetched catalogue TOC stays usable before the next catalogue call refreshes it, in milliseconds. Defaults to 12 hours."
},
{
"name": "EUROSTAT_BULK_TIMEOUT_MS",
"format": "string",
"default": "120000",
"description": "HTTP timeout for one eurostat_download_dataset transfer, in milliseconds. Held separate from EUROSTAT_REQUEST_TIMEOUT_MS because a bulk body streams for minutes where a metadata call answers in seconds. Defaults to 2 minutes."
},
{
"name": "EUROSTAT_BULK_MAX_BYTES",
"format": "string",
"default": "52428800",
"description": "Byte budget for one eurostat_download_dataset transfer, counted on the decoded TSV rather than on the wire. Eurostat sends the body chunked with no Content-Length, so the budget is enforced while streaming and the transfer is aborted when it is reached. Defaults to 50 MiB."
},
{
"name": "CANVAS_PROVIDER_TYPE",
"format": "string",
"default": "none",
"description": "Set to 'duckdb' to enable the dataframe canvas, which lists the eurostat_dataframe_describe and eurostat_dataframe_query tools, lets eurostat_query_dataset stage a match larger than its 5,000-row inline cap as a SQL table, and lets eurostat_download_dataset retain a whole bulk download instead of only its inline preview. The DuckDB binding ships with the server, so this variable is the only switch."
},
{
"name": "CANVAS_TEMP_PATH",
"format": "string",
"description": "Parent directory for DuckDB canvas spill files: a private 'mcp-canvas-XXXXXX' directory is created inside it, so it must be writable by the server process. Defaults to the OS temp directory."
},
{
"name": "CANVAS_TTL_MS",
"format": "string",
"default": "86400000",
"description": "Sliding lifetime of a staged dataframe canvas in milliseconds; every call against it extends the window. Defaults to 24 hours."
},
{
"name": "CANVAS_DEFAULT_ROW_LIMIT",
"format": "string",
"default": "10000",
"description": "Maximum rows a single eurostat_dataframe_query returns before the result is reported as truncated."
},
{
"name": "EUROSTAT_DATAFRAME_DROP_ENABLED",
"format": "boolean",
"default": "false",
"description": "Set to 'true' to list eurostat_dataframe_drop, which removes one staged table from a dataframe canvas and leaves its other tables in place. Off by default because a drop cannot be undone; staged tables expire with their canvas either way. Takes effect only with CANVAS_PROVIDER_TYPE=duckdb."
}
]
},
{
"version": "0.10.0",
"transport": {
"url": "http://localhost:3010/mcp",
"type": "streamable-http"
},
"identifier": "@cyanheads/eurostat-mcp-server",
"runtimeHint": "npx",
"registryType": "npm",
"registryBaseUrl": "https://registry.npmjs.org",
"environmentVariables": [
{
"name": "MCP_TRANSPORT_TYPE",
"value": "http",
"format": "string",
"description": "Selects the HTTP transport."
},
{
"name": "MCP_HTTP_HOST",
"format": "string",
"default": "127.0.0.1",
"description": "The hostname for the HTTP server."
},
{
"name": "MCP_HTTP_PORT",
"format": "string",
"default": "3010",
"description": "The port to run the HTTP server on."
},
{
"name": "MCP_HTTP_ENDPOINT_PATH",
"format": "string",
"default": "/mcp",
"description": "The endpoint path for the MCP server."
},
{
"name": "MCP_PUBLIC_URL",
"format": "string",
"description": "Public origin override for deployments behind a TLS-terminating reverse proxy (e.g. https://mcp.example.com)."
},
{
"name": "MCP_AUTH_MODE",
"format": "string",
"default": "none",
"description": "Authentication mode to use: 'none', 'jwt', or 'oauth'."
},
{
"name": "MCP_LOG_LEVEL",
"format": "string",
"default": "info",
"description": "Sets the minimum log level for output (e.g., 'debug', 'info', 'warn')."
},
{
"name": "EUROSTAT_BASE_URL",
"format": "string",
"default": "https://ec.europa.eu/eurostat/api/dissemination",
"description": "Eurostat API base URL. Override when using a mirror or proxy."
},
{
"name": "EUROSTAT_COMEXT_BASE_URL",
"format": "string",
"default": "https://ec.europa.eu/eurostat/api/comext/dissemination",
"description": "Base URL of the Comext dissemination host, which serves every DS-* dataset code (detailed trade and PRODCOM). Override when using a mirror or proxy."
},
{
"name": "EUROSTAT_REQUEST_TIMEOUT_MS",
"format": "string",
"default": "30000",
"description": "HTTP request timeout in milliseconds for Eurostat API calls."
},
{
"name": "EUROSTAT_METADATA_TIMEOUT_MS",
"format": "string",
"default": "120000",
"description": "HTTP timeout for one dataset's SDMX dataflow structure, in milliseconds. Held separate from EUROSTAT_REQUEST_TIMEOUT_MS because the structure carries a label for every code the dataset uses: 23 MB, uncompressed, for DS-045409. Defaults to 2 minutes."
},
{
"name": "EUROSTAT_TOC_CACHE_TTL_MS",
"format": "string",
"default": "43200000",
"description": "How long a fetched catalogue TOC stays usable before the next catalogue call refreshes it, in milliseconds. Defaults to 12 hours."
},
{
"name": "EUROSTAT_BULK_TIMEOUT_MS",
"format": "string",
"default": "120000",
"description": "HTTP timeout for one eurostat_download_dataset transfer, in milliseconds. Held separate from EUROSTAT_REQUEST_TIMEOUT_MS because a bulk body streams for minutes where a metadata call answers in seconds. Defaults to 2 minutes."
},
{
"name": "EUROSTAT_BULK_MAX_BYTES",
"format": "string",
"default": "52428800",
"description": "Byte budget for one eurostat_download_dataset transfer, counted on the decoded TSV rather than on the wire. Eurostat sends the body chunked with no Content-Length, so the budget is enforced while streaming and the transfer is aborted when it is reached. Defaults to 50 MiB."
},
{
"name": "CANVAS_PROVIDER_TYPE",
"format": "string",
"default": "none",
"description": "Set to 'duckdb' to enable the dataframe canvas, which lists the eurostat_dataframe_describe and eurostat_dataframe_query tools, lets eurostat_query_dataset stage a match larger than its 5,000-row inline cap as a SQL table, and lets eurostat_download_dataset retain a whole bulk download instead of only its inline preview. The DuckDB binding ships with the server, so this variable is the only switch."
},
{
"name": "CANVAS_TEMP_PATH",
"format": "string",
"description": "Parent directory for DuckDB canvas spill files: a private 'mcp-canvas-XXXXXX' directory is created inside it, so it must be writable by the server process. Defaults to the OS temp directory."
},
{
"name": "CANVAS_TTL_MS",
"format": "string",
"default": "86400000",
"description": "Sliding lifetime of a staged dataframe canvas in milliseconds; every call against it extends the window. Defaults to 24 hours."
},
{
"name": "CANVAS_DEFAULT_ROW_LIMIT",
"format": "string",
"default": "10000",
"description": "Maximum rows a single eurostat_dataframe_query returns before the result is reported as truncated."
},
{
"name": "EUROSTAT_DATAFRAME_DROP_ENABLED",
"format": "boolean",
"default": "false",
"description": "Set to 'true' to list eurostat_dataframe_drop, which removes one staged table from a dataframe canvas and leaves its other tables in place. Off by default because a drop cannot be undone; staged tables expire with their canvas either way. Takes effect only with CANVAS_PROVIDER_TYPE=duckdb."
}
]
}
],
"repository": {
"url": "https://github.com/cyanheads/eurostat-mcp-server",
"source": "github"
},
"description": "Search and query the Eurostat catalogue — EU economy, demography, trade, and NUTS regional data."
}