mcpField
S
swiss-efv-mcp

swiss-efv-mcp

本地服务
github.com金融数据05 周前更新

关于 swiss-efv-mcp

swiss-efv-mcp 是面向 AI Agent 和助手的只读 MCP 服务,可查询瑞士联邦预算、债务、预测及支出数据。它结合财政汇总序列、分层预算和机构支出视图,数据来自 EFV 开放数据。

主要功能

  1. 011990–2029 年财政序列
  2. 02标记实际值与预测值
  3. 03分层预算明细查询
  4. 04按部门和单位查看支出
  5. 05缓存数据并在故障时提供旧数据
  6. 06支持 stdio 和 SSE 传输

适用场景

  1. 01追踪联邦收入、支出、收支余额或债务
  2. 02对比实际数据与预测
  3. 03按预算主题查看支出
  4. 04查看各行政单位的支出

MCP 相关

向 MCP 客户端提供只读财政数据工具,包括汇总查询、预算明细、机构支出、维度发现和数据源状态检查。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"malkreide-swiss-efv": {
"command": "uvx",
"args": [
"swiss-efv-mcp"
]
}
}
}
启动命令uvx swiss-efv-mcp

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiswiss-efv-mcp0.4.0

工具

6

收录的工具列表 · 更新于 2 周前

参数类型必填说明
modelstring否
year_toany否
variablestring是
householdstring否
year_fromany否

详细介绍

🇨🇭 属于 瑞士公共数据 MCP 组合 — 开源 MCP 服务,将 AI Agent 连接到瑞士公共和开放数据。 这是一个私人项目,与任何雇主或机构均无关联。

🏛️ swiss-efv-mcp

Version CI License: MIT Python 3.11+ MCP Auth: none Portfolio

用于查询瑞士联邦财政(EFV)的 MCP 服务:预算、债务、预测,以及按任务和机构划分的支出。

🇩🇪 德语版

概览

此服务填补了组合中经济与金融集群的财政空白。 swiss-snb-mcp 已涵盖货币政策;swiss-efv-mcp 则补充了国家预算——联邦收入、支出、收支差额、债务比率(含截至 2029 年的预测)、分层预算明细,以及按部门划分的支出。数据来自瑞士联邦财政管理局(EFV),经由 opendata.swiss(OGD Schweiz)获取。

功能

  • 提供五个只读工具,读取经过整理的 EFV FS/GFS 转储文件。
  • 按家庭(bund、ktn、gdn、staat、sv)和模型(FS / GFS)提供 1990–2029 年主要指标序列;每个数据点均带有 is_projection,明确区分实际值与计划/预测年份。
  • 提供联邦预算分层明细查询,以及按部门/单位划分的支出。
  • 采用 24 小时 TTL 内存缓存,并在缓存过期时回退提供旧数据;支持指数退避重试(2/4/8 秒);dump_status 绝不会静默返回空结果。
  • 双传输方式:stdio(本地)和 SSE(云端)。
  • 无需身份验证——使用公共开放政府数据(No-Auth-First)。

🎯 锚点演示查询

“自 2022 年 SNB 利率转向以来,联邦收支差额如何变化? 哪些任务领域承接了支出增长?”

fiscal_headline(variable="saldo", household="bund", year_from=2021)
fiscal_budget_breakdown(topic="Ausgaben nach Aufgabengebiet", level=2)

与 swiss-snb-mcp 交叉读取,可将利率周期与联邦赤字联系起来——这并非任何一个服务单独就能回答的问题。

演示

演示:Claude 使用 fiscal_headline 和 fiscal_budget_breakdown

前置条件

  • Python 3.11+
  • uv / uvx(推荐)或 pip
  • 可访问 data.finance.admin.ch 和 efv.admin.ch 的网络——无需 API 密钥

安装

uvx swiss-efv-mcp            # zero-install run (once published to PyPI)
# or
pip install swiss-efv-mcp

Claude Desktop(claude_desktop_config.json):

{
  "mcpServers": {
    "swiss-efv": {
      "command": "uvx",
      "args": ["swiss-efv-mcp"]
    }
  }
}

快速开始

# Run locally over stdio (default transport)
uvx swiss-efv-mcp

# From a checkout, without installing
PYTHONPATH=src python -m swiss_efv_mcp

配置

所有配置只会加载一次,存入类型化的 Settings 对象 (pydantic-settings)。下方未加前缀的旧名称仍可使用;规范名称使用 EFV_MCP_ 前缀。默认值适用于本地使用。

变量默认值用途
TRANSPORTstdio传输方式:stdio(Claude Desktop)或 sse / streamable-http(云端)
HOST127.0.0.1绑定主机(仅限 SSE)。默认绑定回环地址;仅在容器中设置为 0.0.0.0
PORT8000绑定端口(仅限 SSE)
EFV_MCP_LOG_LEVELINFOstructlog 级别(以 JSON 格式输出到 stderr)
EFV_MCP_CORS_ORIGINS[]仅限 SSE:明确允许的浏览器来源(默认拒绝;以逗号分隔或使用 JSON)
EFV_MCP_OTEL_ENABLEDfalse启用 OpenTelemetry 跟踪(需要 otel extra);使用标准 OTEL_* 环境变量配置导出

云端(Render / Railway):

TRANSPORT=sse PORT=8000 swiss-efv-mcp   # exposes /sse

可用工具

工具用途
fiscal_headline1990–2029 年的收入 / 支出 / 余额 / 债务比率,按家庭和模型划分;每个数据点均标记 is_projection
fiscal_budget_breakdown按主题划分的联邦预算层级结构(Ausgaben nach Art / nach Aufgabengebiet、Einnahmen、Bilanz 等)
fiscal_by_institution自 2007 年起按部门 / 行政单位划分的支出(Personalausgaben、Informatik、external services、FTE)
fiscal_list_dimensions查看有效的参数值——先调用此工具以构建正确的参数
fiscal_status各数据集的缓存新鲜度和上游健康状况;绝不会悄无声息地返回空结果
dump_statusfiscal_status 的已弃用别名(为向后兼容而保留;将在未来的次要版本中移除)

所有工具均为只读:每个工具都标注了 readOnlyHint: true、 destructiveHint: false,仅对 EFV dump 文件发起 HTTP GET 请求,且不具备写入、发送或文件系统操作能力。

MCP 原语。 此服务仅使用 Tools 原语。EFV 数据会从缓存的 dump 中实时切片,不存在可供 Resources 使用的稳定资源层级,也没有由服务端编写的 Prompts。这五个工具规模小且关系密切,因此放在单个 server.py 中,而不是 tools/ 包中。

架构

                      ┌──────────────────────────────┐
   Claude / Agent ──▶ │  swiss-efv-mcp (FastMCP)      │
                      │  5 tools · Pydantic v2 env.   │
                      └───────────────┬──────────────┘
                                      │ fetch + retry + TTL cache
              ┌───────────────────────┴───────────────────────┐
              ▼                                               ▼
   data.finance.admin.ch                          efv.admin.ch/dam
   fs_dashboard/main_extern.csv                   bundeshaushalt_de.csv
   (headline, 1990–2029)                          institutionen_de.csv

架构决策

此服务采用 Architecture C(Dump-first)。

理由(于 2026-07-24 实时验证):

  • EFV FS/GFS 信息面板没有经过筛选的查询 API;它提供静态 CSV dump,由前端在浏览器中进行筛选。
  • 三个精选文件体积足够小,可整体获取并缓存(516 KB / 5 MB / 1 MB)。它们涵盖了主要汇总数据、分层预算和按机构划分的视图——也就是可回答的问题。
  • 完整明细数据立方体(standardauswertung.csv 157 MB、fir_art_funk.csv 1.23 GB)不在 v0.1.0 的范围内;每次请求都加载这些文件并不可行。未来的第 2 阶段可将其预处理为 SQLite/Parquet。

后果:

  • 文件会缓存在内存中,TTL 为 24 小时;上游不可用时,优先返回过期缓存,而不是空响应。
  • 所有 HTTP 请求均采用指数退避重试;dump_status 始终会返回可读的状态。

项目结构

swiss-efv-mcp/
├── src/swiss_efv_mcp/
│   ├── __init__.py
│   ├── __main__.py        # entry point; dual transport (stdio / SSE+CORS)
│   ├── client.py          # dump-first data layer: egress allow-list, retry, UA, TTL cache
│   ├── logging_config.py  # structlog JSON to stderr
│   ├── models.py          # Pydantic v2 envelopes (source + provenance)
│   ├── server.py          # 5 FastMCP tools (annotated) + testable *_impl functions
│   └── settings.py        # typed pydantic-settings config
├── tests/                 # respx mock tests + hardening tests + @pytest.mark.live
├── docs/                  # network-egress.md + accepted-risk ADRs
├── audits/                # MCP best-practice audit runs (findings, report, summary)
├── README.md · README.de.md · CHANGELOG.md · SECURITY.md · CONTRIBUTING.md
├── Dockerfile · server.json · LICENSE
└── pyproject.toml

安全与限制

  • 只读。 每个工具都标注为 readOnlyHint: true,只会对 EFV 转储文件发送 HTTP GET 请求,不具备写入、发送或文件系统操作能力。
  • 出站访问允许列表。 不可变的 ALLOWED_HOSTS frozenset 和 assert_host_allowed() 会在每次请求前强制执行(仅 HTTPS,两个固定的 EFV 主机)。URL 是硬编码常量;不会根据用户输入构建 URL。请参阅 docs/network-egress.md。
  • 已启用 TLS。 httpx 默认启用证书验证,且从不禁用。
  • 无凭据。 这些端点是公开的 OGD;不会存储或转发 API 密钥或机密信息。由于端点会对默认的 httpx/curl UA 返回 403,因此会注入浏览器 User-Agent(请参阅已知限制)——请勿移除。
  • 错误信息屏蔽。 mask_error_details=True 加上客户端屏蔽,可防止原始上游/内部详细信息出现在工具结果中;完整详细信息只会写入 structlog stderr 日志。
  • 输入范围限制。 工具参数带有明确的 Pydantic 约束(年份 1900–2100、level 1–8、字符串 max_length)。
  • 优雅降级。 采用指数退避重试(2/4/8 秒);有陈旧缓存时优先返回缓存,而不是空响应;dump_status 始终返回可读状态,不会无提示地返回空结果。
  • 回环绑定 + 默认拒绝 CORS。 SSE 绑定到 HOST,默认值为 127.0.0.1;仅在容器内设置 HOST=0.0.0.0(提供的 Dockerfile 已这样设置)。 浏览器来源必须通过 EFV_MCP_CORS_ORIGINS 显式列出。
  • 已审计。 已依据 MCP 最佳实践目录进行审查(44 项适用检查)——请参阅 audits/ 和 SECURITY.md。 已接受的风险记录在 docs/adr/ 下的 ADR 中。
  • 非权威数据。 数据并非官方数据;如需官方用途,请查阅 EFV 原始资料。

已知限制

实时探测结果(2026-07-24),也记录在 CHANGELOG.md → Known findings 中:

发现影响
端点在没有浏览器 User-Agent 时返回 HTTP 403客户端会注入 UA;请勿移除
opendata.swiss 上 2 个数据集的“CSV”链接指向 HTML 落地页实际文件已解析到 DAM 路径(/dam/de/sd-web/{id}/…),其不透明 ID 可能在重新上传后轮换
hh/model/source 中会出现字面字符串 NA已在中央清理为 None
“前瞻性”并非统一标签:Bund 使用“预算/财务计划”,staat 使用“预测”通过 is_projection 进行抽象
2022/2023 会计模型发生变化(主题为“截至 2022 年”和“从 2023 年起”)序列存在衔接断点;note 会标记受影响的主题
不提供详细数据立方体(157 MB / 1.23 GB)第 2 阶段;目前请使用精选文件

项目阶段

此服务处于第 1 阶段(只读)。所有工具都只会获取公开的 EFV 转储文件——不具备写入、发送或文件系统操作能力。

阶段范围状态
1 — 只读核心序列、预算明细、按机构分类的支出✅ 当前阶段
2 — 详细数据立方体将 157 MB / 1.23 GB 的数据立方体预处理为 SQLite/Parquet计划中
3 — 多 Agent(无计划)—

进入后续阶段前,必须重新审计,然后才能添加任何具备写入能力的工具。

MCP 协议版本

此服务原生支持 MCP 规范 2026-07-28,同时仍服务于较早的握手时代,因此同时列出两个版本——单个版本号只能说明客户端实际获得能力的一半。

时代修订版连接如何协商固定为
现代(默认)2026-07-28server/discover + 每个请求各自携带的封装;没有 initialize 握手,且 Client.initialize_result 为 NoneMCP_MODERN_PROTOCOL_VERSION
握手(旧版客户端)2025-11-25经典的 initialize 握手MCP_HANDSHAKE_PROTOCOL_VERSION

这两个常量都位于 server.py 中,并与 mcp SDK 自身的 LATEST_MODERN_VERSION / LATEST_HANDSHAKE_VERSION 保持一致,而不是与复制出来的规范文本比对;两个时代都通过真实连接进行了测试——SDK 升级若更改协议,会在 CI 中明确失败,而不会悄然偏离(ARCH-012)。

2026-07-28 时代带来的影响不止版本号:

  • 路由标头。 每个现代请求都携带 Mcp-Protocol-Version、 Mcp-Method,以及(对于 tools/call)Mcp-Name。它们已列入 __main__.py 中的 CORS 允许列表;如果缺少这些标头,浏览器客户端会在 预检阶段失败,无法到达服务。这里特意不包含 Mcp-Param-*——没有任何工具架构带有 x-mcp-header 注解来促使客户端发送此类标头;若有工具添加了该注解,测试就会失败。
  • 日志记录已弃用(SEP-2577)。 工具处理程序不再发送面向客户端的日志通知;每次调用的诊断信息会写入 structlog 的 stderr 流,并遵循 EFV_MCP_LOG_LEVEL。进度报告不受影响,仍会保留。
  • fastmcp>=4.0 是最低要求,不是装饰。 只有 fastmcp 4 会引入 mcp 2.x,也只有在该版本中才存在 2026-07-28 修订版。使用 fastmcp 3.x 时, 此服务最多只能使用 2025-11-25。

依赖项通过每月的 Dependabot PR 保持更新 (.github/dependabot.yml);与协议相关的升级会记录在 CHANGELOG.md 中。

测试

PYTHONPATH=src pytest tests/ -m "not live"   # offline, respx-mocked
PYTHONPATH=src pytest tests/ -m live         # hits the real EFV endpoints
PYTHONPATH=src ruff check src tests

更新日志

请参阅 CHANGELOG.md。

贡献

欢迎提交 Issue 和 Pull Request。请确保工具为只读,在提交前运行 ruff check 和离线测试套件,并在 [Unreleased] 下的 CHANGELOG.md 中添加面向用户的变更记录。请参阅 CONTRIBUTING.md。

维护者:分步 PyPI 发布流程(通过 GitHub Release 进行 Trusted Publishing)请参阅 PUBLISHING.md。

安全

安全状况、加固措施以及漏洞报告方式,请参阅 SECURITY.md。

许可证

此服务采用 MIT 许可证——请参阅 LICENSE。EFV 数据仍受 OGD Schweiz 条款约束(可自由使用,但须注明出处)。

作者

Hayal Oezkan · github.com/malkreide

致谢与相关项目

  • 数据:通过 opendata.swiss 提供的 Eidgenössische Finanzverwaltung EFV(OGD Schweiz,可自由使用)
  • 配套项目:swiss-snb-mcp(货币政策)——财政与货币政策项目组合
  • 项目索引:swiss-public-data-mcp

免责声明:这是一个私人项目,与任何雇主或机构无关。不提供任何保证;所列数字不具权威性——如需官方用途,请查阅 EFV 原始数据。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。