mv-wahl-mcp
The server lets you search and retrieve the election programmes and Wahl-O-Mat data for all 19 parties in the Mecklenburg-Vorpommern 2026 Landtagswahl, as a retrieval-only research tool.
list_parties – View all 19 parties, their indexing status, source notes, and chunk counts.
search_programmes – Run FTS5 keyword searches across party programmes or Wahl-O-Mat theses/answers, with optional party and corpus filters.
get_party_programme – Fetch sequential text chunks of a selected party's programme or Wahl-O-Mat answers for reading.
coverage_status – Get a coverage table showing which parties are indexed and their source documentation.
Click on "Deploy 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., "@mv-wahl-mcpWhat do the parties say about affordable housing in their Wahlprogramme?"
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.
mv-wahl-mcp
MCP server for searching and retrieving the Wahlprogramme (election platforms) of all 19 parties admitted to the Landtagswahl Mecklenburg-Vorpommern 2026.
This is retrieval only — not a Wahl-O-Mat clone and not a voting recommender. Do not use it to compute "closeness" scores from user positions.
Built for Martin Müller / Remington S.: let a KI browse full party programmes (primary) plus the official bpb Wahl-O-Mat MV 2026 theses & answers (secondary corpus).
Quick start
git clone https://github.com/voundbrand/mv-wahl-mcp.git
cd mv-wahl-mcp
./run.shThat's it. The script creates a virtual environment if needed, installs dependencies, and starts the MCP server. The pre-built search index is included — no rebuild required.
Requirements: Python 3.11+
Related MCP server: mcp-bundestag-de
Add to Cursor or Claude Desktop
Run ./run.sh --print-config to get a ready-to-paste MCP configuration:
./run.sh --print-configCopy the output into your MCP config file:
Cursor:
~/.cursor/mcp.jsonor.cursor/mcp.jsonin your projectClaude Desktop:
claude_desktop_config.json
If you already have other MCP servers configured, merge the mv-wahl entry into your existing mcpServers object.
Features
Tool | Purpose |
| All 19 parties + indexing status |
| FTS5 keyword search ( |
| Fetch sequential chunks for one party |
| Coverage table (source → indexed) |
Corpora:
programme— full / website-captured Wahlprogramme (primary)wahlomat— bpb Wahl-O-Mat MV 2026 dataset (theses + party answers)
Test search without MCP
./run.sh & # or skip if you just want to test the search module
cd mv-wahl-mcp
source .venv/bin/activate
python -c "
from mv_wahl_mcp.search import search_programmes
import json
print(json.dumps(search_programmes('Wohnungsbau', limit=5), ensure_ascii=False, indent=2))
"Data layout
data/
parties.json # metadata + source URLs for all 19
programmes/ # PDF sources
programmes_text/ # pdftotext extracts
wahlomat/ # bpb Datensatz zip + xlsx
index.db # SQLite + FTS5 (pre-built, ready to use)Wahl-O-Mat dataset
Downloaded from the bpb download page:
https://www.bpb.de/themen/wahl-o-mat/mecklenburg-vorpommern-2026/579912/download/
File:
Wahl-O-Mat_Mecklenburg-Vorpommern_2026_Datensatz.zip
bpb licence restricts creating Wahl-O-Mat-like recommenders from the dataset; this project only indexes text for search/retrieval (journalistic/research-style analysis).
Programme sources
Prefer official party / Landesverband PDFs where available. Many smaller parties are mirrored via the schwerin.news Aug 2026 aggregation of all admitted lists:
See data/parties.json and the coverage_status tool for per-party notes. Short / website-captured texts (e.g. Die PARTEI, WLD, Team Freiheit, Handwerker 10-Punkte) are documented honestly.
Re-extract / re-index (optional)
Only needed if you modify the source PDFs or Wahl-O-Mat data:
# Needs poppler-utils (pdftotext)
for f in data/programmes/*.pdf; do
base=$(basename "$f" .pdf)
pdftotext -layout "$f" "data/programmes_text/${base}.txt"
done
python scripts/build_index.pyLicence / ethics
Party programmes remain copyright of the respective parties.
Wahl-O-Mat dataset © Bundeszentrale für politische Bildung — see
data/wahlomat/Hinweis.txt.This tool must not be turned into a proximity/voting recommender.
Coverage (build-time snapshot)
All 19/19 admitted Landeslisten are indexed. Volume varies:
Party | Chars (approx) | Notes |
SPD, AfD, CDU, Die Linke, GRÜNE, FDP, BSW, Volt | large full programmes | Official / Landesverband PDFs |
Tierschutzpartei, FREIE WÄHLER, Bündnis C, PdF, KPD | medium | Official or aggregator PDFs |
PIRATEN, ÖDP | shorter full programmes | Official / aggregator |
Die PARTEI, Team Freiheit, WLD | website captures | No long PDF published |
Handwerker Partei Deutschland | short 10-point PDF | Intentional short programme |
Secondary corpus: 722 Wahl-O-Mat position rows (38 theses × 19 parties) from the official bpb dataset.
Available Tools
4 toolscoverage_statusA
Return coverage table: which of the 19 parties are indexed and source notes.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description must convey behavioral traits. It only states 'Return', implying a read operation, but does not explicitly confirm it is non-destructive, nor does it mention any side effects, permissions, or limitations. The behavior is essentially a simple retrieval, but this is not disclosed beyond the verb.
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 a single, direct sentence that front-loads the action and specifies the output content. There is no unnecessary wording or repetition, making it highly efficient.
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 and no parameters, the description provides the essential context: it returns a coverage table of indexed parties with source notes. It mentions the specific count of 19 parties, which is helpful. The description is sufficient for an agent to know what to expect, though it could optionally clarify the read-only nature, which is covered by behavioral transparency.
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 tool has zero parameters, so the input schema is fully covered by default. The description correctly avoids adding parameter details since there are none, earning the baseline score for parameterless 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 specifies a clear action ('Return coverage table') and identifies the specific content (which of the 19 parties are indexed and source notes). This distinguishes it from siblings like list_parties (listing) and search_programmes (searching) by focusing on coverage status.
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 no guidance on when to use this tool versus alternatives. It merely states what it does without any contextual triggers, exclusions, or references to sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_party_programmeA
Fetch sequential text chunks from one party's programme (or Wahl-O-Mat answers).
Args: party: Party id or short name (e.g. "CDU", "Volt", "BSW"). offset: Chunk offset (0-based). limit: Number of chunks to return (1–50). corpus: "programme" (default) or "wahlomat".
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| party | Yes | ||
| corpus | No | programme | |
| offset | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden. It discloses the sequential chunking behavior and the alternative corpus, which is helpful. However, it does not describe edge cases like end-of-document behavior, chunk ordering guarantees, or whether the operation is purely read-only, though 'Fetch' implies a safe read.
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 short and purposeful: a one-sentence summary followed by a compact Args block. Every line adds necessary parameter semantics, with no filler or repetition of schema titles.
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?
The tool is simple and an output schema exists, so return values need no explanation. The description covers core behavior and all parameters, though it omits minor context such as how to discover valid party IDs via list_parties. This is a minor gap given the provided examples.
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 must compensate, and it does thoroughly. It explains each parameter beyond the schema: party with concrete examples, offset as 0-based chunk offset, limit as a 1–50 count, and corpus with its two possible values and default.
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 states a specific verb ('Fetch'), a resource ('sequential text chunks from one party's programme'), and an optional alternative corpus ('Wahl-O-Mat answers'). It clearly distinguishes from sibling tools like search_programmes by emphasizing sequential chunk retrieval versus searching, though it does not explicitly name alternatives.
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?
Usage is implied by the description: use this tool when you need to read a party's programme or Wahl-O-Mat answers as sequential chunks. However, it provides no explicit when-to-use or when-not-to-use guidance, and does not mention search_programmes or list_parties as alternatives for different needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_partiesA
List all 19 parties with indexing status, source notes, and chunk counts.
| 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?
With no annotations, the description carries the behavioral burden. It accurately portrays a read-only list operation, states the fixed scope (all 19 parties), and describes the returned content. It does not mention auth or rate limits, but for a simple listing tool the behavioral profile is sufficiently clear.
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?
A single sentence that is front-loaded with the core action and scope, followed by the specific output attributes. Every word earns its place with no filler or repetition.
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 parameterless list tool with an output schema, the description covers the essential use case and return content, which is sufficient. It does not mention ordering, but given the fixed 'all 19 parties' scope and available output schema, nothing critical is missing.
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 tool has zero parameters, so there is nothing for the description to explain beyond what the schema already shows. This meets the baseline for parameterless 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 uses a specific verb ('List') with a clear resource ('all 19 parties') and enumerates the output fields (indexing status, source notes, chunk counts). This clearly distinguishes it from siblings like search_programmes and get_party_programme, which target searching or single-party retrieval.
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 implies when to use the tool—when an agent needs an overview of all parties—but it does not explicitly state alternatives or when not to use it. No exclusions or comparisons to sibling tools are given, so usage guidance is inferred rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_programmesA
Keyword/FTS search across Wahlprogramme (and optionally Wahl-O-Mat answers).
Args: query: Search terms in German or English (e.g. "Wohnungsbau", "Energiewende"). party: Optional party filter (id or short name, e.g. "SPD", "GRÜNE", "Die Linke"). corpus: Optional "programme" (full platforms) or "wahlomat" (theses + answers). limit: Max hits (1–50, default 10).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| party | No | ||
| query | Yes | ||
| corpus | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full burden. It conveys important behavior constraints like language support, optional corpora, and a 1–50 hit limit, which is useful. It does not explicitly state that this is read-only/has no side effects, nor how null party/corpus defaults behave, though the output schema helps with return shape.
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 compact and well-structured: a one-line purpose statement followed by a labeled Args block. Every line contributes useful parameter or behavior information, with no filler or 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?
For a search tool with four parameters and an output schema, this description is nearly complete: all parameters are explained with types, examples, and constraints. The only gaps are the lack of explicit sibling-tool routing and a precise statement of default corpus behavior, which are minor given the clear operation and output schema.
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%, and the description fully compensates: it explains query semantics with language examples, party as id or short name with examples, corpus as 'programme' vs 'wahlomat', and limit range/default. This adds genuine meaning beyond the bare property titles.
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 starts with a specific action and resource: 'Keyword/FTS search across Wahlprogramme (and optionally Wahl-O-Mat answers).' This makes the tool's scope clear and distinguishes it from sibling tools like list_parties, coverage_status, and get_party_programme, which are not search operations.
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 Args block provides operational guidance, such as party filters, corpus selection, and limit range, so an agent knows how to shape calls. However, it never explicitly says when to prefer this tool over get_party_programme or when not to use it, leaving cross-tool routing implied rather than stated.
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.
4 tool updates
v0.1.0- First observed
coverage_status - First observed
get_party_programme - First observed
list_parties - First observed
search_programmes
TDQS
Scored across 4 tools
The tools list_parties and coverage_status both report on which of the 19 parties are indexed, with only minor differences (chunk counts vs. a coverage table). This overlap could cause misselection, while search_programmes and get_party_programme are clearly distinct.
Tool names are consistently lowercase with underscores and mostly follow a verb_noun pattern (list_parties, search_programmes, get_party_programme). The exception is coverage_status, which uses a noun phrase, but it remains readable and predictable.
With exactly 4 tools, the server is well-scoped for its purpose of listing, checking coverage, searching, and retrieving election programme content. Each tool has a clear role and the count is appropriate.
The server covers the core read-only workflows: listing parties, verifying indexing status, performing keyword search, and fetching chunked content. No obvious gaps exist for the stated domain of accessing Wahlprogramme and Wahl-O-Mat data.
Maintenance
Related MCP Connectors
Abgeordnetenwatch MCP — German federal & state parliament data.
Danish parliamentary cases, votes, politicians, parties, elections, and comparison tools.
GovData.de MCP — Germany's national open-data portal (CKAN API).
Search public procurement notices from 17 sources across Germany, the EU and the UK. Read-only.
Related MCP Servers
- AlicenseAqualityCmaintenanceProvides unified access to German federal and state legislation, court decisions, and European Union legal databases for comprehensive legal research. It enables users to search and retrieve full-text laws, parliamentary documents, and judicial rulings directly through the Model Context Protocol.20122 npmGPL 3.0
- AlicenseNot gradedqualityCmaintenanceEnables searching and retrieving documents, activities, and plenary protocols from the German Bundestag's DIP system via MCP tools.3 npmMIT
- AlicenseNot gradedqualityDmaintenanceProvides programmatic access to official German Bundestag parliamentary data, enabling LLMs to answer questions about legislation, voting records, and members.1MIT
- FlicenseNot gradedqualityBmaintenanceProvides live, source-linked transparency data on German MPs, including roll-call voting, side jobs, committee memberships, and election programs, via the Abgeordnetenwatch API. No API key required.-