swiss-democracy-mcp
This MCP server provides AI models with access to Swiss direct democracy data — federal popular votes since 1848, elections since 1900, and real-time results — across three tiers of tools:
Swissvotes (no auth required)
Search votes (
democracy_search_votes): Find federal popular votes by keyword, date range, legal form (initiative/referendum), outcome, or policy domain.Get vote details (
democracy_get_vote_detail): Retrieve official title, parliamentary positions, national result, turnout, and campaign finance data.Get party positions (
democracy_get_party_positions): See how major Swiss parties (FDP, SP, SVP, Die Mitte, GPS, GLP, etc.) voted, including Yes/No committee links.Get cantonal results (
democracy_get_cantonal_results): View yes%, turnout, and acceptance flags for all 26 cantons (useful for analyzing Ständemehr).List vote dates (
democracy_list_vote_dates): Browse all historical voting dates with proposal counts.
BFS / opendata.swiss (no auth required)
List BFS vote dates (
democracy_bfs_list_vote_dates): List all available voting dates in the Federal Statistical Office system (archive since 1981, with live updates on voting Sundays).Get BFS vote results (
democracy_bfs_get_vote_results): Fetch real-time or archived results at national, cantonal, or municipality level.
SRGSSR Polis (optional API key required)
List historical votations (
democracy_polis_list_votations): Access votations since 1900, often with municipality-level data.Get votation detail (
democracy_polis_get_votation_detail): Get full Polis details for a specific vote, optionally including results for every municipality (e.g., "How did Zurich vote?").List elections (
democracy_polis_list_elections): Browse National Council, Council of States, and cantonal elections since 1900.
Provides access to historical votations and elections since 1900 with municipality-level detail using the SRGSSR Polis API (requires OAuth2 key).
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@swiss-democracy-mcpsearch for votes on climate change since 2020"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
🗳️ swiss-democracy-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
«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")
→ More use cases by audience →
Related MCP server: parlament-mcp
Data Sources
Source | Coverage | Auth |
Swissvotes (Uni Bern) | All federal votes since 1848 · 874 columns · party positions · cantonal results | None ✓ |
Real-time & archive (since 1981) · municipality level | None ✓ | |
Votes & elections since 1900 · municipality detail | OAuth2 key |
Tools
Phase 1 — Swissvotes (No Auth Required)
Tool | Description |
| Search all federal popular votes since 1848 by keyword, date range, legal form, outcome, policy domain |
| Full details for a specific vote: official title, parliamentary positions, national result, signatures |
| Party recommendations (FDP, SP, SVP, Die Mitte, GPS, GLP, …) with campaign finance data |
| Results for all 26 cantons: yes%, turnout, accepted flag |
| List all voting dates with number of proposals per date |
Phase 2 — BFS Real-Time (No Auth Required)
Tool | Description |
| List all BFS voting dates (archive + current) |
| Real-time or archived results at national, cantonal, or municipality level |
Phase 3 — SRGSSR Polis (API Key Required)
Tool | Description |
| Historical votations since 1900 with municipality-level data |
| Full Polis detail, optionally with all municipality results |
| National Council, Council of States, and cantonal elections since 1900 |
Installation
Claude Desktop (stdio)
Add to 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"
}
}
}
}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)
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.serverMCP_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
┌─────────────────────────────────────────────┐
│ 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 │ │
│ └─────────────────────────────────────┘ │
└─────────────────────────────────────────────┘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):
Variable | Default | Purpose |
|
|
|
|
| HTTP bind address — set |
|
| HTTP port |
|
| structured JSON logs go to stderr |
| — | comma-separated CORS allow-origins for the HTTP transport. Empty means no browser client is permitted; |
| — | comma-separated inbound |
| — | optional, only for |
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.
Era | Revision | Who reaches it |
|
| What today's clients speak. The server answers with the revision asked for, or with the |
Per-request envelope |
| A request carrying the |
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. This server builds no ASGI app to send an initialize through, so
the gate asserts the SDK constants rather than a measured response — the
weaker form, named rather than left unsaid.
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
# Unit tests (no network required)
PYTHONPATH=src pytest tests/ -m "not live" -v
# Live tests (require network access)
PYTHONPATH=src pytest tests/ -m "live" -vWhere 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.
python scripts/record_fixtures.py # re-recordThe 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):
{
"mcpServers": {
"swiss-democracy-mcp": {
"command": "uvx",
"args": [
"swiss-democracy-mcp"
]
}
}
}Available Tools
10 toolsdemocracy_bfs_get_vote_resultsARead-onlyIdempotent
Ruft Echtzeit- oder Archiv-Abstimmungsresultate vom BFS ab.
Resultate auf Gemeinde-/Kantons-/Bundesebene, v.a. am Abstimmungssonntag.
Nutzt die direkte JSON-URL eines Abstimmungsdatums (aus democracy_bfs_list_vote_dates). Gibt Resultate pro Vorlage auf nationaler, kantonaler oder Gemeindeebene zurück. Am Abstimmungssonntag werden die Daten laufend aktualisiert.
Args: params (BfsVoteResultInput): Enthält: - result_url (str): URL aus democracy_bfs_list_vote_dates - level (str): 'national', 'cantonal' oder 'municipality'
Returns: str: JSON mit Abstimmungsresultaten pro Vorlage
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true. The description adds that data is updated continuously on voting Sunday and returns results per template, which provides useful behavioral context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise at about five sentences, well-structured with a use_case tag and clear sections. Every sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity (two parameters, output JSON schema available, annotations present), the description is complete: it explains the purpose, prerequisite, parameter semantics, and real-time behavior. No gaps remain for an agent to misuse the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema fully describes both parameters with detailed descriptions (e.g., result_url has maxLength, minLength; level has enum values explained). The description does not need to add more, but the schema itself is comprehensive.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool fetches real-time or archive voting results from BFS. It specifies the use case and distinguishes from the sibling tool democracy_bfs_list_vote_dates by referencing its output as input.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes a use_case tag indicating when to use (election results at various levels, especially on voting Sunday). It mentions the prerequisite of using the URL from democracy_bfs_list_vote_dates. It does not explicitly list alternatives or when not to use, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
democracy_bfs_list_vote_datesARead-onlyIdempotent
Listet alle verfügbaren eidgenössischen Abstimmungsdaten im BFS-Echtzeit-Webservice auf.
Einstieg in BFS-Echtzeit-/Archivdaten; liefert die Ressourcen-URLs für democracy_bfs_get_vote_results.
Die Daten werden am Abstimmungssonntag ab 12:00 Uhr laufend aktualisiert. Das Archiv enthält eidgenössische Abstimmungen seit 1981.
Returns: str: JSON mit verfügbaren Abstimmungsdaten und deren Ressource-URLs
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint, idempotentHint, and openWorldHint. The description adds valuable behavioral context: data updates on voting Sunday from 12:00 and the archive contains votes since 1981. This goes beyond what annotations offer, though it could mention any rate limits or data freshness guarantees.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise: two sentences plus a use_case tag and a returns line. It front-loads the core purpose and uses structured tags for additional context. Every sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no input parameters, a rich set of annotations, and an existing output schema, the description is complete. It explains the tool's role in the workflow, data update timing, and archive coverage. The sibling list and annotations provide further context, leaving no critical gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are no parameters, so the input schema provides complete coverage. The description does not need to add parameter details, meeting the baseline score of 4 for zero-parameter tools.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists available federal voting dates from the BFS real-time web service and serves as an entry point for BFS data. It distinguishes itself from sibling tools by specifying it provides resource URLs for democracy_bfs_get_vote_results, and the sibling list includes other democracy tools that cover different data scopes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly identifies the tool as an entry point for BFS real-time/archive data and mentions it feeds into democracy_bfs_get_vote_results, giving clear context for when to use it. However, it does not explicitly differentiate from the sibling tool 'democracy_list_vote_dates', which appears to be a non-BFS variant. Without contrast, the agent may be uncertain which listing tool to choose.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
democracy_get_cantonal_resultsARead-onlyIdempotent
Gibt die Abstimmungsresultate aller 26 Kantone für eine eidgenössische Volksabstimmung zurück.
Kantonsvergleich und Ständemehr-Analyse zu einer Vorlage.
Inkl. Stimmberechtigte, abgegebene Stimmen, gültige Stimmen, Ja- und Nein-Stimmen, Ja-Prozent und ob der Kanton angenommen hat (für Ständemehr-Zählung).
Args: params (VoteDetailInput): Enthält: - vote_number (str): Abstimmungsnummer (anr)
Returns: str: JSON mit kantonalen Resultaten (26 Kantone), nationalem Total und Stimmenmehr/Ständemehr-Übersicht
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, destructiveHint, and idempotentHint. The description adds meaningful behavioral context by listing the returned fields (Stimmberechtigte, gültige Stimmen, etc.) and confirming national total inclusion, which goes beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured, with clear sections for use case, parameter description, and return value description. Every sentence serves a purpose, and the key information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has an output schema (though not shown) and annotations, the description covers the necessary behavioral details. It includes return value structure and complements the schema. Minor gap: no error handling guidance, but not critical.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides a description for vote_number. The tool description does not add new parameter semantics beyond reiterating the role of vote_number. Schema coverage appears high, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns cantonal results for a federal vote, specifying the verb (gibt zurück) and resource (Abstimmungsresultate aller 26 Kantone). It includes a use case but does not explicitly differentiate from siblings like democracy_bfs_get_vote_results.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description mentions when to use (cantonal comparison and Ständemehr analysis) but lacks explicit guidance on when not to use or alternatives. This is adequate but not comprehensive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
democracy_get_party_positionsARead-onlyIdempotent
Gibt die Parteiparolen der grossen Schweizer Parteien zu einer Volksabstimmung zurück.
Analyse von Parteilinien und Kampagnen-Finanzierung zu einer Vorlage.
Dekodiert die numerischen Parolen-Codes aus Swissvotes in lesbare Labels: 1=Ja, 2=Nein, 3=Stimmfreigabe, 4=Nein zum Gegenentwurf, 5=Ja zum Gegenentwurf, 66=Keine Parole gefasst, 9=Unbekannt.
Args: params (VoteDetailInput): Enthält: - vote_number (str): Abstimmungsnummer (anr)
Returns: str: JSON mit Parteiparolen und Links zu Ja-/Nein-Komitees
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint. The description adds value by explaining the decoding of numeric codes into labels and the return format (JSON with links to committees). No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with sections, but slightly lengthy (three paragraphs). Every sentence adds value, and the use case and code decoding are useful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with good annotations and a single well-described parameter, the description adequately covers purpose, input, and output. It could mention potential errors or rate limits but is largely complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema itself provides a good description of the vote_number parameter (including example values). The tool description adds a brief restatement, but no substantial new information. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it returns party positions (Parolen) for Swiss popular votes, distinguishing it from sibling tools like democracy_get_vote_detail or democracy_bfs_get_vote_results. However, the use of German may reduce clarity for non-German-speaking agents, and the exact scope is implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a use case ('Analyse von Parteilinien und Kampagnen-Finanzierung') but does not explicitly mention when to avoid this tool or suggest alternatives. Usage is implied rather than guided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
democracy_get_vote_detailARead-onlyIdempotent
Gibt vollständige Details zu einer eidgenössischen Volksabstimmung zurück.
Vertiefung zu einer konkreten Vorlage (Parlamentsempfehlungen, Resultat, Beteiligung).
Inkl. offiziellem Titel, Rechtsform, Parlamentsempfehlungen (NR, SR, Bundesrat), Abstimmungsresultat (national und kantonal), Beteiligung, Finanzierungsdaten und Link zur Swissvotes-Seite.
Args: params (VoteDetailInput): Enthält: - vote_number (str): Abstimmungsnummer (anr) aus democracy_search_votes
Returns: str: JSON mit vollständigen Vote-Details oder Fehlermeldung
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint and idempotentHint, reducing burden. The description adds context about the returned JSON and error handling, and lists included fields, aligning with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a use-case block, list of included items, and Args/Returns sections. It is informative but could be slightly more concise by avoiding redundancy with schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and the presence of an output schema, the description covers input, use case, and output sufficiently. It mentions error messages and links to additional resources.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter (params) is described with details about its field (vote_number) and source in the description. The schema also provides a description, so the main description adds clarity about the input's origin.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it returns full details of a federal popular vote, listing specific elements. It distinguishes itself from siblings through the emphasis on 'complete details', but does not explicitly name differences.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes a use-case hint ('Vertiefung zu einer konkreten Vorlage') implying when to use, but lacks explicit when-not-to-use or alternatives. It references democracy_search_votes for input, providing context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
democracy_list_vote_datesARead-onlyIdempotent
Listet alle eidgenössischen Abstimmungsdaten auf, an denen Vorlagen zur Abstimmung kamen.
Orientierung/Navigation vor einer Detailabfrage.
Gibt für jedes Datum die Anzahl Vorlagen zurück. Nützlich zur Orientierung vor einer Detailabfrage.
Args: params (ListDatesInput): Optionaler Zeitraumfilter (year_from, year_to)
Returns: str: JSON mit Liste von Abstimmungsdaten und Anzahl Vorlagen pro Datum
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, destructiveHint=false, idempotentHint=true, covering safety. The description adds that it returns JSON with dates and proposal counts, but no additional behavioral traits like auth needs or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is concise and front-loaded with purpose. Some redundancy (e.g., 'Nützlich zur Orientierung...' appears twice), but overall efficient with mixed German and technical formatting.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given tool complexity (listing with filtering) and existence of output schema, description adequately explains return format (JSON with dates and counts). Lacks differentiation from sibling list tools but covers essentials.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so description must compensate. It mentions 'Optionaler Zeitraumfilter (year_from, year_to)' for two of three parameters but omits 'limit'. Partial coverage limits clarity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Listet alle eidgenössischen Abstimmungsdaten auf' (lists all federal voting dates), specifying verb, resource, and scope. It distinguishes from siblings like democracy_get_vote_detail and democracy_bfs_list_vote_dates by focusing on date listing with proposal counts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes a <use_case> tag indicating 'Orientierung/Navigation vor einer Detailabfrage' (orientation/navigation before a detail query), providing context for when to use. However, it does not explicitly exclude usage or mention alternatives like democracy_bfs_list_vote_dates.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
democracy_polis_get_votation_detailARead-onlyIdempotent
Gibt detaillierte Polis-Daten zu einer Volksabstimmung zurück.
Gemeindescharfe Detailanalyse einer historischen Abstimmung.
Optional mit Gemeinde-Resultaten – ideal für Fragen wie «Wie hat die Stadt Zürich bei der AHV-Reform abgestimmt?». Benötigt SRGSSR_CONSUMER_KEY und SRGSSR_CONSUMER_SECRET.
Args: params (PolisVotationDetailInput): Enthält: - votation_id (str): Polis-ID aus democracy_polis_list_votations - lang (str): Ausgabesprache - include_municipalities (bool): Gemeinderesultate einschliessen
Returns: str: JSON mit Polis-Abstimmungsdetails, kantonalen und optionalen Gemeindedaten
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark it as read-only, idempotent, open-world. The description adds that it requires authentication (SRGSSR keys) and returns JSON with cantonal/optional municipal data, providing context beyond annotations. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise with four sentences plus a structured use case tag and args list. Every sentence adds value: purpose, use case, auth, parameter overview. No fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description does not need to detail return values. It covers input, auth, and use case adequately. Minor omission: no mention of rate limits or pagination, but not critical given the straightforward single-item retrieval.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description lists the three parameters from the input schema, but the schema itself already has detailed descriptions for each (e.g., votation_id source, lang enum, municipality inclusion effect). The description adds the auth requirement but does not significantly enrich the semantic meaning of the parameters beyond the schema; baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns detailed Polis data for a popular vote, with optional municipal results. It specifies the resource (votation detail) and verb (get), and distinguishes from siblings like democracy_polis_list_votations (listing) and democracy_bfs_get_vote_results (BFS data).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a concrete use case (analyzing municipal results like Zurich's AHV vote) and prerequisites (votation_id from list_votations, SRGSSR keys). It does not explicitly state when not to use or list alternatives, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
democracy_polis_list_electionsARead-onlyIdempotent
Ruft historische Wahlen (National-/Ständerat, Regierungsrat) aus Polis ab.
Wahlanalysen (Kandidierende, Parteistimmen) seit 1900.
Polis enthält Wahlresultate seit 1900, inkl. Kandidatinnen- und Parteistimmen. Benötigt SRGSSR_CONSUMER_KEY und SRGSSR_CONSUMER_SECRET.
Args: params (PolisElectionInput): Enthält: - year_from/year_to (int): Zeitraumfilter - lang (str): Ausgabesprache - limit (int): Max. Resultate
Returns: str: JSON mit Wahlliste oder Hinweis zur Registrierung
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true, which cover safety. The description adds that authentication is required and returns JSON with election list or registration hint. It does not contradict annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured with a title, use case tag, authentication note, and separate Args/Returns sections. It is not overly long, but the German language and special characters may slightly reduce readability for English agents.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the presence of an output schema (context signal), the description adequately covers purpose, parameters, authentication, and return type. It lacks explicit examples or exclusions, but for a list-like tool it is sufficiently complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description compensates by listing parameters (year_from, year_to, lang, limit) and their basic purpose. However, it does not provide detailed guidance such as format or example values beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it retrieves historical elections (National-/Ständerat, Regierungsrat) from Polis for analysis since 1900. The use case tag explicitly mentions 'Wahlanalysen', making the purpose distinct from sibling tools that deal with votations or popular votes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context: it requires API keys (SRGSSR_CONSUMER_KEY and SECRET). It also gives a use case indicator. However, it does not explicitly contrast with sibling tools (e.g., democracy_polis_list_votations) to guide when to choose this tool over alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
democracy_polis_list_votationsARead-onlyIdempotent
Ruft historische Volksabstimmungen aus dem SRGSSR Polis-System ab (seit 1900).
Historische Analysen mit Gemeinde-Granularität.
Polis enthält Resultate auf Gemeinde-Ebene, was für historische Analysen besonders wertvoll ist. Benötigt SRGSSR_CONSUMER_KEY und SRGSSR_CONSUMER_SECRET.
Args: params (PolisListInput): Enthält: - year_from/year_to (int): Zeitraumfilter - lang (str): Sprache ('de', 'fr', 'it', 'rm', 'en') - limit/offset (int): Pagination
Returns: str: JSON mit Polis-Abstimmungsliste oder Hinweis zur Registrierung
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent behavior. The description adds context about municipality granularity and authentication needs, but does not elaborate on rate limits or other constraints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured with a use case tag, authentication note, and parameter summary. It is slightly verbose but well-organized and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, the description covers authentication, parameter usage, output format, and the value of municipality-level data. No obvious gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description lists the parameters (year_from/year_to, lang, limit, offset) but adds little meaning beyond the input schema, which already has clear descriptions. With high schema coverage, baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves historical popular votes from the SRGSSR Polis system since 1900, with municipality-level granularity, distinguishing it from sibling tools like detail or election queries.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description highlights a specific use case (historical analysis at municipality level) and mentions authentication requirements, but does not explicitly state when not to use this tool or compare to alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
democracy_search_votesARead-onlyIdempotent
Durchsucht alle eidgenössischen Volksabstimmungen seit 1848 (Swissvotes-Datenbank).
Politische/journalistische Recherche: Vorlagen nach Thema, Zeitraum oder Ergebnis finden.
Filtert nach Stichwort, Zeitraum, Rechtsform, Ergebnis und Politikbereich. Gibt Titel, Datum, Rechtsform, Ja-Anteil, Beteiligung und Bundesratsempfehlung zurück.
Args: params (VoteSearchInput): Suchparameter mit optionalen Feldern: - keyword (str): Freitextsuche im Titel (DE/EN) - year_from/year_to (int): Zeitraumfilter - legal_form (str): 'initiative', 'obligatorisch', 'fakultativ' - result (str): 'angenommen' oder 'abgelehnt' - policy_domain (str): Politikbereich-Stichwort - limit (int): Max. Resultate (Standard: 20) - offset (int): Pagination-Offset
Returns: str: JSON mit 'total', 'count', 'offset', 'has_more', 'votes' (Liste von Vote-Objekten mit vote_number, date, title_de, legal_form, accepted, yes_percent, turnout_percent, federal_council_position)
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only, idempotent, non-destructive; description adds return field context and default limit, no contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections (description, use case, filters, returns, args), concise and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers all relevant aspects: filters, pagination, return fields (output schema present), no gaps given complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has full descriptions for parameters; description briefly repeats them without adding significant new meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches all federal popular votes since 1848, with use case and filter options, distinguishing it from siblings like democracy_get_vote_detail.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a use case tag and lists filter criteria, but lacks explicit when-not-to-use or alternative sibling guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
4 tool updates
v0.2.0- Changed
democracy_bfs_get_vote_results1 field changed- added
Input schema / $defs / BfsVoteResultInput / properties / level / enumAdded value: +[ + "national", + "cantonal", + "municipality" +]
- Changed
democracy_polis_get_votation_detail1 field changed- added
Input schema / $defs / PolisVotationDetailInput / properties / lang / enumAdded value: +[ + "de", + "fr", + "it", + "rm", + "en" +]
- Changed
democracy_polis_list_elections1 field changed- added
Input schema / $defs / PolisElectionInput / properties / lang / enumAdded value: +[ + "de", + "fr", + "it", + "rm", + "en" +]
- Changed
democracy_polis_list_votations1 field changed- added
Input schema / $defs / PolisListInput / properties / lang / enumAdded value: +[ + "de", + "fr", + "it", + "rm", + "en" +]
10 tool updates
v0.1.0- First observed
democracy_bfs_get_vote_results - First observed
democracy_bfs_list_vote_dates - First observed
democracy_get_cantonal_results - First observed
democracy_get_party_positions - First observed
democracy_get_vote_detail - First observed
democracy_list_vote_dates - First observed
democracy_polis_get_votation_detail - First observed
democracy_polis_list_elections - First observed
democracy_polis_list_votations - First observed
democracy_search_votes
TDQS
Most tools have distinct purposes, but there is overlap between democracy_list_vote_dates and democracy_bfs_list_vote_dates, and between democracy_get_vote_detail and democracy_bfs_get_vote_results. Descriptions clarify the different data sources, but an agent could still be confused.
All tools follow a consistent 'democracy_' prefix with snake_case verb_noun pattern. Source-specific tools (bfs, polis) maintain their own sub-pattern, while generic tools use clear verbs like get, list, search. No mixing of conventions.
10 tools is well-scoped for a Swiss democracy data server. Each tool covers a specific aspect: listing dates, searching, details, cantonal results, party positions, BFS real-time, Polis votes and elections. No tool feels superfluous or missing.
The tool set covers the main aspects of Swiss democratic data: vote search, listing, details, cantonal results, party positions, and two separate historical sources (Swissvotes and Polis). A minor gap is the lack of detailed election results (e.g., candidate-level data), but core workflows are supported.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
opendata.swiss MCP — Switzerland's federal open-data portal (CKAN catalogue).
MCP server for Brazilian Federal Senate open data (legislative, administrative, e-Cidadania).
An MCP server that provides congressional transcripts
Abgeordnetenwatch MCP — German federal & state parliament data.
Related MCP Servers
- AlicenseAqualityDmaintenanceSwiss open data MCP server — transport, weather, geodata, companies, etc,. Zero API keys.7622722MIT
- AlicenseAqualityAmaintenanceAn MCP server connecting AI models to the Swiss Federal Parliament via the Curia Vista OData API, enabling queries of motions, votes, members, sessions, and debate transcripts without authentication.7MIT
- AlicenseAqualityDmaintenanceAn unofficial MCP server for accessing Swiss Federal Statistical Office (BFS) data.81MIT
- FlicenseAqualityCmaintenanceMCP server for the Swiss federal tax calculator, providing income, wealth, inheritance, and corporate tax figures for all Swiss municipalities and tax years 2010-2026.132-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/malkreide/swiss-democracy-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server