
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 分