parlament-mcp
The parlament-mcp server connects AI models to the Swiss Federal Parliament's Curia Vista API, enabling read-only search and retrieval of parliamentary data — no API key required.
parlament_search_business: Search parliamentary motions, interpellations, postulates, and other submissions by keyword, type, status (e.g.'Eingereicht','Erledigt'), council ('NR','SR'), and submission date.parlament_get_business: Retrieve full details of a specific business by its Curia Vista ID, including the motion text, initial situation, and Federal Council response.parlament_search_members: Find National and State Councillors filtered by canton (e.g.'ZH','BE'), party (e.g.'SP','SVP'), council, last name, or active status.parlament_get_votes: Access voting records with yes/no meanings explained, filterable by keyword or session ID.parlament_get_sessions: List recent parliamentary sessions with IDs, names, and dates — IDs can be used to filter votes or transcripts.parlament_search_transcripts: Search verbatim Amtliches Bulletin debate transcripts by keyword, speaker name, session ID, or council. Returns citable excerpts with source URLs (coverage from 1999 onward).parlament_get_transcript: Fetch the complete verbatim text of a single speech by ID, with pagination support — always the exact original wording, never summarised.
Key use cases: finding pending motions on specific topics, quoting exactly what a councillor said with proper citations, cross-referencing votes on legislation, or combining with tools like fedlex-mcp to link law texts to the debates that created them.
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., "@parlament-mcpFinde alle hängigen Motionen zum Thema KI in der Bildung"
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.
🏛️ parlament-mcp
Part of the Swiss Public Data MCP Portfolio – connecting AI models to Swiss public data sources.
Note: This server covers the federal level (Curia Vista). This repo additionally hosts a self-contained subproject under
openparldata-mcp/— the subnational counterpart for the 26 cantons and ~70 municipal parliaments (OpenParlData.ch). The two are independent servers.
An MCP server that connects AI models to the Swiss Federal Parliament via the
Curia Vista OData API (ws.parlament.ch).
Access motions, interpellations, votes, members, sessions, and the verbatim
debate transcripts of the Amtliches Bulletin – with no API key required
(Phase 1 – No-Auth-First).
🎯 Anchor Demo Queries
Metadata layer:
"Welche Vorstösse zu KI in der Schule sind hängig?" →
parlament_search_business(keyword="KI", keyword2="Schule", status="Eingereicht")
Verbatim transcripts (Amtliches Bulletin):
"What did National Councillor Munz say in the 2024 spring session about the Volksschule? Give me the exact wording with a correct AB citation." →
parlament_search_transcripts(speaker_name="Munz", session_id=5202, keyword="Volksschule")→ thenparlament_get_transcript(transcript_id=…)for the full wording.Returns short, citable excerpts (
AB 2024 N, 2024-03-13, Munz Martina) with a stable source URL; the verbatim text is fetched on demand, never in bulk.
Perfect for the KI-Fachgruppe Stadtverwaltung Zürich: find pending motions on AI in education, or quote what was actually said in the chamber – instantly.
Related MCP server: lobbywatch-mcp
🔧 Tools
Tool | Description |
| Search Vorstösse by keyword, type, status, council, date |
| Full details of a single business (texts, FC response) |
| Find councillors by canton (e.g. ZH), party, council |
| Parliamentary votes with Ja/Nein meaning |
| List recent sessions with IDs for follow-up queries |
| Search debate transcripts → citable excerpts with AB citation + source URL (speaker / session / business / date filters) |
| Fetch the verbatim full text of a single speech by ID (capped, paginated, |
🏗️ Architecture
┌──────────────────────────────────┐
│ MCP Host (Claude Desktop / │
│ Claude API / IDE) │
└─────────────┬─────────────────────┘
│ MCP Protocol (JSON-RPC 2.0)
│ Transport: stdio (local) / SSE (cloud)
┌─────────────▼─────────────────────┐
│ parlament-mcp │
│ FastMCP · Python · Pydantic v2 │
│ │
│ ┌── metadata layer (server.py) ──┐
│ │ search_business · get_business │
│ │ search_members · get_votes │
│ │ get_sessions │
│ └─────────────────────────────────┘
│ ┌── transcript layer ────────────┐ ← separate module (transcripts.py)
│ │ search_transcripts (excerpts) │ · Language='DE' dedups editions
│ │ get_transcript (verbatim) │ · Type=1 = real speeches only
│ └─────────────────────────────────┘ · retry + 45s read timeout
└─────────────┬─────────────────────┘
│ HTTPS / OData v3
┌─────────────▼─────────────────────┐
│ ws.parlament.ch / odata.svc │
│ Curia Vista – No Auth Required │
│ │
│ Business · Vote · MemberCouncil │ metadata path
│ Session ─< Meeting ─< Subject ─< Transcript transcript path
└───────────────────────────────────┘🚀 Installation
Claude Desktop (stdio)
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"parlament": {
"command": "uvx",
"args": ["parlament-mcp"]
}
}
}Local development
git clone https://github.com/malkreide/parlament-mcp
cd parlament-mcp
pip install -e .
python -m parlament_mcp.serverCloud / Railway (SSE)
MCP_TRANSPORT=sse MCP_HOST=0.0.0.0 PORT=8080 python -m parlament_mcp.server
# SSE endpoint: http://your-host:8080/sseNetwork binding
By default the server binds to 127.0.0.1 (localhost only). Set
MCP_HOST=0.0.0.0 only inside a container/cloud context (Docker, Railway,
Render, Kubernetes). Never bind to 0.0.0.0 on a local dev machine – it exposes
the server to your local network (NeighborJack risk); the server logs a warning
if you do so outside a detected container.
Transport is selected via MCP_TRANSPORT (stdio default, or sse /
streamable-http); --http is kept as an alias for streamable-http.
Authentication (optional)
The HTTP transport is open by default (public read-only data). To require a
bearer token, serve via the CORS/auth app factory and set MCP_BEARER_TOKENS:
MCP_BEARER_TOKENS="alice:tok_abc,bob:tok_def" MCP_ALLOWED_ORIGINS="https://claude.ai" \
uvicorn parlament_mcp.server:create_http_app --factory --host 0.0.0.0 --port 8080Each request then needs Authorization: Bearer <token>; identity comes from the
validated token, not a session header (see docs/security.md).
Docker
docker compose up --build # binds 127.0.0.1:8080 only
# or build the hardened image directly (non-root, read-only FS):
docker build -t parlament-mcp .Kubernetes manifests (hardened securityContext, resource limits, egress
NetworkPolicy, Mcp-Session-Id sticky routing) live in deploy/k8s/;
an HAProxy stick-table example is in deploy/haproxy.cfg.
🔗 Synergies
Partner Server | Combination |
Federal ↔ subnational — same question across cantons & municipalities | |
Law text ↔ parliamentary debate that created it | |
City policy ↔ cantonal/federal motions | |
Data backing ↔ motions citing statistics |
Power query example:
"Zeige mir alle Zürcher Motionen zu KI in der Bildung
und verlinke die relevanten Bundesgesetze aus fedlex-mcp."📊 Data Source
Authentication: None (Phase 1 – No-Auth-First)
Protocol: OData v3 / JSON
Coverage: All parliamentary businesses since 1978; votes since ~2000. Structured verbatim transcripts (Amtliches Bulletin) from 1999-12-06 onward (earlier years 1891–1999 exist only as archive scans — see Known Limitations).
Update cycle: Real-time (official government data)
Copyright — verbatim quotation is allowed
Official proceedings of Swiss authorities are excluded from copyright under Art. 5 para. 1 lit. a URG (Swiss Copyright Act). The verbatim wording of parliamentary debates in the Amtliches Bulletin may therefore be reproduced and quoted freely — which is exactly what the transcript tools return: the wording itself, never a summary standing in for it.
📜 Data sources & licenses
Source | License | Attribution |
Curia Vista (ws.parlament.ch) | CC BY 4.0 | © Schweizer Parlament, CC BY 4.0 |
Every tool returns a typed structured response (FastMCP exposes the output
schema) carrying source, license, provenance, match_type and count
alongside typed results. Data is passed through unmodified.
🧭 Phase
This server is in Phase 1 — Read-only Wrapper (all tools readOnlyHint: true,
no writes). The full phase model and transition criteria are in
docs/roadmap.md.
🔖 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.
🧱 MCP primitives
Phase 1 uses Tools only — rationale and the Phase-2 Resources plan are in
docs/adr/ADR-003-mcp-primitives.md.
🏷️ Tool annotations
All tools declare explicit annotations consistent with their behaviour:
Tool | readOnly | destructive | idempotent | openWorld |
| ✅ | — | ✅ | ✅ |
| ✅ | — | ✅ | ✅ |
| ✅ | — | ✅ | ✅ |
| ✅ | — | ✅ | ✅ |
| ✅ | — | ✅ | ✅ |
| ✅ | — | ✅ | ✅ |
| ✅ | — | ✅ | ✅ |
📈 Observability
Structured JSON logs go to stderr (stdout stays reserved for the stdio
protocol). OpenTelemetry tracing wraps each tool call and auto-instruments
outgoing HTTP; set OTEL_EXPORTER_OTLP_ENDPOINT (with the otel-export extra)
to ship spans. See docs/security.md for the full security
posture (Lethal-Trifecta assessment, egress allow-list, gateway hardening).
🛡️ Safety & Limits
Aspect | Details |
Access | Read-only ( |
Personal data | Parliamentary businesses are public record by law (BGÖ). No private data is accessed or stored. |
Rate limits | Built-in per-query caps: max. 100 results (businesses/members), 50 (votes), 30 (transcript search), 10 (sessions). Transcript full text is capped per call and paginated — you never pull a whole session by accident. |
Timeout | 20 seconds per metadata call; 45 seconds for transcript reads (verbatim search is heavier) |
Authentication | No API keys required — Curia Vista is publicly accessible |
Data source | Official Swiss federal government data (Schweizerische Parlamentsdienste) |
Terms of Service | Subject to ToS of ws.parlament.ch — Schweizerische Parlamentsdienste |
Known Limitations
General
OData
substringof()filter is case-sensitive for some fields.Session names may be
nullin the API for very recent sessions – use session ID.
Transcripts (Amtliches Bulletin) — verified live 2026-07-19:
Temporal coverage: from 1999-12-06 only. The structured
Transcriptentity reaches back to Dec 1999. Debates from 1891–1999 exist only as scanned archive documents (Bundesarchiv / Amtsdruckschriften) and are not connected here (no OCR in scope). A query whose whole date window predates coverage returns an explanatory error, not an empty result.No page number in the source. The API carries no page/column field, so the classic
AB <year> N <page>form cannot be built. We emit a stable, verifiable substitute —AB <year> <N|S>, <date>, <speaker>— plus the authoritativesource_url(SubjectId) and thetranscript_id. This is a documented, honest trade-off, not an omission.Language behaviour (important).
Languageis the edition, not the spoken language. The tools filterLanguage eq 'DE'purely to deduplicate the three byte-identical editions (DE/FR/IT) down to one copy. Every speech is returned in its original wording; a French or Italian speech is not hidden — its real language is reported in thelanguagefield (de/fr/it). The response states this vialanguage_note.Truncation is explicit, never silent. Search returns short excerpts (
snippet, ~320 chars) withis_excerpt,total_length_charsand a hint to fetch the full text.parlament_get_transcriptcaps output atmax_chars; when it truncates it setsis_excerpt=Trueand returns anext_offsetto continue.Verbatim only, never summarised. The wording is the product; the tools never substitute a summary for the actual text.
Latency: a free-text
keywordcombined with aspeaker_nameis the slowest path (~40 s). Add asession_id,business_numberor date window to keep reads around 1–2 s.
🧪 Testing
pip install -e ".[dev]"
# Unit + mocked integration tests (no network), as run in CI:
PYTHONPATH=src pytest tests/ -m "not live"
# Include live tests against the real ws.parlament.ch API:
PYTHONPATH=src pytest tests/ -m liveHTTP is mocked with respx; network-dependent tests are marked
@pytest.mark.live and excluded from CI via -m "not live". Tool definitions are
pinned in tool-hashes.json (python -m parlament_mcp.tool_hashes --check).
Contributing
See CONTRIBUTING.md.
Security
See SECURITY.md for the security policy and posture (vulnerability reporting, Lethal-Trifecta assessment, accepted risks).
License
MIT © Hayal Oezkan — see LICENSE
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": {
"parlament-mcp": {
"command": "uvx",
"args": [
"parlament-mcp"
]
}
}
}Available Tools
7 toolsparlament_get_businessARead-onlyIdempotent
Vollständige Details eines parlamentarischen Vorstosses nach Curia Vista ID abrufen.
Nach einer Suche verwenden, um vollständige Informationen inkl. Ausgangslage, Vorstosstext und Antwort des Bundesrats zu erhalten.
Benötigt die numerische Geschäfts-ID (aus
parlament_search_business). found=false bei unbekannter ID.
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | |
| url | No | |
| tags | No | |
| type | No | |
| found | No | |
| title | No | |
| source | No | |
| status | No | |
| council | No | |
| license | No | |
| department | No | |
| description | No | |
| motion_text | No | |
| proceedings | No | |
| status_date | No | |
| short_number | No | |
| submitted_by | No | |
| submitted_text | No | |
| submission_date | No | |
| initial_situation | No | |
| federal_council_response | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only, idempotent, non-destructive behavior. The description adds behavioral context beyond annotations by explaining the 'found=false' return value for invalid IDs and the need for a prior search. This adds useful transparency.
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: a single-line purpose, followed by structured XML tags for use case and important notes. Every sentence adds value, and the 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?
The description covers the input (ID), usage context (post-search), and error behavior (found=false). Since an output schema exists, return values do not need explanation. The description is complete for this tool's purpose.
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 already provides descriptions for both parameters (business_id and language). The description reinforces the importance of the ID but does not add new semantics for the language parameter. With 0% schema description coverage in the context, the description partially compensates but misses the optional language parameter.
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 verb 'abrufen' (retrieve) and resource 'Details eines parlamentarischen Vorstosses', and the use case distinguishes it from the sibling tool 'parlament_search_business'. It is specific and action-oriented.
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 explicit usage guidance: use after a search to get full details, requires the numeric business ID from search, and notes that 'found=false' is returned for unknown IDs. This clearly tells when and how to use the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
parlament_get_sessionsARead-onlyIdempotent
Aktuelle parlamentarische Sessionen mit Daten auflisten.
Session-IDs aus dieser Liste zum Filtern von Abstimmungen oder Transkripten verwenden.
Session-Namen können für sehr aktuelle Sessionen null
sein – dann die Session-ID verwenden.
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| count | No | |
| offset | No | |
| source | No | |
| license | No | |
| results | No | |
| match_type | No | |
| provenance | No | |
| suggestions | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint, idempotentHint, and nondestructive. The description adds important behavioral context: session names can be null for recent sessions. This goes 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, using a single sentence plus structured XML tags for use case and notes. However, it could be slightly more efficient by integrating the notes into the main text.
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 output schema exists, the description explains the tool's purpose and a key behavioral note (null names). However, it omits parameter descriptions, which are essential for proper invocation. This is a moderate gap.
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%, yet the description does not explain the parameters (limit, offset). It only describes the output, leaving the agent to infer input semantics from the schema alone. This is a significant gap.
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 verb 'auflisten' (list) and the resource 'parlamentarische Sessionen' (parliamentary sessions). The use case explicitly mentions using session IDs for filtering votes or transcripts, distinguishing this tool from siblings like get_votes or get_transcripts.
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 clear use case for when to use the tool (fetching session IDs for filtering). However, it does not explicitly state when not to use it or mention alternatives, though for a simple listing tool this is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
parlament_get_transcriptARead-onlyIdempotent
Den vollen Wortlaut eines einzelnen Votums nach Transkript-ID abrufen.
Nach einer Suche mit parlament_search_transcripts den kompletten Wortlaut eines konkreten Votums holen – zitierfähig, mit stabiler URL.
Ausgabe ist gedeckelt (max_chars); bei Kürzung ist
is_excerpt=True gesetzt und note/next_offset erklären, wie die
Fortsetzung zu laden ist. Kein stilles Kürzen. Der Wortlaut wird nie durch
eine Zusammenfassung ersetzt.
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| date | No | |
| note | No | |
| text | No | |
| found | No | |
| group | No | |
| canton | No | |
| offset | No | |
| source | No | |
| council | No | |
| license | No | |
| speaker | No | |
| citation | No | |
| function | No | |
| language | No | |
| is_excerpt | No | |
| provenance | No | |
| session_id | No | |
| source_url | No | |
| next_offset | No | |
| transcript_id | No | |
| business_title | No | |
| business_number | No | |
| total_length_chars | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The <important_notes> section discloses non-obvious behavior: the output is capped by max_chars, truncation is signaled by is_excerpt=True, and note/next_offset explain how to load the continuation. It also promises no silent truncation and no summarization, going beyond the readOnly/idempotent 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 lead sentence, a <use_case> block, and an <important_notes> block. Every sentence adds functional value, and the formatting makes it easy to scan.
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 single-record retrieval tool with rich annotations and an output schema, the description covers what is fetched, when to use it, and the pagination/truncation contract. No return-value documentation is needed because the output schema exists.
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?
With schema description coverage at 0%, the description compensates by tying transcript_id to the lookup key and explaining that max_chars caps the response, with is_excerpt/next_offset for continuation. It does not describe the offset parameter directly, but the continuation note implies its role.
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 opens with a specific verb+resource statement: 'Den vollen Wortlaut eines einzelnen Votums nach Transkript-ID abrufen' (retrieve the full wording of a single speech by transcript ID), which clearly distinguishes this tool from the search-oriented siblings. It also names the exact follow-up use case after parlament_search_transcripts.
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 <use_case> section explicitly says to use this after a search with parlament_search_transcripts to get the complete, quotable wording of a specific Votum. It does not list alternative tools or explicit 'when not to use' exclusions, but the context is clear enough to guide tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
parlament_get_votesBRead-onlyIdempotent
Parlamentarische Abstimmungen (im Rat) mit Ja/Nein-Bedeutung abrufen.
Zeigt, wie der Rat über Themen wie KI-Regulierung, Bildungsfinanzierung oder Digitalisierungsprojekte abgestimmt hat.
meaning_yes/meaning_no erklären, was ein Ja/Nein im
konkreten Geschäft bedeutet – wichtig zur korrekten Interpretation.
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| count | No | |
| offset | No | |
| source | No | |
| license | No | |
| results | No | |
| match_type | No | |
| provenance | No | |
| suggestions | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnly, idempotent, and non-destructive nature. Description adds value by highlighting the importance of 'meaning_yes'/'meaning_no' for correct interpretation, which is not evident from annotations alone.
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 with two sentences plus structured use_case and important_notes. No redundancy, but could be more efficient by integrating note into main text.
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, return values need not be explained. However, parameter semantics are missing and usage context is sparse. For a simple retrieval tool, it is incomplete.
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%, meaning parameters lack descriptions in the schema. The tool description does not explain any parameters (limit, offset, keyword, session_id), relying solely on the schema which is insufficient.
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 parliamentary votes with yes/no meaning, using specific verb 'abrufen' and resource 'Abstimmungen'. Use case examples differentiate from siblings like get_sessions or get_business.
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?
No explicit guidance on when to use this tool versus alternatives like parlament_search_business or when not to use it. The use case provides context but lacks comparative direction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
parlament_search_businessARead-onlyIdempotent
Parlamentarische Vorstösse suchen (Motionen, Interpellationen, Postulate usw.).
Durchsucht Curia Vista Geschäftsdaten von ws.parlament.ch.
Politische Recherche zu Bildungs-, Datenschutz- oder Verwaltungsthemen; hängige Vorstösse zu KI in der Bildung, Digitalisierungsinitiativen oder beliebigen Politikthemen finden.
Titel-Suche via OData substringof() (gross-/klein-sensitiv).
Maximal 100 Treffer pro Aufruf; mit offset paginieren.
keyword='KI', keyword2='Schule', status='Eingereicht'
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| count | No | |
| offset | No | |
| source | No | |
| license | No | |
| results | No | |
| match_type | No | |
| provenance | No | |
| suggestions | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint, idempotentHint, and destructiveHint=false. The description adds critical behavioral details beyond annotations: case-sensitive OData substringof search, maximum 100 results per call, and pagination via offset. 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 well-structured with tags for use_case, important_notes, and example. It is concise (around 4 sentences plus tags) and front-loaded with the main purpose. Minor verbosity from tags but overall effective.
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, the description adequately covers use cases, important technical notes (case sensitivity, pagination), and provides an example. It is complete enough for a search tool with well-documented parameters.
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 has detailed descriptions for each parameter (limit, offset, status, etc.), so the description adds minimal additional semantic value. It mentions OData substringof for title search but does not explain each parameter beyond the schema. Baseline 3 is appropriate given schema coverage.
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 purpose: searching parliamentary business (motions, interpellations, etc.) in German. It distinguishes itself from sibling tools like parlament_get_business (for single business) and other search/get tools for sessions, transcripts, votes, and members.
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 with specific political research topics, providing clear context for when to use the tool. It does not explicitly state when not to use it, but the sibling tools are distinct enough to imply alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
parlament_search_membersARead-onlyIdempotent
National- und Ständeräte suchen.
Alle Zürcher Ratsmitglieder ('ZH') oder Mitglieder einer bestimmten Partei finden. Synergie: mit parlament_search_business kombinieren, um Urheber von Vorstössen zu identifizieren.
active_only=True (Default) liefert nur amtierende
Mitglieder. Kanton als 2-Buchstaben-Kürzel.
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| count | No | |
| offset | No | |
| source | No | |
| license | No | |
| results | No | |
| match_type | No | |
| provenance | No | |
| suggestions | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, confirming safe read operation. The description adds behavioral detail beyond annotations by specifying the default active_only=True behavior and canton format, though it omits pagination details which are covered by the schema.
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 with a single sentence, a use case tag, and important notes tag. No wasted words; all content is valuable and well-structured.
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 seven parameters and presence of an output schema, the description covers the main purpose, typical use cases, and key behavior. It lacks explanation of offset/limit but those are standard and schema-defined. Overall adequate for a search 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 description adds moderate value over the schema: it reinforces canton format and active_only default, but the schema already provides adequate descriptions for all parameters (e.g., party, council, last_name). With 0% overall schema description coverage, the tool description compensates partially but not heavily.
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 for members of National and Ständeräte, and distinguishes from siblings by mentioning synergy with parlament_search_business for identifying motion authors. The use case example reinforces the purpose.
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 explicit usage scenarios (finding all Zurich members or members of a party) and notes important defaults and format requirements (active_only=True, canton as 2-letter code). It also guides users to combine with a sibling tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
parlament_search_transcriptsARead-onlyIdempotent
Wörtliche Wortmeldungen aus den Ratsdebatten durchsuchen (Amtliches Bulletin).
Liefert kurze, zitierfähige Auszüge (kein Volltext) mit korrekter
AB-Zitation und stabiler Quell-URL. Für den Wortlaut eines einzelnen Votums
danach parlament_get_transcript(transcript_id=…) verwenden.
«Was hat Nationalrätin X in der Frühjahrssession 2024 zur Volksschule gesagt?» – Sprecher, Session, Rat, Geschäft oder Datumsfenster kombinieren. Synergie mit fedlex-mcp: vom Gesetzestext zur Debatte.
Nur echte Wortmeldungen (keine Abstimmungszeilen). Der
Language-Filter dedupliziert die Editionen und blendet keine
französisch-/italienischsprachigen Voten aus – die reale Sprache steht in
language. Abdeckung ab 1999-12-06. Für beste Latenz session_id,
business_number oder ein Datumsfenster mit einem freien keyword
kombinieren.
speaker_name='Munz', session_id=5202, keyword='Volksschule'
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| count | No | |
| offset | No | |
| source | No | |
| edition | No | |
| license | No | |
| results | No | |
| match_type | No | |
| provenance | No | |
| suggestions | No | |
| citation_note | No | |
| language_note | No | |
| coverage_since | No | |
| full_text_hint | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark readOnlyHint=true and idempotentHint=true, but the description adds substantial behavioral detail beyond that: it returns only real spoken contributions (not voting lines), explains that the Language filter deduplicates editions but does not hide French/Italian votes, and states coverage starts at 1999-12-06. These are valuable context for the agent.
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 distinct sections (main statement, return format, pointer to related tool, use_case, important_notes, example). Every sentence adds value: the limitation of excerpts, the language filter behavior, coverage start, and a concrete example. It is detailed but not bloated, and the front-loaded purpose sentence is immediately clear.
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 description covers the essential aspects for a search tool: what it searches, what it returns (short quotable extracts with citation and stable URL), what it does not return (full text), which sibling to use next, scope limitations, and coverage date. It also addresses the Language filter nuance. Given the output schema exists and the input schema has detailed per-parameter descriptions, this is fully 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?
While the description does not individually document each parameter, the input schema itself provides thorough descriptions for all nested properties (limit, offset, council, dates, keyword, session_id, speaker_name, business_number). The tool description adds practical usage meaning via the example (speaker_name='Munz', session_id=5202, keyword='Volksschule') and latency guidance for combining parameters, which goes beyond raw schema listings.
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 opens with a specific verb+resource: 'Wörtliche Wortmeldungen aus den Ratsdebatten durchsuchen (Amtliches Bulletin)' – clearly searching verbatim contributions in council debates. It further distinguishes itself from siblings by stating it returns 'kurze, zitierfähige Auszüge (kein Volltext)' and explicitly redirects to parlament_get_transcript for the full text of a single vote.
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 explicit guidance: use this tool for search/snippets, then call parlament_get_transcript for the exact full wording. It also gives a concrete use case and performance tips (combine session_id, business_number, or a date window with a free keyword for best latency), plus notes about synergie with fedlex-mcp.
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.
3 tool updates
v0.3.4- Added
parlament_get_transcript - Removed
parlament_get_transcripts - Added
parlament_search_transcripts
6 tool updates
v0.3.3- First observed
parlament_get_business - First observed
parlament_get_sessions - First observed
parlament_get_transcripts - First observed
parlament_get_votes - First observed
parlament_search_business - First observed
parlament_search_members
TDQS
Scored across 7 tools
Each tool targets a distinct resource and action: search vs. get, and business/transcripts/members/votes/sessions are clearly separated. The two search tools return different entity types, and the two get tools are distinguished by ID and purpose.
All tool names follow a consistent verb_noun pattern with 'search_' for queries and 'get_' for retrievals. No mixed conventions or vague verbs.
Seven tools cover the core parliamentary data domain without bloat. Each tool has a clear, non-redundant role, and the count is within the ideal 3-15 range.
The set covers search and retrieval for proposals, transcripts, members, votes, and sessions, which are the main entities. Minor gaps include no direct get_member by ID and no committee data, but agents can work around these with search_members and get_votes.
Maintenance
Related MCP Connectors
MCP server for Brazilian Federal Senate open data (legislative, administrative, e-Cidadania).
An MCP server that provides congressional transcripts
MCP server unifying ERPs, CRMs, APIs and knowledge base for Claude, ChatGPT and Gemini.
- UnifAPIOAuthcom.unifapi
Hosted MCP server for live public-data APIs and Skills for AI agents.
Related MCP Servers
AlicenseAqualityDmaintenanceMCP server for Portuguese Parliament open data, enabling AI agents to access legislative initiatives, deputies, plenary votes, petitions, and parliamentary committees.127 npmMIT- AlicenseAqualityAmaintenanceAn MCP server that connects AI models to the Lobbywatch.ch database, providing access to Swiss parliamentarians' conflicts of interest, lobby groups, access badges, and transparency scores.825 PyPIMIT
- AlicenseAqualityAmaintenanceMCP server connecting AI models to Swiss Federal Food Safety and Veterinary Office open data, enabling queries about food recalls, animal disease surveillance, food control results, and more.11MIT
- AlicenseBqualityAmaintenanceAn MCP server providing AI-powered access to Open Data from the City of Zurich, enabling queries to 900+ datasets, real-time environmental and mobility data, geodata, parliamentary proceedings, and more.268MIT