mcpField
S
swiss-democracy-mcp

swiss-democracy-mcp

本地服务
github.com法律与政务25 周前更新

关于 swiss-democracy-mcp

swiss-democracy-mcp 为 MCP 客户端提供瑞士联邦公投、选举及相关统计数据,面向民主研究和公共数据分析。它整合 Swissvotes、BFS 和 SRGSSR Polis;多数数据无需认证,Polis 工具需要凭据。

主要功能

  1. 01搜索 1848 年以来的联邦公投
  2. 02查询政党立场与州级结果
  3. 03获取 BFS 实时及历史投票结果
  4. 04查询 Polis 公投与选举记录

适用场景

  1. 01分析特定公投的全国和州级结果
  2. 02比较政党对提案的建议立场
  3. 03查询市镇级历史投票或选举数据

MCP 相关

作为 MCP 服务,它向客户端提供只读工具,不提供资源或提示词。工具读取 Swissvotes、BFS 和 SRGSSR Polis 数据;Polis 工具需要 OAuth2 凭据。

配置

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

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

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

安装包
pypiswiss-democracy-mcp0.3.0

工具

10

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

参数类型必填说明
paramsany是

详细介绍

🗳️ swiss-democracy-mcp

CI PyPI Python License: MIT MCP Swiss Public Data MCP

🇨🇭 属于 Swiss Public Data MCP Portfolio — 将 AI 模型连接至瑞士机构数据源。

🌐 English | 🇩🇪 德语版

一个 MCP 服务,提供访问瑞士直接民主数据的能力,涵盖自 1848 年以来的所有联邦全民投票,以及自 1900 年以来的选举。

演示:Claude 使用 democracy_search_votes、democracy_get_cantonal_results 和 democracy_get_party_positions


演示查询

«Wie hat der Kanton Zürich bei der AHV 21 Initiative 2022 abgestimmt,
 und welche Parteien unterstützten die Vorlage?»

→ democracy_search_votes(keyword="AHV 21", year_from=2022)
→ democracy_get_cantonal_results(vote_number="551")
→ democracy_get_party_positions(vote_number="551") → 按受众分类查看更多用例 →


数据源

来源覆盖范围身份验证
Swissvotes(伯尔尼大学)自 1848 年以来的所有联邦投票 · 874 列 · 政党立场 · 州级结果无需 ✓
BFS / opendata.swiss实时数据和档案(自 1981 年起)· 市镇级无需 ✓
SRGSSR Polis自 1900 年以来的投票和选举 · 市镇级详情OAuth2 密钥

工具

阶段 1 — Swissvotes(无需身份验证)
工具描述
democracy_search_votes按关键词、日期范围、法律形式、结果、政策领域搜索自 1848 年以来的所有联邦全民投票
democracy_get_vote_detail查看特定投票的完整详情:官方标题、议会立场、全国结果、签名数
democracy_get_party_positions政党建议(FDP、SP、SVP、Die Mitte、GPS、GLP 等)及竞选资金数据
democracy_get_cantonal_results查看全部 26 个州的结果:赞成比例、投票率、通过标记
democracy_list_vote_dates列出所有投票日期及每个日期的提案数量
阶段 2 — BFS 实时数据(无需身份验证)
工具描述
democracy_bfs_list_vote_dates列出所有 BFS 投票日期(档案和当前数据)
democracy_bfs_get_vote_results查看全国、州或市镇级别的实时或存档结果
阶段 3 — SRGSSR Polis(需要 API 密钥)
工具描述
democracy_polis_list_votations查看自 1900 年以来的历史投票及市镇级数据
democracy_polis_get_votation_detail查看完整的 Polis 详情,可选包含所有市镇结果
democracy_polis_list_elections查看自 1900 年以来的国民院、联邦院和州级选举

安装

Claude Desktop(stdio)

添加到 claude_desktop_config.json:

{
  "mcpServers": {
    "swiss-democracy": {
      "command": "uvx",
      "args": ["swiss-democracy-mcp"],
      "env": {
        "SRGSSR_CONSUMER_KEY": "your_key_here",
        "SRGSSR_CONSUMER_SECRET": "your_secret_here"
      }
    }
  }
}

SRGSSR_* 变量为可选项。不设置这些变量时,所有 Swissvotes 和 BFS 工具仍可正常使用。只有 Polis 工具需要凭据。

云端 / Render.com(Streamable HTTP)
pip install swiss-democracy-mcp
# Bind to all interfaces ONLY inside a container/cloud environment:
MCP_TRANSPORT=streamable_http MCP_HOST=0.0.0.0 MCP_PORT=8000 python -m swiss_democracy_mcp.server

MCP_HOST 默认为 127.0.0.1(环回地址)。仅在沙盒容器/云端部署中设置 MCP_HOST=0.0.0.0 — 切勿在本地机器上设置,否则会使整个网络都能访问该服务。


架构

┌─────────────────────────────────────────────┐
│              Claude / LLM Host              │
└──────────────┬──────────────────────────────┘
               │ MCP (stdio / Streamable HTTP)
┌──────────────▼──────────────────────────────┐
│         swiss-democracy-mcp                 │
│                                             │
│  ┌─────────────────────────────────────┐   │
│  │  Swissvotes CSV Cache (24h TTL)     │   │
│  │  All 874 columns, since 1848        │   │
│  └──────────────┬──────────────────────┘   │
│                 │                           │
│  ┌──────────────▼──────────────────────┐   │
│  │  BFS / opendata.swiss (no auth)     │   │
│  │  Real-time & archive since 1981     │   │
│  └──────────────┬──────────────────────┘   │
│                 │                           │
│  ┌──────────────▼──────────────────────┐   │
│  │  SRGSSR Polis (OAuth2, optional)    │   │
│  │  Votes & elections since 1900       │   │
│  └─────────────────────────────────────┘   │
└─────────────────────────────────────────────┘

传输方式: Claude Desktop 使用 stdio · 云端/Render.com 使用 Streamable HTTP
认证模式: 优先免认证——Swissvotes 和 BFS 无需任何凭据即可使用
缓存: Swissvotes CSV 在启动时加载一次,并缓存 24 小时


配置

所有配置均通过环境变量完成(参见 .env.example):

变量默认值用途
MCP_TRANSPORTstdiostdio(本地)或 streamable_http(云端)
MCP_HOST127.0.0.1HTTP 绑定地址——仅在容器中设置为 0.0.0.0
MCP_PORT8000HTTP 端口
LOG_LEVELINFO结构化 JSON 日志写入 stderr
MCP_CORS_ORIGINS—HTTP 传输的 CORS 允许来源列表,以逗号分隔。留空表示不允许任何浏览器客户端;* 允许任何来源,并会记录一条警告。stdio 客户端不受影响
MCP_ALLOWED_HOSTS—入站 Host 允许列表,以逗号分隔。仅在绑定地址非回环地址时需要
SRGSSR_CONSUMER_KEY / SRGSSR_CONSUMER_SECRET—可选,仅用于 democracy_polis_* 工具

密钥以 SecretStr 类型保存,绝不会写入日志。请参阅 docs/secret-management.md 和 docs/security.md。

MCP 原语

此服务有意仅公开工具(不提供资源或提示词)。它是一个第 1 阶段的只读数据封装器(参见 docs/roadmap.md);工具集规模较小(10 个面向用例的工具),且每条响应都包含完整的来源信息。资源(例如 vote://{anr})可作为后续阶段的候选方案,待 URI 方案稳定后再考虑。

MCP 协议版本

此服务通过同一端点支持两个协议时代。客户端在连接上的第一个请求决定适用哪个时代;后续若声明属于另一时代,则会被拒绝。

时代修订版可接入的客户端
initialize 握手2024-11-05 … 2025-11-25当前客户端使用的协议。服务会以请求指定的修订版作答;如果请求要求更新的版本,则使用 2025-11-25 这一上限版本作答。
按请求封套2026-07-28携带 2026-07-28 _meta 封套的请求会建立现代连接。

两个修订版都固定在 tests/test_protocol_version.py 中,并与已安装的 SDK 断言比对,因此 Dependabot 升级 mcp 时不会悄然更改任一版本。在这两个文件旁边, tests/test_server_identity.py 会通过组装好的 ASGI 应用发送真实请求:按请求封套会收到工具列表作为响应,而即使 initialize 提供了现代修订版,也仍会收到握手上限版本。常量表明 SDK 知晓哪些修订版;实测则表明此服务实际提供哪些修订版。

服务身份。 在握手时代,serverInfo 只在 initialize 响应中声明一次。现代时代没有握手,而是在每条响应中添加身份信息,具体为 _meta["io.modelcontextprotocol/serverInfo"]。Implementation.version 是必填的架构字段;如果构造函数中省略该字段,SDK 会预先填入 "",因此版本未设置并非缺失,而是线上传输的一个值——绿色的测试套件也不会显示这一点。此服务会显式传入其发行版本;test_server_identity.py 会在两种协议线上测量该版本,并以一个未经特殊处理的 MCPServer 作为负向对照。

请注意,SDK 的 LATEST_PROTOCOL_VERSION 是现代时代的别名,而非握手时代的别名——若只针对它固定版本,当前客户端实际协商的时代就会任其漂移。

更新策略。 门禁失败时,不要盲目编辑常量:阅读两个修订版之间的规范变更日志,验证服务仍能正常运行,然后同步更新常量、本节、README.de.md 和 CHANGELOG.md。


组合使用

与瑞士公共数据 MCP 组合中的其他服务搭配使用:

多服务查询示例:
«Vergleiche die Abstimmungsresultate zur AHV-Reform mit der Altersstruktur der Kantone»
→ swiss-democracy-mcp + swiss-statistics-mcp


安全与限制

  • 只读: 所有工具仅执行 HTTP GET 请求 — 不会在上游写入、修改或删除任何数据。
  • 出站访问允许列表(SSRF 防护): 出站请求仅限固定的可信主机允许列表(swissvotes.ch、opendata.swiss、*.bfs.admin.ch、api.srgssr.ch),且仅允许 HTTPS。调用方提供的 URL(BFS result_url)还会经过解析;若指向私有、环回或云元数据 IP 地址段,则会被拒绝。
  • 无个人数据: Swissvotes、BFS 和 SRGSSR Polis 提供民主数据汇总信息(投票结果、政党立场、州/市镇统计)。此服务不会处理或存储任何个人身份信息(PII)。
  • 速率限制: Swissvotes 是单个 CSV,每 24 小时下载一次并缓存在内存中。BFS / opendata.swiss 和 SRGSSR Polis 是未公布速率限制的公共 API — 请谨慎设置 limit 和日期范围。此服务会为每个请求强制设置 30 秒超时。
  • 数据时效性: BFS 实时结果反映查询时的上游数据源(不进行本地缓存)。Swissvotes 每 24 小时从伯尔尼大学镜像站刷新一次。
  • 服务条款: 数据受各来源的服务条款约束 — swissvotes.ch(CC BY 4.0,伯尔尼大学)、opendata.swiss(大多采用 CC-BY / Open by Default)、SRGSSR Polis(免费套餐,仅限非商业用途)。请始终在下游产品中注明上游来源。
  • 不作保证: 此服务是一个社区项目,与伯尔尼大学、联邦统计局或 SRG SSR 均无关联。服务可用性取决于上游 API。

已知限制

  • Swissvotes 覆盖范围: 州级结果自 1848 年起可用;市镇级结果仅通过 SRGSSR Polis 提供(自约 1990 年代起,具体取决于投票)。
  • BFS 档案: 实时服务仅涵盖自 1981 年起的联邦投票。
  • Polis 工具: 需要在 developer.srgssr.ch 免费注册。仅限非商业用途。
  • CSV 缓存: Swissvotes 数据集约有数 MB,并在内存中缓存 24 小时。因此,其内存占用高于仅使用 API 的服务。

测试

# Unit tests (no network required)
PYTHONPATH=src pytest tests/ -m "not live" -v

# Live tests (require network access)
PYTHONPATH=src pytest tests/ -m "live" -v
测试数据的来源

tests/fixtures/ 下的测试固件记录自在线数据源,并标注了日期。每个文件的来源、获取日期、筛选规则和 SHA-256 值见: tests/fixtures/PROVENANCE.md。

python scripts/record_fixtures.py   # re-record

这里的关键在于筛选规则。 Swissvotes 数据集包含 714 行 和 874 列,记录的行是按属性而非位置选取的。“前 N 行”的做法 会恰好删掉测试固件所要验证的单元格:占位符 9999(“无 信息”)和 .(“不适用”),它们出现在 714 次投票中的 667 次里。没有这些值的测试固件看起来会很干净,却无法证明任何问题 — 而这正是没人注意到这些工具一直把它们当作实际值传递的原因。

文件中也保留了字节顺序标记,因为源文件包含该标记,而服务会显式移除它。没有这个标记,测试固件就无法证明服务需要执行这一步。

SRGSSR Polis 需要 OAuth 凭据,因此在 PROVENANCE.md 中列为 NOT RECORDED,而不是为其编造一个并不存在的日期。


贡献

请参阅 CONTRIBUTING.md(🇩🇪 Deutsch)。


安全

请参阅 SECURITY.md(🇩🇪 Deutsch),了解安全状况和漏洞报告方式。


许可证

MIT — 请参阅 LICENSE。

数据许可:


作者

Hayal Oezkan · github.com/malkreide

安装

通过 uv 的 uvx 运行——无需克隆或手动安装。将其添加到 MCP 客户端配置中(Claude Desktop、Cursor 和 Windsurf 使用 mcpServers;VS Code 在 .vscode/mcp.json 中使用顶层 servers 键):

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

评论

支持 Markdown

第一次接触 MCP?

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

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