Bundestag MCP Server
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., "@Bundestag MCP Serversearch for recent drucksachen on energy reform"
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.
Bundestag MCP Server
A production-ready Model Context Protocol (MCP) server that provides access to the German Bundestag's parliamentary documentation system (DIP API).
Public Instance
A public instance is available at:
https://bundestagapi.moritz-waechter.de/mcpYou can use this directly in your MCP client configuration without running your own server.
Related MCP server: mcp-bundestag-de
Table of Contents
Features
Core Capabilities
Search Drucksachen - Find bills, motions, inquiries, and other printed documents
Search Plenarprotokolle - Find plenary session transcripts
Search Vorgaenge - Track legislative proceedings through parliament
Search Personen - Find MPs and their information
Search Aktivitaeten - Find parliamentary activities (speeches, questions)
Full Text Retrieval - Get complete document texts
Semantic Search - AI-powered search using Qdrant + Mistral embeddings
Speech Search - Find specific statements in debates with hybrid vector/keyword search
Document Section Search - Search within document sections (articles, questions, etc.)
NLP Analysis - Extract speeches, analyze tone, classify topics, and compare parties
Production-Ready
Graceful Shutdown - Clean session termination on SIGTERM/SIGINT
Retry with Backoff - Automatic retries with exponential backoff and jitter
Rate Limiting - Token bucket rate limiter to protect upstream API
Circuit Breaker - Fast-fail pattern to prevent cascading failures
Response Caching - Three-layer caching (API, entity, metadata)
Observability
Prometheus Metrics -
/metrics/prometheusendpoint for monitoringDeep Health Checks -
/health/deepverifies DIP API connectivityStructured Logging - JSON logs with categories and levels
MCP Protocol
33 Tools - Search, retrieval, semantic search, speech search, and NLP analysis
8 Prompts - Guided workflows for common research tasks
12 Resources - Static and dynamic resource templates
Dual Mode - Supports stateful (Claude, Cursor) and stateless (ChatGPT) clients
Quick Start
Prerequisites
Node.js 18+
DIP API Key (a public test key is provided)
Installation
git clone https://github.com/Movm/bundestag-mcp.git
cd bundestag-mcp
npm installConfiguration
Create a .env file (or copy .env.example):
# Public test key valid until 05/2026
DIP_API_KEY=OSOegLs.PR2lwJ1dwCeje9vTj7FPOt3hvpYKtwKkhw
# Optional
PORT=3000
PUBLIC_URL=
LOG_LEVEL=INFONote: For production, request your own API key from:
parlamentsdokumentation@bundestag.de
Run
# Production
npm start
# Development (auto-reload)
npm run devThe server will start at http://localhost:3000.
MCP Tools
Document Tools
Tool | Description |
| Search printed documents (Gesetzentwürfe, Anträge, Anfragen) |
| Get specific document by ID (optionally with full text) |
| Full-text search within document content |
Protocol Tools
Tool | Description |
| Search plenary session transcripts |
| Get specific protocol by ID (optionally with full text) |
| Full-text search within transcript content |
Proceeding Tools
Tool | Description |
| Search parliamentary proceedings |
| Get specific proceeding by ID |
| Search proceeding positions/steps (track bill progress) |
Person & Activity Tools
Tool | Description |
| Search MPs and other persons |
| Get person details by ID |
| Search parliamentary activities |
| Get specific activity by ID |
Semantic Search Tools
Tool | Description |
| AI-powered semantic search across all documents |
| Show semantic search system status |
| Manually trigger document indexing |
Speech Search Tools
Tool | Description |
| Semantic/hybrid search through parliamentary speeches |
| Trigger protocol chunking and indexing |
| Force full re-indexing of all protocols |
| Show protocol search system status |
Document Section Search Tools
Tool | Description |
| Semantic search through document sections |
| Trigger document chunk indexing |
| Show document chunk search status |
NLP Analysis Tools
These tools use a Python FastAPI service with spaCy's German language model for natural language processing.
Tool | Description |
| Parse protocol text into individual speeches with speaker, party, and type |
| Analyze German text for word frequencies (nouns, adjectives, verbs) |
| Communication style analysis (aggression, collaboration, solution-focus) |
| Classify text by political topics (migration, climate, economy, etc.) |
| Check if the NLP analysis service is available |
| Generate comprehensive profile for a speaker based on their speeches |
| Compare political parties based on their parliamentary speeches |
Utility Tools
Tool | Description |
| Check document/protocol size BEFORE fetching to manage context window |
| Show cache statistics |
| Generate MCP client configurations |
Common Parameters
Parameter | Description |
| Full-text search in title |
| Electoral period (e.g., 20 for current 2021-2025) |
| Date range filter (YYYY-MM-DD) |
| Results per page (1-100, default 10) |
| Pagination cursor from previous response |
| Fetch full document text |
| Whether to use cached results (default: true) |
MCP Prompts
Guided workflows for common parliamentary research tasks:
Prompt | Description |
| Guided search for bills and legislation with semantic search and fallback strategies |
| Track a parliamentary proceeding with legislative glossary and timeline |
| Comprehensive MP report with rhetorical analysis via |
| Analyze plenary debate with party comparison via |
| Compare party rhetoric on a topic using cross-party analysis |
| Find specific quotes/statements from politicians with fallback strategies |
| Analyze how topic discussion evolved over time (across Wahlperioden/years) |
| Comprehensive rhetorical and policy analysis of a politician |
MCP Resources
Static Resources
URI | Description |
| AI usage instructions with tool selection guide and context management |
| Server capabilities and tool listing |
| Electoral periods (Wahlperioden) |
| Document types (Gesetzentwurf, Antrag, etc.) |
| Parliamentary factions with official names, aliases, colors, and positions |
Resource Templates
URI Pattern | Description |
| Fetch document by ID |
| Fetch document full text |
| Fetch protocol by ID |
| Fetch protocol full text |
| Fetch proceeding by ID |
| Fetch person by ID |
| Fetch activity by ID |
Client Configuration
Tip: Use the public instance
https://bundestagapi.moritz-waechter.de/mcpor run your own withhttp://localhost:3000/mcp
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"bundestag": {
"url": "https://bundestagapi.moritz-waechter.de/mcp"
}
}
}Cursor
Add to .cursor/mcp.json:
{
"mcpServers": {
"bundestag": {
"url": "https://bundestagapi.moritz-waechter.de/mcp"
}
}
}VS Code (GitHub Copilot)
Add to settings:
{
"mcp.servers": {
"bundestag": {
"type": "http",
"url": "https://bundestagapi.moritz-waechter.de/mcp"
}
}
}ChatGPT
The server is fully compatible with ChatGPT as a connector. Use the public instance or deploy your own.
Enable developer mode in ChatGPT:
Go to Settings → Apps & Connectors → Advanced settings
Enable developer mode
Add the connector:
Go to Settings → Connectors → Create
Use URL:
https://bundestagapi.moritz-waechter.de/mcpName it "Bundestag" and provide a description
Use in chat:
Click the + button in a new chat
Select your connector from the More menu
Ask about German parliamentary documents!
API Endpoints
Endpoint | Description |
| MCP protocol endpoint |
| SSE stream for sessions |
| Close session |
| Basic health check |
| Deep health check (verifies DIP API) |
| JSON statistics |
| Prometheus format metrics |
| Auto-discovery |
| Client-specific config |
| Server information |
Docker
# Build
docker build -t bundestag-mcp .
# Run
docker run -p 3000:3000 \
-e DIP_API_KEY=your-api-key \
bundestag-mcpDocker Compose
version: '3.8'
services:
bundestag-mcp:
build: .
ports:
- "3000:3000"
environment:
- DIP_API_KEY=${DIP_API_KEY}
- LOG_LEVEL=INFO
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3Development
Running Tests
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverageProject Structure
src/
├── index.js # Express server, MCP setup, endpoints
├── config.js # Environment configuration
├── api/
│ └── bundestag.js # DIP API client with retry logic
├── jobs/
│ └── indexer.js # Background document/protocol indexer
├── services/
│ ├── analysisService.js # HTTP client for Python NLP service
│ ├── embeddingService.js # Mistral embeddings
│ ├── qdrantService.js # Vector database operations
│ ├── protokollParser.js # Protocol speech extraction
│ └── drucksacheParser.js # Document section parsing
├── tools/
│ ├── search.js # 15 search/entity tools (incl. estimate_size)
│ ├── analysis.js # 7 NLP analysis tools
│ ├── semanticSearch.js # 10 semantic search tools
│ └── clientConfig.js # Client configuration tool
├── prompts/
│ └── index.js # MCP Prompts
├── resources/
│ ├── info.js # Static resources
│ └── templates.js # Resource templates
└── utils/
├── cache.js # Three-layer caching
├── logger.js # Structured logging
├── retry.js # Exponential backoff
├── rateLimiter.js # Token bucket rate limiter
├── circuitBreaker.js # Circuit breaker pattern
├── metrics.js # Prometheus metrics
└── textNormalization.js # German text handlingArchitecture
Resilience Patterns
Request → Rate Limiter → Circuit Breaker → Retry Logic → DIP API
↓ ↓ ↓
(throttle) (fast-fail) (backoff)Rate Limiter: Token bucket algorithm prevents overwhelming the DIP API
Circuit Breaker: Opens after consecutive failures, fast-fails during outages
Retry Logic: Exponential backoff with jitter for transient failures
Caching Strategy
Layer | TTL | Max Entries | Use Case |
API Response | 5 min | 500 | Search results |
Entity | 15 min | 200 | Individual documents |
Metadata | 24 hr | 50 | Wahlperioden, document types |
Semantic Search
The server supports AI-powered semantic search using Qdrant vector database and Mistral embeddings. This enables finding conceptually related documents even when exact keywords don't match.
How It Works
Document Indexing: Background indexer fetches documents from DIP API and generates embeddings using Mistral AI
Vector Storage: Embeddings are stored in Qdrant with rich metadata for filtering
Semantic Query: User queries are embedded and matched against document vectors using cosine similarity
Three Search Collections
Collection | Description |
| Document-level search (Drucksachen, Vorgaenge, Aktivitaeten, Personen) |
| Speech-level search from Plenarprotokolle |
| Section-level search from Drucksachen (articles, questions, etc.) |
Features
Multilingual: Search in English, finds German documents (e.g., "renewable energy" → "Erneuerbare Energien")
Hybrid Search: Combines vector similarity with keyword boosting for improved precision
Rich Filtering: Filter by document type, entity type, Wahlperiode, Sachgebiet, initiative, faction, date range
Speech Search: Find specific statements by speaker, party, speech type, or government officials
Document Section Search: Find specific paragraphs, questions, or articles within documents
Incremental Indexing: Uses
f.aktualisiert.startfor efficient updates after initial indexing
Configuration
Add to your .env file:
# Semantic Search (Qdrant + Mistral)
QDRANT_ENABLED=true
QDRANT_URL=http://qdrant:6333
QDRANT_API_KEY=your-qdrant-api-key # Optional: API key for Qdrant authentication
MISTRAL_API_KEY=your-mistral-api-key
# Background Indexer
INDEXER_ENABLED=true
INDEXER_INTERVAL_MINUTES=15
INDEXER_WAHLPERIODEN=19,20Tip: Generate a secure API key with
openssl rand -hex 32
Docker Compose with Qdrant
services:
bundestag-mcp:
build: .
environment:
- QDRANT_ENABLED=true
- QDRANT_URL=http://qdrant:6333
- QDRANT_API_KEY=${QDRANT_API_KEY}
- MISTRAL_API_KEY=${MISTRAL_API_KEY}
- INDEXER_ENABLED=true
depends_on:
- qdrant
qdrant:
image: qdrant/qdrant:latest
ports:
- "6333:6333"
volumes:
- qdrant_data:/qdrant/storage
environment:
- QDRANT__SERVICE__API_KEY=${QDRANT_API_KEY}
volumes:
qdrant_data:Semantic Search Parameters
Parameter | Description |
| Natural language search query |
| Max results (1-50) |
| Filter: |
| Filter: |
| Electoral period (19, 20) |
| Subject area |
| Initiating faction (CDU/CSU, SPD, etc.) |
| Parliamentary group |
| Date range (YYYY-MM-DD) |
| Minimum similarity (0-1, default 0.3) |
Speech Search Parameters
Parameter | Description |
| Natural language search query |
| Max results (1-50) |
| Filter by speaker name (e.g., "Friedrich Merz") |
| Filter by party (e.g., "CDU/CSU", "SPD") |
| Filter by state for Bundesrat (e.g., "Bayern") |
| Filter by agenda item (e.g., "TOP 1") |
| Electoral period |
| Publisher: |
| Type: |
| Filter for government officials (ministers, state secretaries) |
| Category: |
|
|
| Boost factor for keyword matches in hybrid mode (0-2, default 0.5) |
| Keywords that must appear in the text |
| Keywords that must not appear in the text |
Document Section Search Parameters
Parameter | Description |
| Natural language search query |
| Max results (1-50) |
| Filter: |
| Section type: |
| Electoral period |
| Author/initiator (e.g., "Bundesregierung", "CDU/CSU") |
| Date range (YYYY-MM-DD) |
| Minimum similarity (0-1, default 0.3) |
NLP Analysis Service
The server includes optional NLP analysis capabilities powered by a Python FastAPI service using spaCy's German language model.
Features
Speech Extraction: Parse Plenarprotokolle into individual speeches with speaker, party, and type
Word Analysis: Extract and lemmatize nouns, adjectives, and verbs with frequency counts
Tone Analysis: 12 communication style metrics including aggression, collaboration, and solution-focus
Topic Classification: Detect focus on 13 policy areas (migration, climate, economy, etc.)
Speaker Profiles: Generate comprehensive profiles with statistics, vocabulary, and communication style
Party Comparison: Compare parties based on their speeches with tone rankings and topic focus
Tone Metrics
Metric | Description |
| Positive vs critical adjective ratio (0-100) |
| Aggressive language intensity (0-100) |
| "Othering" language usage (0-100) |
| Solution vs problem-oriented verbs (0-100) |
| Collaborative vs confrontational (0-100) |
| Demanding language (fordern, müssen) (0-100) |
| Obligation vs possibility modals (0-100) |
| Forward vs backward-looking (0-100) |
Topic Categories
Migration, Climate (Klima), Economy (Wirtschaft), Social Policy (Soziales), Security (Sicherheit), Health (Gesundheit), Europe (Europa), Digital, Education (Bildung), Finance (Finanzen), Justice (Justiz), Labor (Arbeit), Mobility (Mobilität)
Configuration
The analysis service runs as a separate Python container. Add to your .env:
ANALYSIS_SERVICE_URL=http://analysis:8000Docker Compose with Analysis
services:
bundestag-mcp:
build: .
environment:
- ANALYSIS_SERVICE_URL=http://analysis:8000
depends_on:
- analysis
analysis:
image: ghcr.io/movm/bundestag-analysis:latest
expose:
- "8000"Note: The analysis service requires ~1GB RAM for the spaCy model and takes ~30s to start.
DIP API
This server uses the official Bundestag DIP API:
Documentation: https://dip.bundestag.de/
API Docs: https://dip.bundestag.api.bund.dev/
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Fork the repository
Create your feature branch (
git checkout -b feature/amazing-feature)Run tests (
npm test)Commit your changes (
git commit -m 'feat: Add amazing feature')Push to the branch (
git push origin feature/amazing-feature)Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
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/Movm/bundestag-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server