
Swiss Democracy Mcp
io.github.malkreide由 GitHub 账号 malkreide 发布v0.3.0更新于 Oct 24, 2026
Swiss popular votes and elections: Swissvotes 1848+, BFS opendata.swiss, SRGSSR Polis 1900+
概览
本地 MCP 服务器,让助手以只读方式查询 1848 年以来的瑞士联邦全民公投和 1900 年以来的选举,含州级、政党及市镇级结果。
- 可以做什么
- 按关键词、日期范围、法律形式、结果或政策领域搜索并列出联邦公投,并列出各投票日期及议案数量。获取单次公投的完整详情:官方标题、议会立场、全国结果和签名数。获取政党推荐立场及竞选资金数据,以及全部 26 个州的赞成率、投票率和是否通过。查询 BFS 全国、州或市镇层级的实时与存档结果。配置可选的 SRGSSR Polis 凭据后,可列出 1900 年以来的历史公投与选举并获取市镇级详情。
- 适用场景
- 适合回答关于瑞士直接民主的问题:某州如何就某项议案投票、哪些政党支持该议案、历史投票趋势,或比较各市镇结果。更适合对汇总公共数据做研究与分析,而非获取实时新闻。
- 运行要求
- 通过 uvx 以 Python 包形式在本地经 stdio 运行(需安装 uv),仅支持桌面客户端。需能访问 swissvotes.ch、opendata.swiss、bfs.admin.ch 和 api.srgssr.ch。Swissvotes 与 BFS 工具无需凭据;Polis 工具需免费注册获得的 SRGSSR_CONSUMER_KEY 和 SRGSSR_CONSUMER_SECRET。HTTP 模式可选配置 MCP_TRANSPORT、MCP_HOST、MCP_PORT、MCP_CORS_ORIGINS 和 MCP_ALLOWED_HOSTS。
安装
在 SourceWeft 中
- 打开 控制台中的 Swiss Democracy Mcp,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
🗳️ swiss-democracy-mcp
[CI] [PyPI] [Python] [License: MIT] [MCP] [Swiss Public Data MCP]
🇨🇭 Part of the Swiss Public Data MCP Portfolio — connecting AI models to Swiss institutional data sources.
🌐 English | 🇩🇪 Deutsche Version
An MCP server providing access to Swiss direct democracy data, covering all federal popular votes since 1848 and elections since 1900.
Demo Query
→ democracy_search_votes(keyword="AHV 21", year_from=2022)
→ democracy_get_cantonal_results(vote_number="551")
→ democracy_get_party_positions(vote_number="551")
→ More use cases by audience →
Data Sources
Tools
Phase 1 — Swissvotes (No Auth Required)
Phase 2 — BFS Real-Time (No Auth Required)
Phase 3 — SRGSSR Polis (API Key Required)
Installation
Claude Desktop (stdio)
Add to claude_desktop_config.json:
The
SRGSSR_*variables are optional. Without them, all Swissvotes and BFS tools remain fully functional. Only the Polis tools require credentials.
Cloud / Render.com (Streamable HTTP)
MCP_HOST defaults to 127.0.0.1 (loopback). Set MCP_HOST=0.0.0.0 only
inside a sandboxed container/cloud deployment — never on a local machine, where
it would expose the server to your whole network.
Architecture
Transport: stdio for Claude Desktop · Streamable HTTP for cloud/Render.com
Auth pattern: No-Auth-First — Swissvotes & BFS work without any credentials
Cache: Swissvotes CSV is loaded once at startup and cached for 24 hours
Configuration
All configuration is via environment variables (see .env.example):
Secrets are held as SecretStr and never logged. See
docs/secret-management.md and
docs/security.md.
MCP Primitives
This server intentionally exposes Tools only (no Resources or Prompts). It is
a Phase-1 read-only data wrapper (see docs/roadmap.md); the
tool surface is small (10 use-case-oriented tools) and every response is
self-contained with source provenance. Resources (e.g. vote://{anr}) are a
candidate for a later phase once the URI scheme stabilises.
MCP Protocol Version
This server speaks two protocol eras over the same endpoint. The client's first request on a connection decides which one applies; a later claim from the other era is refused.
Both revisions are pinned in
tests/test_protocol_version.py and asserted
against the installed SDK, so a Dependabot bump of mcp cannot move either one
silently. Next to them,
tests/test_server_identity.py sends real
requests through the assembled ASGI app: a per-request envelope is answered
with the tool list, and an initialize that offers the modern revision still
gets the handshake ceiling back. The constants say which revisions the SDK
knows; the measurement says which ones this server serves.
Server identity. Under the handshake era serverInfo is named once, in the
initialize reply. The modern era has no handshake and stamps the identity
onto every response instead, as
_meta["io.modelcontextprotocol/serverInfo"]. Implementation.version is a
required schema field that the SDK pre-fills with "" when the constructor
omits it, so an unset version is not a gap but a value on the wire — and one
that a green test suite will not show you. This server passes its distribution
version explicitly; test_server_identity.py measures it on both wires, with a
bare MCPServer as the negative control.
Note that the SDK's LATEST_PROTOCOL_VERSION is an alias for the modern
era, not for the handshake era — pinning against it alone would leave the era
that current clients actually negotiate free to drift.
Update policy. When the gate fails, do not edit the constant blindly: read
the spec changelog between the two revisions, verify the server still behaves,
then move the constant, this section, README.de.md and
CHANGELOG.md together.
Portfolio Synergy
Combine with other servers in the Swiss Public Data MCP portfolio:
- zurich-opendata-mcp — add Zurich city-level statistics to vote analysis
- swiss-statistics-mcp — enrich with BFS demographic data by canton
- srgssr-mcp — link SRF news archive content to specific vote dates
Example multi-server query:
«Vergleiche die Abstimmungsresultate zur AHV-Reform mit der Altersstruktur der Kantone»
→ swiss-democracy-mcp + swiss-statistics-mcp
Safety & Limits
- Read-only: All tools perform HTTP GET requests only — no data is written, modified, or deleted upstream.
- Egress allow-list (SSRF protection): Outbound requests are restricted to a fixed allow-list of trusted hosts (
swissvotes.ch,opendata.swiss,*.bfs.admin.ch,api.srgssr.ch), HTTPS only. Caller-supplied URLs (the BFSresult_url) are additionally resolved and rejected if they point at private, loopback or cloud-metadata IP ranges. - No personal data: Swissvotes, BFS and SRGSSR Polis expose aggregate democratic data (vote results, party positions, cantonal/municipality tallies). No personally identifiable information (PII) is processed or stored by this server.
- Rate limits: Swissvotes is a single CSV downloaded once per 24h and cached in memory. BFS / opendata.swiss and SRGSSR Polis are public APIs without documented rate limits — keep
limitand date ranges conservative. The server enforces a 30s timeout per request. - Data freshness: Real-time BFS results reflect the upstream feed at query time (no local caching). Swissvotes is refreshed every 24h from the Uni Bern mirror.
- Terms of service: Data is subject to the ToS of each source — swissvotes.ch (CC BY 4.0, Uni Bern), opendata.swiss (mostly CC-BY / Open by Default), SRGSSR Polis (free tier, non-commercial use only). Always cite the upstream source in downstream products.
- No guarantees: This server is a community project, not affiliated with the University of Bern, the Federal Statistical Office, or SRG SSR. Availability depends on upstream APIs.
Known Limitations
- Swissvotes coverage: Cantonal-level results are available since 1848; municipality-level results only via SRGSSR Polis (since ~1990s depending on the vote).
- BFS archive: Real-time service covers federal votes since 1981 only.
- Polis tools: Require free registration at developer.srgssr.ch. Non-commercial use only.
- CSV cache: The Swissvotes dataset is ~several MB and is cached in memory for 24 hours. Memory footprint is accordingly higher than API-only servers.
Testing
Where the test data comes from
The fixtures under tests/fixtures/ are recorded from the live sources and
dated. Source, retrieval date, selection rule and SHA-256 for every file:
tests/fixtures/PROVENANCE.md.
The selection rule is the point here. The Swissvotes dataset has 714 rows
and 874 columns, and the recorded rows are chosen by property, not by
position. "The first N rows" would cut away exactly the cells the fixture
exists for: the placeholders 9999 ("no information") and . ("not
applicable"), which appear in 667 of the 714 votes. A fixture without them
would look clean and prove nothing — which is precisely why nobody noticed the
tools were passing them through as if they were values.
The byte-order mark stays in the file too, because the source sets one and the server strips it explicitly. Without it the fixture could not show that it has to.
SRGSSR Polis needs OAuth credentials and is listed under NOT RECORDED in
PROVENANCE.md rather than given a date it never had.
Contributing
See CONTRIBUTING.md (🇩🇪 Deutsch).
Security
See SECURITY.md (🇩🇪 Deutsch) for the security posture and vulnerability reporting.
License
MIT — see LICENSE.
Data licenses:
- Swissvotes: Creative Commons BY 4.0
- BFS / opendata.swiss: Open use
- SRGSSR Polis: Non-commercial use only — see developer.srgssr.ch
Author
Hayal Oezkan · github.com/malkreide
Installation
Run via uv's uvx — no clone or manual install needed. Add to your MCP client config (mcpServers for Claude Desktop, Cursor and Windsurf; use a top-level servers key for VS Code in .vscode/mcp.json):
来源:README.md,提交 c0477a9
工具
0版本历史
2- v0.3.0最新Sep 26, 2026
- v0.2.5Sep 16, 2026
评分
已满足适用检查项的 50%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分