protogrid

Search / io.github.cyanheads/eurostat-mcp-server

eurostat-mcp-server

R0· no sign-in

Search and query the Eurostat catalogue — EU economy, demography, trade, and NUTS regional data.

v0.10.0 · active · repository · descriptor JSON · versions

An agent can connect right now, no human step.Remote endpoint, no authentication, reachable on the last probe.
Quality70needs work
Trust94of 100
Uptime, 30 days99%
Latency p50180 ms

Connect

8 clients · secrets stay placeholders
{
  "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

Quality 70 / 100needs work

protocol88 · weight 25
  • pass
    protocol.modernsupports 2026-07-28 (server/discover)
  • pass
    protocol.statelessanswers without a session
  • pass
    protocol.transportstreamable HTTP
  • warn
    protocol.list_ttltools/list declares ttlMs 0, so clients re-fetch it on every use
authorizationn/a · weight 15
  • n/a
    auth.prm, auth.as_metadata, auth.cimdno remote uses OAuth
  • n/a
    auth.secret_in_urlno templated URL
tool hygiene79 · weight 30
  • pass
    tools.descriptionsevery tool has a description
  • warn
    tools.description_length5 tools have descriptions over 1,024 characters, which crowds the context
  • pass
    tools.schemasevery tool has an object input schema
  • pass
    tools.annotations8 of 8 tools declare readOnlyHint or destructiveHint
  • fail
    tools.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); …
  • pass
    tools.token_costabout 5,938 tokens to load every tool
  • pass
    tools.api_dumptools are not a one-to-one API dump
stability25 · weight 15
  • warn
    stability.changes14 tool changes in 30 days
  • fail
    stability.rug_pull2 tools kept their name but changed most of their description in 30 days; review before trusting them
dependenciesn/a · weight 15

8 tools, about 5,938 tokens to load them all · tool set 801877095f77 · tools last changed 2026-10-15 · checked 2026-10-19 20:06 UTC

Tool changes

  • eurostat_download_datasetchangedinput schema, output schema
  • eurostat_query_datasetchangedinput schema, output schema
  • eurostat_get_dimension_valueschangeddescription, input schema, output schema
    before

    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.

    after · 79% of words in common

    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 schema
  • eurostat_browse_themeschangedoutput schema
  • eurostat_search_datasetschangedinput schema, output schema
  • eurostat_dataframe_querychangeddescription, input schema
    before

    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 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.

    after · 82% of words in common

    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 schema
    before

    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. 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.

    after · 74% of words in common

    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 schema
  • eurostat_query_datasetchangedinput schema, output schema

Showing 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.

Trust 94 / 100

provenance80
liveness100
freshness100
hygiene100

+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.

Dependencies

@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.

Endpoints

remoteauthreachableuptime 30dp50protocollast ok
https://eurostat.caseyjhand.com/mcp streamable-httpnoneyes99%180 ms2026-07-282026-10-19
packageregistryversionruntimesecrets
@cyanheads/eurostat-mcp-servernpm0.10.0npx
@cyanheads/eurostat-mcp-servernpm0.10.0npx

Tools (8)

eurostat_browse_themesread-onlyNavigate 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-onlyList 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-onlyRun 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-onlyDownload 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-onlyFetch 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-onlyList 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-onlyFetch 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-onlySearch 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.

Similar MCP servers

More from io.github.cyanheads

And 136 more from this publisher.

Official server.json
{
  "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."
}