Wraps the Eurostat Statistics and TOC APIs to make 8,933 EU datasets searchable and queryable through MCP. You get five tools: keyword search across the catalogue, theme tree navigation, dataset metadata inspection, dimension value enumeration, and filtered data queries with NUTS geo-level support. The query tool decodes JSON-stat 2.0 responses into labeled observations and catches Eurostat's async-response warnings before they silently fail. Useful when you need programmatic access to EU economy, demography, trade, or regional statistics without manually navigating the web interface or writing your own API client. Ships with a public hosted instance at eurostat.caseyjhand.com and runs locally via stdio or HTTP.
Search and query 8,933 Eurostat datasets — EU economy, demography, trade, health, and NUTS regional data via MCP. STDIO or Streamable HTTP.
Public Hosted Server: https://eurostat.caseyjhand.com/mcp
5 tools for discovering and querying Eurostat statistical datasets:
| Tool | Description |
|---|---|
eurostat_search_datasets | Search the Eurostat catalogue (8,933 datasets) by keyword — returns codes, descriptions, period coverage, and theme breadcrumbs |
eurostat_browse_themes | Navigate the Eurostat theme hierarchy — list root themes or drill into subthemes and datasets |
eurostat_get_dataset_info | Fetch metadata for a dataset: dimensions with sample values, time range, observation count, and last-update date |
eurostat_get_dimension_values | List all valid codes for a specific dimension (e.g., all geo codes, all unit codes); supports NUTS hierarchy filtering |
eurostat_query_dataset | Fetch decoded statistical observations with dimension filters, NUTS geo-level, and time-range controls |
eurostat_search_datasetsSearch the Eurostat dataset catalogue by keyword.
eurostat_browse_themes for structured domain exploration when keywords are uncleareurostat_browse_themesNavigate the Eurostat theme tree.
theme_code: returns the 11 top-level themes (Economy and finance, Population, Transport, etc.)theme_code: returns immediate children — subtheme folders and datasets in that brancheurostat_get_dataset_infoFetch metadata for a Eurostat dataset before querying it.
eurostat_get_dimension_values for the full listeurostat_get_dimension_valuesList all valid values for a specific dataset dimension.
geo dimension, supports NUTS hierarchy filtering: aggregate (EU/EA totals), country (41 states), nuts1 (127 major regions), nuts2 (309 basic regions), nuts3 (1,343 small regions)eurostat_query_dataset return nothing without error; verify codes here firsteurostat_query_datasetFetch statistical data from a Eurostat dataset.
{dimension_code: [value1, value2, ...]}aggregate, country, nuts1, nuts2, nuts3) — mutually exclusive with a geo key in filterssince_period/until_period (e.g., "2020", "2023-Q1") or last_n_periods for the N most recentp = provisional, e = estimated, etc.)| Type | Name | Description |
|---|---|---|
| Resource | eurostat://dataset/{dataset_code} | Dataset metadata (dimensions, time range, obs count, last-updated) accessible by URI for cache-injectable context |
Built on @cyanheads/mcp-ts-core:
none, jwt, oauth)in-memory, filesystem, Supabase, Cloudflare KV/R2/D1Eurostat-specific:
Agent-friendly output:
eurostat_search_datasets / eurostat_browse_themes → eurostat_get_dataset_info → eurostat_get_dimension_values → eurostat_query_dataseteurostat_get_dimension_values tool prevents this by letting agents verify codes firstA public instance is available at https://eurostat.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"eurostat-mcp-server": {
"type": "streamable-http",
"url": "https://eurostat.caseyjhand.com/mcp"
}
}
}
Add the following to your MCP client configuration file.
{
"mcpServers": {
"eurostat-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/eurostat-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"eurostat-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/eurostat-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with Docker:
{
"mcpServers": {
"eurostat-mcp-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/eurostat-mcp-server:latest"]
}
}
}
For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
git clone https://github.com/cyanheads/eurostat-mcp-server.git
cd eurostat-mcp-server
bun install
All configuration is validated at startup via Zod schemas in src/config/server-config.ts. Key environment variables:
| Variable | Description | Default |
|---|---|---|
MCP_TRANSPORT_TYPE | Transport: stdio or http | stdio |
MCP_HTTP_PORT | HTTP server port | 3010 |
MCP_HTTP_ENDPOINT_PATH | HTTP endpoint path | /mcp |
MCP_PUBLIC_URL | Public origin override for TLS-terminating reverse-proxy deployments | none |
MCP_AUTH_MODE | Authentication: none, jwt, or oauth | none |
MCP_LOG_LEVEL | Log level (debug, info, warning, error, etc.) | info |
MCP_GC_PRESSURE_INTERVAL_MS | Opt-in Bun-only forced-GC pressure loop (ms). Recommended starting point if heap growth is observed: 60000. | 0 (disabled) |
LOGS_DIR | Directory for log files (Node.js only) | <project-root>/logs |
STORAGE_PROVIDER_TYPE | Storage backend: in-memory, filesystem, supabase, cloudflare-kv/r2/d1 | in-memory |
EUROSTAT_BASE_URL | Eurostat API base URL | https://ec.europa.eu/eurostat/api/dissemination |
EUROSTAT_REQUEST_TIMEOUT_MS | HTTP request timeout in ms | 30000 |
OTEL_ENABLED | Enable OpenTelemetry | false |
Build and run the production version:
# One-time build
bun run rebuild
# Run the built server
bun run start:http
# or
bun run start:stdio
Run checks and tests:
bun run devcheck # Lints, formats, type-checks, and more
bun run test # Runs the test suite
| Directory | Purpose |
|---|---|
src/mcp-server/tools | Tool definitions (*.tool.ts). Five tools for discovery and data access. |
src/mcp-server/resources | Resource definitions. Dataset metadata resource. |
src/services/eurostat-catalogue | Catalogue service — fetches and parses the Eurostat TOC TXT file; session-level in-memory cache. |
src/services/eurostat-data | Data service — Statistics API HTTP client, JSON-stat 2.0 decoder, async-response detection. |
src/config | Server-specific environment variable parsing and validation with Zod. |
tests/ | Unit and integration tests, mirroring the src/ structure. |
See CLAUDE.md for development guidelines and architectural rules. The short version:
try/catch in tool logicctx.log for logging, ctx.state for storagecreateApp() arraysIssues and pull requests are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
This project is licensed under the Apache 2.0 License. See the LICENSE file for details.
MCP_LOG_LEVELdefault: infoSets the minimum log level for output (e.g., 'debug', 'info', 'warn').
EUROSTAT_BASE_URLdefault: https://ec.europa.eu/eurostat/api/disseminationEurostat API base URL. Override when using a mirror or proxy.
EUROSTAT_REQUEST_TIMEOUT_MSdefault: 30000HTTP request timeout in milliseconds for Eurostat API calls.
MCP_HTTP_HOSTdefault: 127.0.0.1The hostname for the HTTP server.
MCP_HTTP_PORTdefault: 3010The port to run the HTTP server on.
MCP_HTTP_ENDPOINT_PATHdefault: /mcpThe endpoint path for the MCP server.
MCP_PUBLIC_URLPublic origin override for deployments behind a TLS-terminating reverse proxy (e.g. https://mcp.example.com).
MCP_AUTH_MODEdefault: noneAuthentication mode to use: 'none', 'jwt', or 'oauth'.
com.mcparmory/google-search
io.github.pipeworx-io/brave-search
marcopesani/mcp-server-serper
brave/brave-search-mcp-server
com.mcparmory/google-search-console
acamolese/google-search-console-mcp