关于 eurostat-mcp-server
eurostat-mcp-server 面向需要使用欧盟统计数据的研究者和分析人员,可搜索目录、查询数据集并处理观测数据,涵盖经济、人口、贸易、健康及 NUTS 区域数据。它还支持将结果暂存到数据画布并用只读 SQL 查询。
主要功能
- 01搜索并浏览统计数据目录
- 02查看数据集维度和元数据
- 03按维度与时期筛选数据
- 04批量下载并暂存观测值
- 05在画布上运行只读 SQL
适用场景
- 01查找欧盟经济或人口统计数据
- 02提取特定地区和时期的数据
- 03比较 Comext 或 PRODCOM 数据
- 04对暂存数据执行 SQL 分析
MCP 相关
向 MCP 客户端提供 Eurostat 目录搜索、数据集查询、下载和画布分析工具,并提供数据集元数据资源及 eurostat-guide 技能。支持 STDIO 与 Streamable HTTP,也提供托管端点。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://eurostat.caseyjhand.com/mcpclaude mcp add --transport http cyanheads-eurostat https://eurostat.caseyjhand.com/mcp{"mcpServers":{"cyanheads-eurostat":{"type":"http","url":"https://eurostat.caseyjhand.com/mcp"}}}在 Cursor 中打开{"servers":{"cyanheads-eurostat":{"type":"http","url":"https://eurostat.caseyjhand.com/mcp"}}}在 VS Code 中打开{"mcpServers":{"cyanheads-eurostat":{"type":"http","url":"https://eurostat.caseyjhand.com/mcp"}}}{"mcpServers":{"cyanheads-eurostat":{"serverUrl":"https://eurostat.caseyjhand.com/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
8| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| limit | integer | 否 | 页面大小——每页返回的数据集上限(1–100)。默认值为 20。若要获取后续页的匹配项,请将返回的 nextCursor 作为 cursor 传回;页面大小由首次调用固定。 |
| query | string | 是 | 搜索词——至少需要一个非空白词元。按空白拆分为词元;每个词元都必须在数据集标签、主题层级路径或代码中的某处匹配(AND),且不区分大小写。目录中标点符号旁的空格会被忽略,因此“Rev.2”也能匹配“Rev. 2”,“2015=100”也能匹配“2015 = 100”;词元会保留自身标点,例如“R&D”、“non-EU”或“DS-045409”。词序无关,因此无需逐字指定标签,也能通过“business demography NUTS 3”或“regional economic accounts”找到结果。无匹配项时,错误会列出单独删除后即可找到匹配项的每个词。 |
| cursor | string | 否 | 来自先前调用的 nextCursor 的不透明分页游标。第一页时省略;后续请求时与相同查询一起传回,以按稳定顺序获取下一页匹配项。游标绑定到生成它的查询及当时生效的目录快照;因此,使用不同查询重用游标,或在目录刷新后重用游标,都会被拒绝,而不会静默翻页到不同的结果集。 |
详细介绍
@cyanheads/eurostat-mcp-server
通过 MCP 搜索和查询 Eurostat 目录,获取欧盟经济、人口、贸易、健康和 NUTS 区域数据。支持 STDIO 或 Streamable HTTP。
概述
Eurostat 的欧盟统计数据:经济、人口、贸易、健康和 NUTS 区域数据,包括详细的 Comext 贸易数据和 PRODCOM 工业生产数据。搜索或浏览目录,查看数据集的维度,然后查询部分数据或批量下载整个数据集。
工具
三个 eurostat_dataframe_* 工具需要数据框画布。该画布默认开启,可通过 CANVAS_PROVIDER_TYPE=none 关闭;eurostat_dataframe_drop 还需要 EUROSTAT_DATAFRAME_DROP_ENABLED=true。
| 工具 | 描述 |
|---|---|
eurostat_search_datasets | 按关键词搜索 Eurostat 目录——返回代码、描述、时期覆盖范围和主题路径 |
eurostat_browse_themes | 浏览 Eurostat 主题层级——列出根主题,或深入浏览子主题和数据集 |
eurostat_get_dataset_info | 获取数据集元数据:维度及示例值、时间范围、观测数量和最后更新时间 |
eurostat_get_dimension_values | 列出数据集某个维度的所有有效代码,支持分页、代码/标签词语筛选,以及针对 geo 的 NUTS 层级筛选 |
eurostat_query_dataset | 获取解码后观测值的有限预览,支持维度筛选、NUTS 地理级别和时间范围控制 |
eurostat_download_dataset | 通过 SDMX 批量端点下载整个数据集,并将所有观测值暂存到数据框画布 |
eurostat_dataframe_describe | 列出数据框画布上暂存的表,以及行数和列类型 |
eurostat_dataframe_query | 对暂存的表执行只读 SQL SELECT 查询 |
eurostat_dataframe_drop | 从数据框画布中移除一个暂存表,保留其他表(需主动启用) |
资源
| 资源 | 描述 |
|---|---|
eurostat://dataset/{dataset_code} | 通过 URI 获取数据集元数据(维度、时间范围、观测数量、最后更新时间) |
skill://eurostat-guide/SKILL.md | 统计比较条件、标识符来源和 SQL 分析工作流 |
仅使用工具的客户端也可以通过 eurostat_get_dataset_info 获取相同的元数据。
Agent 技能
eurostat-guide 涵盖国家和地区比较、Comext 汇总、缺失数据解读,以及对暂存观测值执行 SQL 联接。该技能随插件、npm、Docker 和 MCPB 安装包一同提供,并通过 MCP 在 skill://eurostat-guide/SKILL.md 提供;配套 SQL 示例位于该技能的 references/ 目录下。
功能参考
eurostat_search_datasets 工具
query中的词语会以不区分大小写的方式在每个数据集的标签、主题路径和代码中按 AND 条件匹配;会忽略标点符号旁的空格(Rev.2可找到Rev. 2);limit必须为正整数(默认为 20),超过 100 时会限制为 100 并显示提示。将nextCursor作为cursor传回即可翻页;使用游标时会忽略limit- 结果包含
code、label、type(dataset/table)、时期覆盖范围、obsCount、lastUpdated和themePath,并通过totalMatches提供所有页面的匹配总数;如果移除某些词语即可找到匹配项,则会以no_match失败并指出这些词语;也可能以invalid_cursor失败;若未加载目录且无法访问 Eurostat 目录表,则会以可重试的upstream_fault失败 - 如果无法加载 Comext 数据流列表,结果会包含
comextListMissing和notice;无法刷新的目录会包含catalogueLoadedAt
eurostat_browse_themes 工具
- 省略
theme_code可获取顶层主题文件夹;传入文件夹代码可获取其直接子项。代码会优先精确匹配,其次不区分大小写匹配。Comext 集合位于ext_go_detail(详细贸易数据,属于ext_go)和prom(PRODCOM,属于icts)下 - 条目包含
code、label、type(folder/dataset/table)和hasChildren,以及parentPath路径导航信息;对于归入多个分支的文件夹,还会包含otherPlacements。未知代码会以not_found失败;数据集或表代码会以not_a_folder失败;若未加载目录且无法访问 Eurostat 目录表,则会以可重试的upstream_fault失败 - 如果无法加载 Comext 数据流列表,
ext_go和icts会包含comextListMissing和notice;无法刷新的目录会包含catalogueLoadedAt
eurostat_get_dataset_info 工具
- 提供一个
dataset_code;返回每个维度的valuesCount和最多 10 个sampleValues,以及timeRange、obsCount、lastUpdated和 ESMSmetadataUrl - 数据集未知时返回
not_found;Eurostat 返回的结构无法读取时返回upstream_fault(端点不可用时可重试)
eurostat_get_dimension_values 工具
- 提供
dataset_code和dimension,先进行精确匹配,再进行不区分大小写的匹配(TIME_PERIOD是time的别名);返回的值代码和标签保持不变。对于geo,geo_level用于选择 NUTS 级别(默认为aggregate、country、nuts1、nuts2、nuts3)。filter会保留代码和标签中包含所给每个词的值,忽略大小写和重音符号(palma frankfurt可找到DE_EDDF_ES_LEPA),匹配数计入matchCount limit默认为 25,最大限制为 1,000,并会显示提示。每页包含指定数量的值,末页可能少于该数量;totalCount表示完整列表的数量。有后续内容的页面会包含truncated、nextCursor(将其作为cursor传回)和提示。后续请求沿用有效数量,并忽略新的limit;超过 1,000 的旧游标会规范为 1,000,并说明这一调整。失败时返回not_found、no_results、conflicting_params、invalid_cursor、upstream_fault(端点不可用时可重试)或canvas_not_foundcanvas_id会将该画布上的每个值暂存为code/label表(包含canvasId/tableName/stagedRowCount),通过连接为下载内容中的代码列添加标签;绝不会自行创建画布
eurostat_query_dataset 工具
- 提供
dataset_code、filters({dimension_code: [values]})、geo_level,以及以下二者之一:since_period/until_period(2020、2020-Q1、2020-01,直至YYYY-Wnn和YYYY-Dnnn)或last_n_periods;preview_limit必须是正整数(默认为 25),最大限制为 500,并会显示提示;lang为EN、FR或DE stage: true会将所有匹配结果暂存到可用的画布上,不受大小限制;可复用canvas_id,也可省略它以创建画布。否则,当观测数超过 5,000 时会自动暂存。truncated仍表示是否超过该阈值;tableName用于标识暂存结果。已禁用画布的部署会明确说明无法满足暂存请求last_n_periods按数据集的时间位置计数,其中可能包含没有已填充单元格的时段。提示会列出完整匹配范围内的缺失时段(最多列出最新的 24 个,并注明省略数量);增大 N 或将其替换为until_period,即可获取更早的观测数据- 每条观测都包含各维度的代码/标签对、可为空的
value、status(OBS_FLAG)和confStatus(CONF_STATUS);obsCount、missingObsCount和timeRange覆盖全部匹配结果;观测数超过 5,000 时,truncated为 true;unmatchedValues会列出没有匹配结果的筛选值 - 失败时返回
not_found、no_results(注明未匹配的值和没有值的时段)、invalid_dimension、invalid_period、conflicting_params、不可重试的async_response(查询过大,无法提供服务)、canvas_not_found,或可重试的upstream_fault(Statistics API 不可用时)
eurostat_download_dataset 工具
dataset_code,以及相同的filters映射和since_period/until_period(没有last_n_periods:除非范围筛选会移除某个时期,否则 TSV 会为每个时期保留一列);preview_limit为正整数(默认值为 25),上限为 500,并会显示提示- 返回整个下载的
rowCount(作为totalCount回显)、missingCount、periodRange和bytesRead;失败原因包括not_found、invalid_dimension、invalid_period、filter_arity、不可重试的async_queued或extraction_too_big、no_results、upstream_fault(SDMX 端点不可用时可重试)或canvas_not_found EUROSTAT_BULK_MAX_BYTES预算(解码后默认值为 50 MiB)会保留许可范围内前缀中的完整观测值,并返回budgetExceeded: true。如果预算小到无法容纳完整表头和可用观测值,则会以byte_budget_exceeded失败,并提供配置的限制和缩小范围的建议。bytesRead统计已接受的解码字节数,绝不会超过预算;不完整的尾部行会被丢弃。
eurostat_dataframe_describe 工具
- 使用暂存响应中的
canvas_id;列出每个表的name、rowCount、带类型的列以及expiresAt(滑动有效期CANVAS_TTL_MS,默认值为 24h);失败原因包括canvas_not_found或canvas_disabled - 列取决于暂存工具:
eurostat_query_dataset会为每个维度写入一个代码列和一个_label列,eurostat_download_dataset只写入代码以及time(两者共用obs_*和conf_status*度量列),eurostat_get_dimension_values会写入code和label
eurostat_dataframe_query 工具
- 每次调用只能执行一个只读
SELECT;拒绝链式语句、其他动词,以及读取文件或外部数据的函数 - 返回
columns、rows、rowCount和必需的布尔值truncated。Canvas 提供的每一行都会完整返回,最多不超过CANVAS_DEFAULT_ROW_LIMIT(默认值为 10,000)。单元格以无损 JSON 格式呈现,包括嵌套结构和带引号的字符串;64 位整数以字符串形式返回。失败原因包括missing_table、canvas_not_found或canvas_disabled - 结果被截断时会设置
truncated: true并添加提示。对未改变的确定性 SELECT 使用完整的ORDER BY(必须包含平局时的排序键)、LIMIT和OFFSET分页;按实际的rowCount推进。初始未排序的结果应从偏移量为零的位置重新开始并排序。易变 SQL 以及发生变化或已过期的表无法提供稳定分页
eurostat_dataframe_drop 工具
canvas_id和table_name必须与eurostat_dataframe_describe列出的名称完全一致;移除该表,同时保留 Canvas 及其其他表。仅当 Canvas 所在位置设置了EUROSTAT_DATAFRAME_DROP_ENABLED=true时才会列出- 返回
canvasId、tableName、dropped和expiresAt;如果未暂存该名称的表,dropped为false,并附带notice,因此可安全地重复执行删除操作。失败原因包括canvas_not_found、identifier_reserved或canvas_disabled
eurostat://dataset/{dataset_code} 资源
- 与
eurostat_get_dataset_info返回相同的载荷,类型为application/json;读取失败时会附带相同的reason,服务不可用时还会附带retryable dataset_code来自eurostat_search_datasets或eurostat_browse_themes
功能
基于 @cyanheads/mcp-ts-core 构建:支持 stdio 和 Streamable HTTP 传输、可插拔身份验证(none / jwt / oauth)、可切换存储(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1),以及支持可选 OpenTelemetry 跟踪的结构化日志记录。
Eurostat 专属功能:
- 使用 Statistics API(JSON-stat 2.0)获取数据切片,使用 SDMX 2.1 TSV 批量端点获取完整数据集(数据量约为一半),并将目录 TOC 缓存于内存中 12 小时
- 通过相同工具访问 Comext 主机的
DS-*集合(按 CN8、HS、SITC、BEC 和 CPA 分类的详细贸易数据,以及 PRODCOM)。每个请求都必须进行筛选,包括freq,因为贸易流混合了年度和月度序列;与其成员项一起求和时,TOTAL、EU27_2020和EXT_EU27_2020等汇总项会导致重复计数。PRODCOM 文本值位于valueText/obs_value_text中 - 按 NUTS 地理级别筛选(
aggregate/country/nuts1/nuts2/nuts3),并将 OBS_FLAG 和 CONF_STATUS 解码为单独字段 - 对于过大而无法提供的响应,会返回不可重试的
async_response、extraction_too_big或async_queued错误,并指出需要筛选的维度 - 使用
stage: true的查询、匹配结果超过 5,000 条的查询,或任何批量下载,都会暂存为 DuckDB dataframe canvas 上的 SQL 表(canvasId/tableName/stagedRowCount);默认启用该功能。.mcpb捆绑包会剥离原生 DuckDB 绑定,并通过CANVAS_PROVIDER_TYPE=none运行,因此 SQL 分析需要使用 npm、Docker 或从源代码安装
便于 Agent 使用的输出:
- 类型化错误契约:每个已声明的失败都包含
reason和recovery.hint,指出下一步应调用的工具 - 后续步骤提示:
eurostat_search_datasets和eurostat_browse_themes会返回指向后续调用的nextStep - 未知信息保持未知:Eurostat 未报告的计数和时间范围(
obsCount、timeRange.start/end、lastUpdated)会被省略,而不是置为零 - 回显实际查询:
eurostat_query_dataset中的appliedFilters和eurostat_download_dataset中的appliedQuery(包含 SDMXurl);如果预览省略了部分行,还会提供notice
开始使用
连接到托管实例:
claude mcp add --transport http eurostat-mcp-server https://eurostat.caseyjhand.com/mcp
或在本地运行:
claude mcp add eurostat-mcp-server -- npx -y @cyanheads/eurostat-mcp-server
对于其他客户端,将以下内容添加到 MCP 配置文件中:
{
"mcpServers": {
"eurostat-mcp-server": {
"command": "npx",
"args": ["-y", "@cyanheads/eurostat-mcp-server"]
}
}
}
无需 API 密钥。有关 Docker 或从源代码构建的信息,请参阅运行服务。
配置
| 变量 | 描述 | 默认值 |
|---|---|---|
EUROSTAT_BASE_URL | Eurostat API 基础 URL。 | https://ec.europa.eu/eurostat/api/dissemination |
EUROSTAT_COMEXT_BASE_URL | Comext 发布主机,为所有 DS-* 数据集代码(详细贸易和 PRODCOM)提供服务。 | https://ec.europa.eu/eurostat/api/comext/dissemination |
EUROSTAT_REQUEST_TIMEOUT_MS | 单次请求的总时限,包含重试、退避和正文读取,单位为 ms。 | 30000 |
EUROSTAT_METADATA_TIMEOUT_MS | 单个数据集 SDMX 数据流结构的总时限,包含重试、退避和正文读取,单位为 ms。 | 120000 (2 min) |
EUROSTAT_TOC_CACHE_TTL_MS | 目录 TOC 缓存时长,单位为 ms。 | 43200000 (12 h) |
EUROSTAT_BULK_TIMEOUT_MS | 单次批量传输的总时限,包含请求重试、退避和流式传输,单位为 ms。 | 120000 (2 min) |
EUROSTAT_BULK_MAX_BYTES | 单次批量下载的字节数上限。 | 52428800 (50 MiB) |
CANVAS_PROVIDER_TYPE | Dataframe 画布后端;none 会禁用画布及其工具。.mcpb bundle 会设置为 none。 | duckdb |
CANVAS_TTL_MS | 已暂存画布的滑动有效期,单位为 ms。 | 86400000 (24 h) |
CANVAS_DEFAULT_ROW_LIMIT | 单次 eurostat_dataframe_query 返回完整行数的上限,超过时会报告 truncated。 | 10000 |
EUROSTAT_CLAMP_LIMITS | 将正整数预览/搜索/维度限制分别截断为 500/100/1,000,并发出提示。false 会恢复拒绝超限输入的 schema;零、负数、小数和非数值输入始终会被拒绝。每次截断都会记录一次日志,并递增 eurostat.limit_clamps,按工具标记。 | true |
EUROSTAT_DATAFRAME_DROP_ENABLED | true 会列出 eurostat_dataframe_drop;当 CANVAS_PROVIDER_TYPE=none 时无效。 | false |
MCP_TRANSPORT_TYPE | 传输方式:stdio 或 http。 | stdio |
MCP_HTTP_PORT | HTTP 服务端口。 | 3010 |
MCP_SESSION_MODE | HTTP 会话模式:stateless、stateful 或 auto。服务端声明为 stateless;设置此值会覆盖该声明。 | stateless |
MCP_AUTH_MODE | 身份验证方式:none、jwt 或 oauth。 | none |
MCP_LOG_LEVEL | 日志级别(debug、info、warning、error 等)。Docker 镜像设置为 info。 | debug |
LOGS_DIR | 日志文件目录(仅 Node.js)。 | <project-root>/logs |
LOG_TOOL_FAILURE_PAYLOADS | 记录每次失败的工具调用参数和结果,按键名脱敏,并限制在 LOG_TOOL_FAILURE_PAYLOAD_MAX_BYTES 字节以内(默认值为 16384)。自由格式值中的密钥不会被脱敏。 | false |
STORAGE_PROVIDER_TYPE | 存储后端:in-memory、filesystem、supabase、cloudflare-kv/r2/d1。 | in-memory |
OTEL_ENABLED | 启用 OpenTelemetry。 | false |
完整的可选覆盖项列表请参阅 .env.example。
运行服务端
本地开发
需要 Bun v1.4.0 或更高版本(或 Node.js v24+)。
git clone https://github.com/cyanheads/eurostat-mcp-server.git
cd eurostat-mcp-server && bun install
cp .env.example .env # optional; every setting has a default
-
构建并运行生产版本:
# One-time build bun run rebuild # Run the built server bun run start:http # or bun run start:stdio -
运行检查和测试:
bun run devcheck # Lints, formats, type-checks, and more bun run test # Runs the test suite bun run lint:mcp # Validates MCP definitions against spec
Docker
docker run --rm -p 3010:3010 ghcr.io/cyanheads/eurostat-mcp-server:latest
镜像默认使用 HTTP 传输、无状态会话模式,并将日志写入 /var/log/eurostat-mcp-server。要使用 stdio,请运行 docker run -i --rm -e MCP_TRANSPORT_TYPE=stdio ghcr.io/cyanheads/eurostat-mcp-server:latest。使用 docker build -t eurostat-mcp-server . 在本地构建;默认会安装 OpenTelemetry 对等依赖项;构建时使用 --build-arg OTEL_ENABLED=false 可省略这些依赖项。
项目结构
| 目录 | 用途 |
|---|---|
src/index.ts | createApp() 入口点 — 注册工具和资源,初始化服务;通过画布标志控制是否启用数据框架工具,通过独立标志控制是否启用 drop 工具。 |
src/mcp-server/tools | 工具定义(*.tool.ts)。六个发现和数据工具,外加三个受画布标志控制的数据框架工具,其中一个需选择启用。 |
src/mcp-server/resources | 资源定义。数据集元数据资源。 |
src/services/eurostat-catalogue | 目录服务 — 获取并解析 Eurostat TOC,将 Comext 数据流列表合并其中,并使用有 TTL 限制的内存缓存。 |
src/services/eurostat-data | 统计 API 服务 — SDMX 元数据解析(按数据集缓存)、JSON-stat 2.0 解码、异步响应检测、画布行数据源。 |
src/services/eurostat-bulk | SDMX 2.1 TSV 批量服务 — 流式下载、字节数预算、SOAP 故障映射、画布行数据源。 |
src/services/eurostat-codelists.ts | OBS_FLAG 和 CONF_STATUS 代码列表、两个暂存器都会写入的度量列名称,以及文本值解码器。 |
src/services/eurostat-hosts.ts | 根据数据集代码确定提供服务的主机:DS-* 使用 Comext 主机,其他代码使用主主机。 |
src/services/canvas-accessor.ts | 可选 DataCanvas 的访问器,以及供画布工具共用的获取辅助函数。 |
src/services/shared-load.ts | 允许并发调用者等待同一次共享下载,因此一个调用者取消时,只会释放该调用者。 |
src/config | 使用 Zod 解析并验证特定于服务的环境变量。 |
skills/ | 已发布的 eurostat-guide 和 SQL 参考,通过 MCP 提供,并包含在安装包中。 |
tests/ | 单元测试和集成测试,结构与 src/ 对应。 |
开发指南
开发指南和架构规则请参阅 CLAUDE.md。简要说明:
- 处理器抛出错误,框架负责捕获 — 工具逻辑中不要使用
try/catch - 使用
ctx.log记录日志,使用ctx.state存储数据 - 在
src/index.ts的createApp()数组中注册新工具和资源 - 封装外部 API 调用:验证原始数据 → 规范化为领域类型 → 返回输出架构;绝不伪造缺失字段
贡献
欢迎提交问题。提交前请运行检查和测试:
bun run devcheck
bun run test
许可证
本项目采用 Apache 2.0 许可证授权。详情请参阅 LICENSE 文件。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。