API Usage Guide
July 10, 2026 ยท View on GitHub
European Parliament MCP Server - API Usage Guide
Comprehensive guide to using all 63 MCP tools
Real-world examples, best practices, and query patterns
๐ Table of Contents
- Overview
- Quick Reference
- Tool Documentation
- OSINT Intelligence Tools
- assess_mep_influence
- analyze_coalition_dynamics
- detect_voting_anomalies
- compare_political_groups
- analyze_legislative_effectiveness
- monitor_legislative_pipeline
- analyze_committee_activity
- track_mep_attendance
- analyze_country_delegation
- generate_political_landscape
- network_analysis
- sentiment_tracker
- early_warning_system
- comparative_intelligence
- correlate_intelligence
- EP API v2 Endpoint Tools
- get_current_meps
- get_incoming_meps
- get_outgoing_meps
- get_homonym_meps
- get_speeches
- get_procedures
- get_procedure_events
- get_adopted_texts
- get_events
- get_meeting_activities
- get_meeting_decisions
- get_meeting_foreseen_activities
- get_meeting_plenary_session_documents
- get_meeting_plenary_session_document_items
- get_mep_declarations
- get_plenary_documents
- get_committee_documents
- get_plenary_session_documents
- get_plenary_session_document_items
- get_controlled_vocabularies
- get_external_documents
- get_procedure_event_by_id
- EP API v2 Feed Endpoint Tools
- get_meps_feed
- get_events_feed
- get_procedures_feed
- get_adopted_texts_feed
- get_mep_declarations_feed
- get_documents_feed
- get_plenary_documents_feed
- get_committee_documents_feed
- get_plenary_session_documents_feed
- get_external_documents_feed
- get_parliamentary_questions_feed
- get_corporate_bodies_feed
- get_controlled_vocabularies_feed
- MCP Prompts
- MCP Resources
- Common Use Cases
- Best Practices
- Error Handling
๐ฏ Overview
The European Parliament MCP Server provides 63 specialized tools for accessing parliamentary data through the Model Context Protocol โ organized into 9 core tools (including the DOCEO-backed near-real-time get_latest_votes), 3 advanced tools, 15 OSINT intelligence tools, 1 statistics tool, 21 EP API v2 endpoint tools, 1 procedure event detail tool, and 13 EP API v2 feed tools. Each tool is designed for specific data queries with input validation, caching, and rate limiting.
Political Intelligence Coverage
graph TB
subgraph OSINT["๐ต๏ธ OSINT Intelligence Layer (15 tools)"]
direction TB
subgraph MEP_INTEL["MEP Intelligence"]
AI[assess_mep_influence]
CI[comparative_intelligence]
NA[network_analysis]
end
subgraph COALITION["Coalition & Group Analysis"]
ACD[analyze_coalition_dynamics]
CPG[compare_political_groups]
DVA[detect_voting_anomalies]
ST[sentiment_tracker]
end
subgraph STRATEGIC["Strategic Intelligence"]
EWS[early_warning_system]
GPL[generate_political_landscape]
COR[correlate_intelligence]
end
subgraph LEGISLATIVE["Legislative Intelligence"]
ALE[analyze_legislative_effectiveness]
MLP[monitor_legislative_pipeline]
ACA[analyze_committee_activity]
end
subgraph NATIONAL["National & Attendance"]
ACD2[analyze_country_delegation]
TMA[track_mep_attendance]
end
end
subgraph ANALYSIS["๐ Advanced Analysis (4 tools)"]
AVP[analyze_voting_patterns]
TL[track_legislation]
GR[generate_report]
GAGS[get_all_generated_stats]
end
subgraph CORE["๐ฆ Core Data Access (22 tools)"]
direction TB
MEP_TOOLS["๐ค MEP Tools (7)"]
PLENARY["๐๏ธ Plenary & Meeting (9)"]
DOC["๐ Document Tools (7)"]
LEG["โ๏ธ Legislative (4)"]
COMM["๐ข Committee (2)"]
DIAG["๐ง Diagnostics (1)"]
end
subgraph FEEDS["๐ก Real-Time Feeds (13 tools)"]
FEED_ALL["13 change monitoring feeds"]
end
OSINT --> ANALYSIS
ANALYSIS --> CORE
CORE --> FEEDS
style OSINT fill:#d32f2f,stroke:#b71c1c,color:#fff,stroke-width:2px
style ANALYSIS fill:#1565c0,stroke:#0d47a1,color:#fff,stroke-width:2px
style CORE fill:#2e7d32,stroke:#1b5e20,color:#fff,stroke-width:2px
style FEEDS fill:#ff8f00,stroke:#e65100,color:#000,stroke-width:2px
style MEP_INTEL fill:#e53935,stroke:#c62828,color:#fff,stroke-width:2px
style COALITION fill:#e53935,stroke:#c62828,color:#fff,stroke-width:2px
style STRATEGIC fill:#e53935,stroke:#c62828,color:#fff,stroke-width:2px
style LEGISLATIVE fill:#e53935,stroke:#c62828,color:#fff,stroke-width:2px
style NATIONAL fill:#e53935,stroke:#c62828,color:#fff,stroke-width:2px
Tool Category Overview
graph LR
subgraph INPUT["๐ Intelligence Questions"]
Q1["Who are the key players?"]
Q2["What coalitions are forming?"]
Q3["Where are the risks?"]
Q4["How effective is legislation?"]
Q5["What changed recently?"]
end
subgraph TOOLS["๐ ๏ธ MCP Tool Categories"]
T1["MEP Profiling\n7 core + 4 OSINT"]
T2["Coalition Analysis\n4 OSINT tools"]
T3["Risk Detection\n3 OSINT tools"]
T4["Legislative Tracking\n5 analysis tools"]
T5["Change Monitoring\n13 feed tools"]
end
subgraph OUTPUT["๐ Intelligence Products"]
O1["Influence Scores\nNetwork Maps"]
O2["Cohesion Metrics\nAlliance Detection"]
O3["Anomaly Alerts\nEarly Warnings"]
O4["Pipeline Status\nEffectiveness Scores"]
O5["Real-Time Updates\nTrend Data"]
end
Q1 --> T1 --> O1
Q2 --> T2 --> O2
Q3 --> T3 --> O3
Q4 --> T4 --> O4
Q5 --> T5 --> O5
style INPUT fill:#4a90e2,stroke:#2171c7,color:#fff,stroke-width:2px
style TOOLS fill:#9c27b0,stroke:#7b1fa2,color:#fff,stroke-width:2px
style OUTPUT fill:#2e7d32,stroke:#1b5e20,color:#fff,stroke-width:2px
Key Features
- Type Safety: All inputs validated with Zod schemas
- Performance: <200ms cached response times
- Rate Limiting: 100 requests per 15 minutes per IP
- GDPR Compliance: Privacy-first data handling
- MCP Standard: Full compliance with MCP specification
Authentication
Currently, the server does not require authentication for tool access. Future versions may introduce OAuth 2.0 or API key authentication.
๐ Quick Reference
๐ค MEP Tools
| Tool | Purpose | Key Parameters | Response Type |
|---|---|---|---|
get_meps | List MEPs with filters | country, group, committee | Paginated list |
get_mep_details | MEP details | id | Single object |
get_current_meps | Currently active MEPs | limit, offset | Paginated list |
get_incoming_meps | Newly arriving MEPs | limit, offset | Paginated list |
get_outgoing_meps | Departing MEPs | limit, offset | Paginated list |
get_homonym_meps | MEPs with identical names | limit, offset | Paginated list |
get_mep_declarations | MEP financial declarations | docId, year | Paginated list |
๐๏ธ Plenary & Meeting Tools
| Tool | Purpose | Key Parameters | Response Type | Notes |
|---|---|---|---|---|
get_plenary_sessions | List plenary sessions | dateFrom, dateTo, eventId, year, location | Paginated list | โ
Fast with year filter |
get_voting_records | Aggregate voting data | sessionId, topic, dateFrom | Paginated list | โ ๏ธ Roll-call data delayed by weeks |
get_latest_votes | Near-real-time DOCEO vote data | date, weekStart, term, includeIndividualVotes | Vote records | โ Hours fresh โ RCV preferred; falls back to VOT |
get_speeches | Plenary speeches | speechId, year, dateFrom, dateTo | Paginated list | |
get_events | EP events | eventId, limit, offset | Paginated list | โ ๏ธ No date filtering |
get_meeting_activities | Meeting activities | sittingId (required) | Paginated list | โ
Works with session IDs like MTG-PL-2025-01-20 |
get_meeting_decisions | Meeting decisions | sittingId (required) | Paginated list | โ Works with session IDs |
get_meeting_foreseen_activities | Planned agenda items | sittingId (required) | Paginated list | โ Works with session IDs |
get_meeting_plenary_session_documents | Meeting session documents | sittingId (required) | Paginated list | โ ๏ธ Returns 404 for many sittingIds |
get_meeting_plenary_session_document_items | Meeting session doc items | sittingId (required) | Paginated list | โ ๏ธ Returns 404 for many sittingIds |
๐ข Committee Tools
| Tool | Purpose | Key Parameters | Response Type |
|---|---|---|---|
get_committee_info | Committee data | id, abbreviation, showCurrent | Single object |
get_committee_documents | Committee documents | docId, year | Paginated list |
๐ Document Tools
| Tool | Purpose | Key Parameters | Response Type | Notes |
|---|---|---|---|---|
search_documents | Find documents | keyword, documentType, dateFrom, dateTo | Paginated list | โ ๏ธ Always use date filters โ unfiltered searches time out |
get_adopted_texts | Adopted texts | docId, year | Paginated list | โ
Fast with year filter |
get_plenary_documents | Plenary documents | docId, year | Paginated list | โ
Fast with year filter |
get_plenary_session_documents | Session documents | docId | Paginated list | |
get_plenary_session_document_items | Session document items | limit, offset | Paginated list | โ ๏ธ EP API returns 404 โ endpoint may require specific parameters |
get_external_documents | External documents | docId, year | Paginated list | โ
Fast with year filter |
get_parliamentary_questions | Q&A data | docId, type, author, topic, status, dateFrom | Paginated list |
โ๏ธ Legislative Procedure Tools
| Tool | Purpose | Key Parameters | Response Type | Notes |
|---|---|---|---|---|
get_procedures | Legislative procedures | processId, year | Paginated list | โ ๏ธ Use year filter โ unfiltered queries may time out |
get_procedure_events | Procedure timeline events | processId (required) | Paginated list | Use short processId (e.g., 2025-0012), not full URI |
get_procedure_event_by_id | Single procedure event | processId, eventId (both required) | Single object | Use short IDs for both parameters |
get_controlled_vocabularies | Classification terms | vocId | Paginated list | โ
Fast; use short vocId (e.g., ep-document-types) |
๐ Advanced Analysis Tools
| Tool | Purpose | Key Parameters | Response Type |
|---|---|---|---|
analyze_voting_patterns | Voting analysis | mepId, dateFrom | Analysis object |
track_legislation | Track procedure | procedureId | Procedure object |
generate_report | Create reports | reportType, subjectId | Report object |
get_all_generated_stats | Precomputed EP stats (2004-2026) + 30 OSINT metrics | yearFrom, yearTo, category | Statistics object |
๐ต๏ธ OSINT Intelligence Tools
| Tool | Purpose | Key Parameters | Response Type |
|---|---|---|---|
assess_mep_influence | MEP influence scoring | mepId (required), includeDetails | Influence scorecard |
analyze_coalition_dynamics | Coalition cohesion analysis | groupIds, dateFrom, minimumCohesion | Coalition metrics |
detect_voting_anomalies | Anomaly detection | mepId, groupId, sensitivityThreshold | Anomaly report |
compare_political_groups | Cross-group comparison | groupIds (required), dimensions | Comparison matrix |
analyze_legislative_effectiveness | Legislative scoring | subjectType (required), subjectId (required) | Effectiveness score |
monitor_legislative_pipeline | Pipeline monitoring | committee, status, limit | Pipeline status |
analyze_committee_activity | Committee workload & engagement | committeeId (required) | Activity report |
track_mep_attendance | MEP attendance patterns | mepId, country, groupId, limit | Attendance report |
analyze_country_delegation | Country delegation analysis | country (required) | Delegation analysis |
generate_political_landscape | Parliament-wide landscape | dateFrom, dateTo | Landscape overview |
network_analysis | MEP relationship network mapping | mepId, analysisType, depth | Network metrics |
sentiment_tracker | Political group positioning scores | groupId, timeframe | Sentiment report |
early_warning_system | Detect emerging political shifts | sensitivity, focusArea | Warning alerts |
comparative_intelligence | Cross-reference MEP activities | mepIds (required), dimensions | Comparison matrix |
correlate_intelligence | Cross-tool OSINT correlation | mepIds (required), groups, sensitivityLevel | Intelligence alerts |
๐ก Feed Tools
EP API v2 feed endpoints fall into two groups per the OpenAPI spec:
Configurable-window feeds (accept timeframe + startDate):
| Tool | Purpose | Key Parameters | Response Type | Tested Response Time |
|---|---|---|---|---|
get_meps_feed | Recently updated MEPs | timeframe, startDate | Feed list | ~9 s |
get_events_feed | Recently updated events | timeframe, startDate, activityType | Feed list | 30โ120 s โ ๏ธ |
get_procedures_feed | Recently updated procedures | timeframe, startDate, processType | Feed list | 30โ120 s โ ๏ธ |
get_adopted_texts_feed | Recently updated adopted texts | timeframe, startDate, workType | Feed list | ~1 s โ |
get_mep_declarations_feed | Recently updated MEP declarations | timeframe, startDate, workType | Feed list | ~1 s โ |
get_external_documents_feed | Recently updated external documents | timeframe, startDate, workType | Feed list | ~1 s โ |
Fixed-window feeds (no parameters โ server-defined default window, typically one month):
| Tool | Purpose | Key Parameters | Response Type | Tested Response Time |
|---|---|---|---|---|
get_documents_feed | Recently updated documents | (none) | Feed list | 60โ120+ s โ ๏ธ |
get_plenary_documents_feed | Recently updated plenary documents | (none) | Feed list | 30โ120+ s โ ๏ธ |
get_committee_documents_feed | Recently updated committee documents | (none) | Feed list | 30โ120+ s โ ๏ธ |
get_plenary_session_documents_feed | Recently updated plenary session docs | (none) | Feed list | 20โ120+ s โ ๏ธ |
get_parliamentary_questions_feed | Recently updated questions | (none) | Feed list | 30โ120+ s โ ๏ธ |
get_corporate_bodies_feed | Recently updated corporate bodies | (none) | Feed list | 60โ180+ s โ ๏ธ |
get_controlled_vocabularies_feed | Recently updated vocabularies | (none) | Feed list | Returns HTTP 204 (no content) when no updates exist |
โ ๏ธ EP API response times are highly variable. During peak load, even normally fast feeds can exceed the default 60s timeout. Set
--timeout 180000for reliable feed access.Known EP API feed behaviors:
controlled-vocabularies/feedโ returns HTTP 204 No Content when no vocabulary updates exist in the default window (common since vocabularies change infrequently). The server handles this gracefully and returns an empty data array.corporate-bodies/feedโ consistently the slowest feed endpoint (60โ180 s). Increase timeout if using this endpoint.plenary-session-documents/feedโ may return an error-in-body response (HTTP 200 witherrorfield) when the EP API's internal enrichment step fails. Handled gracefully by the server.- All fixed-window feeds accept no parameters โ passing unknown parameters such as
timeframeorstartDatewill fail input validation rather than being ignored.
๐ Tool Documentation
Tool: get_meps
Description: Retrieve Members of the European Parliament with optional filters for country, political group, committee membership, and active status.
โ ๏ธ EP API Note: The
get_mepstool uses the EP API/mepsendpoint which supports server-side filtering but does not returncountryorpoliticalGroupin responses. Results will showcountry: "Unknown"andpoliticalGroup: "Unknown". For country and political group data, useget_current_mepsinstead. All OSINT intelligence tools automatically useget_current_mepsfor accurate MEP metadata.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| country | string | No | - | ISO 3166-1 alpha-2 country code (e.g., "SE", "FR", "DE") |
| group | string | No | - | Political group identifier (e.g., "EPP", "S&D", "Greens/EFA") |
| committee | string | No | - | Committee identifier (e.g., "ENVI", "AGRI") |
| active | boolean | No | true | Filter by active status |
| limit | number | No | 50 | Maximum results (1-100) |
| offset | number | No | 0 | Pagination offset |
Response Format
{
"content": [{
"type": "text",
"text": "{
\"data\": [
{
\"id\": \"MEP-124810\",
\"name\": \"Anna Lindberg\",
\"country\": \"SE\",
\"politicalGroup\": \"S&D\",
\"committees\": [\"ENVI\", \"AGRI\"],
\"email\": \"anna.lindberg@europarl.europa.eu\"
}
],
\"total\": 1,
\"limit\": 50,
\"offset\": 0
}"
}]
}
Example Usage
Claude Desktop - Natural Language:
Get me a list of Swedish MEPs in the S&D political group
VS Code/MCP Client - TypeScript:
const result = await client.callTool('get_meps', {
country: 'SE',
group: 'S&D',
limit: 20
});
const response = JSON.parse(result.content[0].text);
console.log(`Found ${response.total} Swedish S&D MEPs`);
Python MCP Client:
result = await client.call_tool('get_meps', {
'country': 'SE',
'group': 'S&D',
'limit': 20
})
data = json.loads(result['content'][0]['text'])
print(f"Found {data['total']} Swedish S&D MEPs")
Common Errors
| Error | Cause | Solution |
|---|---|---|
ValidationError: country | Invalid country code format | Use 2-letter ISO code (e.g., "SE" not "Sweden") |
RateLimitError | Too many requests | Wait 15 minutes or implement request throttling |
APIError: 500 | European Parliament API down | Check EP API status, implement retry logic |
Use Cases
- Find MEPs by Country: Filter by country code to get national delegation
- Political Group Analysis: List all members of a specific political group
- Committee Membership: Find MEPs serving on specific committees
- Pagination: Use
limitandoffsetfor large result sets
Tool: get_mep_details
Description: Retrieve the complete profile returned by EP API v2
GET /meps/{mep-id}, including biographical fields and the full membership
history used to identify mandates, political groups, committees, and leadership
roles.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| id | string | Yes | - | Numeric ID, person/{id}, or MEP-{id} (for example, 124936) |
Response Format
{
"content": [{
"type": "text",
"text": "{
\"id\": \"person/124936\",
\"type\": \"Person\",
\"identifier\": \"124936\",
\"label\": \"Maria ARENA\",
\"notation_codictPersonId\": \"124936\",
\"name\": \"Maria ARENA\",
\"country\": \"BEL\",
\"politicalGroup\": \"org/5154\",
\"committees\": [\"org/6358\"],
\"active\": false,
\"termStart\": \"2019-07-02\",
\"termEnd\": \"2024-07-15\",
\"bday\": \"1966-12-17\",
\"hasGender\": \"http://publications.europa.eu/resource/authority/human-sex/FEMALE\",
\"citizenship\": \"http://publications.europa.eu/resource/authority/country/BEL\",
\"placeOfBirth\": \"Mons\",
\"familyName\": \"Arena\",
\"givenName\": \"Maria\",
\"img\": \"https://www.europarl.europa.eu/mepphoto/124936.jpg\",
\"roles\": [\"def/ep-roles/MEMBER\", \"def/ep-roles/MEMBER_PARLIAMENT\"],
\"hasMembership\": [{
\"id\": \"membership/124936-f-167664\",
\"type\": \"Membership\",
\"identifier\": \"124936-f-167664\",
\"notation_codictFunctionId\": \"167664\",
\"memberDuring\": {
\"id\": \"time-period/20220518-20240715\",
\"type\": \"PeriodOfTime\",
\"startDate\": \"2022-05-18\",
\"endDate\": \"2024-07-15\"
},
\"organization\": \"org/6358\",
\"role\": \"def/ep-roles/MEMBER\",
\"membershipClassification\": \"def/ep-entities/COMMITTEE_PARLIAMENTARY_STANDING\",
\"contactPoint\": []
}]
}"
}]
}
The tool preserves the EP fields type, identifier, label,
notation_codictPersonId, bday, hasGender, hasHonorificPrefix,
hasMembership, citizenship, placeOfBirth, familyName, givenName,
img, sortLabel, upperFamilyName, and upperGivenName. Membership entries
preserve function or mandate identifiers, represented countries, periods,
organizations, roles, classifications, and contact points.
The compatibility fields name, country, politicalGroup, committees,
active, termStart, termEnd, biography, and roles are derived from the
same source record. committees contains committee organization IDs only;
inspect hasMembership[].membershipClassification and
hasMembership[].role for the authoritative assignment and leadership data.
The EP endpoint does not provide voting statistics, so this tool does not
fabricate them.
Example Usage
Claude Desktop:
Get detailed information about MEP with ID MEP-124810
TypeScript:
const result = await client.callTool('get_mep_details', {
id: '124936'
});
const mep = JSON.parse(result.content[0].text);
console.log(`${mep.name} from ${mep.country}`);
console.log(`Membership records: ${mep.hasMembership.length}`);
Common Errors
| Error | Cause | Solution |
|---|---|---|
ValidationError: id required | Missing ID parameter | Provide MEP ID (get from get_meps) |
NotFoundError | Invalid MEP ID | Verify ID exists in get_meps results |
ValidationError: id format | Empty or invalid ID format | Use non-empty string ID |
Use Cases
- MEP Profile: Get complete EP biographical information for profile pages
- Mandate History: Inspect parliamentary terms and represented countries
- Committee Work: Resolve assignments from membership classifications
- Leadership Analysis: Identify chair and vice-chair roles from membership records
Tool: get_plenary_sessions
Description: Retrieve European Parliament plenary sessions with optional date range, year, or location filtering. Supports single meeting lookup by eventId.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| eventId | string | No | - | Meeting event ID for single meeting lookup |
| year | number | No | - | Filter by calendar year (1900-2100, recommended for annual counts) |
| dateFrom | string | No | - | Start date (YYYY-MM-DD format) |
| dateTo | string | No | - | End date (YYYY-MM-DD format) |
| location | string | No | - | Session location (e.g., "Strasbourg", "Brussels") |
| limit | number | No | 50 | Maximum results (1-100) |
| offset | number | No | 0 | Pagination offset |
Note:
dateFrommust be โคdateTowhen both are provided.
Response Format
{
"content": [{
"type": "text",
"text": "{
\"data\": [
{
\"id\": \"PLENARY-2024-05\",
\"date\": \"2024-05-15\",
\"location\": \"Strasbourg\",
\"agenda\": \"Climate change debate, budget vote\",
\"documents\": [\"DOC-2024-001\", \"DOC-2024-002\"]
}
],
\"total\": 12,
\"limit\": 50,
\"offset\": 0
}"
}]
}
Example Usage
Claude Desktop:
Show me plenary sessions from January to March 2024
TypeScript:
const result = await client.callTool('get_plenary_sessions', {
dateFrom: '2024-01-01',
dateTo: '2024-03-31',
limit: 20
});
const sessions = JSON.parse(result.content[0].text);
console.log(`Found ${sessions.data.length} sessions`);
Common Errors
| Error | Cause | Solution |
|---|---|---|
ValidationError: dateFrom | Invalid date format | Use YYYY-MM-DD format |
ValidationError: dateTo before dateFrom | Date range invalid | Ensure dateTo >= dateFrom |
Use Cases
- Session Calendar: List upcoming plenary sessions
- Historical Analysis: Query past sessions by date range
- Document Tracking: Access session documents and agendas
Tool: get_voting_records
Description: Retrieve aggregate voting records from European Parliament plenary sessions. Filter by session, topic, or date range. Returns aggregate vote counts (for/against/abstain) and final result.
โน๏ธ Data delay: The EP publishes roll-call voting data with a delay of several weeks. Queries for the most recent 1โ2 months may return empty results โ this is expected EP API behavior, not an error.
โน๏ธ EP API limitation: This endpoint returns only aggregate vote tallies โ the EP API does not expose individual MEP voting positions. Filter by
sessionId,topic, or date range to scope results.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| sessionId | string | No | - | Filter by plenary session |
| topic | string | No | - | Filter by topic/keyword |
| dateFrom | string | No | - | Start date (YYYY-MM-DD) |
| dateTo | string | No | - | End date (YYYY-MM-DD) |
| limit | number | No | 50 | Maximum results (1-100) |
| offset | number | No | 0 | Pagination offset |
Response Format
{
"content": [{
"type": "text",
"text": "{
\"data\": [
{
\"voteId\": \"VOTE-2024-001\",
\"sessionId\": \"PLENARY-2024-05\",
\"date\": \"2024-05-15\",
\"subject\": \"Climate Action Directive\",
\"result\": \"ADOPTED\",
\"votesFor\": 450,
\"votesAgainst\": 120,
\"abstentions\": 30
}
],
\"total\": 1250,
\"limit\": 50,
\"offset\": 0
}"
}]
}
Example Usage
Claude Desktop:
Show voting records on climate topics from 2024
TypeScript:
const result = await client.callTool('get_voting_records', {
topic: 'climate',
dateFrom: '2024-01-01',
limit: 100
});
Use Cases
- Topic Analysis: Find all votes on specific topics
- Session Votes: Get all votes from a plenary session
- Trend Analysis: Track voting patterns over time on policy areas
Tool: get_latest_votes
Description: Retrieve the latest plenary votes from European Parliament DOCEO XML documents. Provides near-real-time access to vote data โ hours fresh โ compared to the EP Open Data API which has a publication delay of several weeks for roll-call voting data.
๐ก Data Freshness: DOCEO data is typically available within hours of plenary votes. RCV (Roll-Call Vote) data includes individual MEP positions by political group. VOT (Vote Results) provides aggregate tallies and is used as fallback when RCV is unavailable.
โ ๏ธ
get_all_generated_statsenrichment: WhenincludeRankings=true,get_all_generated_statsalso performs a bounded (2s timeout) DOCEO enrichment for recent vote activity. This enrichment may be unavailable if DOCEO is slow or down; the response will indicate missingrecentVoteActivityin that case.โ ๏ธ
analyze_coalition_dynamicsenrichment: Coalition cohesion scores are enriched with DOCEO RCV group-breakdown data (bounded 3s timeout, cached 5 minutes). If DOCEO is unavailable, cohesion falls back tonullanddataFreshnesswill indicate no DOCEO data was used.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| date | string | No | - | Specific date (YYYY-MM-DD, real calendar date). Mutually exclusive with weekStart. |
| weekStart | string | No | - | Monday date of a specific plenary week (YYYY-MM-DD). Mutually exclusive with date. Fetches MonโThu of that week. |
| term | number | No | 10 | Parliamentary term (1โ15; default 10 = 2024โ2029 term) |
| includeIndividualVotes | boolean | No | true | Include individual MEP vote positions from RCV data |
| limit | number | No | 50 | Maximum vote records to return (1โ100) |
| offset | number | No | 0 | Pagination offset (โฅ 0) |
Mutual exclusivity: Passing both
dateandweekStartsimultaneously is a validation error. Calendar date enforcement: BothdateandweekStartmust be real calendar dates (e.g.,2026-13-40is rejected).weekStartmust be a Monday.
Response Format
{
"content": [{
"type": "text",
"text": "{
\"data\": [
{
\"id\": \"RCV-10-2026-04-28-001\",
\"date\": \"2026-04-28\",
\"term\": 10,
\"subject\": \"Regulation on digital markets: amendment 47\",
\"reference\": \"A10-0012/2026\",
\"votesFor\": 412,
\"votesAgainst\": 198,
\"abstentions\": 35,
\"result\": \"ADOPTED\",
\"dataSource\": \"RCV\",
\"sittingDate\": \"2026-04-28\",
\"voteType\": \"single\",
\"officialCounts\": { \"for\": 412, \"against\": 198, \"abstentions\": 35 },
\"groupBreakdown\": {
\"EPP\": { \"for\": 175, \"against\": 2, \"abstain\": 3 },
\"S&D\": { \"for\": 120, \"against\": 10, \"abstain\": 5 }
},
\"mepVotes\": { \"12345\": \"FOR\", \"23456\": \"AGAINST\" },
\"sourceUrl\": \"https://www.europarl.europa.eu/doceo/document/PV-10-2026-04-28-RCV_EN.xml\"
}
],
\"total\": 48,
\"datesAvailable\": [\"2026-04-28\"],
\"datesUnavailable\": [\"2026-04-29\", \"2026-04-30\", \"2026-05-01\"],
\"source\": {
\"type\": \"DOCEO_XML\",
\"term\": 10,
\"urls\": [\"https://www.europarl.europa.eu/doceo/document/PV-10-2026-04-28-RCV_EN.xml\"]
},
\"limit\": 50,
\"offset\": 0,
\"hasMore\": false
}"
}]
}
Example Usage
Claude Desktop - Natural Language:
What votes happened in the European Parliament this week?
VS Code/MCP Client - TypeScript:
// Get votes from the most recent plenary week (no individual MEP positions)
const result = await client.callTool('get_latest_votes', {
includeIndividualVotes: false
});
const response = JSON.parse(result.content[0].text);
console.log(`Fetched ${response.total} votes from dates: ${response.datesAvailable.join(', ')}`);
// Get votes for a specific date with individual MEP positions
const specific = await client.callTool('get_latest_votes', {
date: '2026-04-28',
includeIndividualVotes: true
});
// Get votes for a specific plenary week (MonโThu)
const weekly = await client.callTool('get_latest_votes', {
weekStart: '2026-04-27', // must be a Monday
limit: 20,
offset: 0
});
Python MCP Client:
result = await client.call_tool('get_latest_votes', {
'date': '2026-04-28',
'includeIndividualVotes': False
})
data = json.loads(result['content'][0]['text'])
adopted = [v for v in data['data'] if v['result'] == 'ADOPTED']
print(f"Adopted: {len(adopted)} of {data['total']}")
Common Errors
| Error | Cause | Solution |
|---|---|---|
Invalid parameters: date: date must be a valid calendar date | Date string matches YYYY-MM-DD pattern but is not a real date (e.g., 2026-13-40) | Use a real calendar date |
Invalid parameters: weekStart: weekStart must be a Monday | The weekStart date is valid but falls on a non-Monday | Use the Monday of the desired plenary week |
Invalid parameters: weekStart: date and weekStart are mutually exclusive | Both date and weekStart were provided | Provide only one, or omit both for the most recent plenary week |
Failed to retrieve latest votes from DOCEO | DOCEO upstream network error or document not yet published | The documents may not be published yet; retry later |
Use Cases
- Near-Real-Time Vote Monitoring: Get vote results within hours of plenary sessions
- Group Cohesion Analysis: Use
groupBreakdownto compare how political groups voted - MEP Position Tracking: With
includeIndividualVotes: true, trace each MEP's vote - Historical Week Lookup: Use
weekStart(must be a Monday) to fetch an entire plenary week - Coalition Intelligence: Feed vote data into
analyze_coalition_dynamicsfor enriched cohesion scores
Tool: search_documents
Description: Search European Parliament legislative documents with keyword and type filters.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| docId | string | No | - | Document ID for single document lookup (bypasses keyword search) |
| keyword | string | No | - | Search keyword or phrase (alphanumeric, spaces, hyphens, underscores) |
| documentType | string | No | - | Document type: REPORT, RESOLUTION, DECISION, DIRECTIVE, REGULATION, OPINION, AMENDMENT |
| dateFrom | string | No | - | Start date (YYYY-MM-DD) |
| dateTo | string | No | - | End date (YYYY-MM-DD) |
| committee | string | No | - | Committee identifier |
| limit | number | No | 20 | Maximum results (1-100) |
| offset | number | No | 0 | Pagination offset |
Note: Provide
docIdfor single document lookup, orkeywordfor search. At least one is recommended for targeted results. If neither is provided, the tool runs a search with default parameters, which may return a broad set of documents.
Response Format
{
"content": [{
"type": "text",
"text": "{
\"data\": [
{
\"id\": \"A9-0123/2024\",
\"title\": \"Report on Climate Action Directive\",
\"type\": \"REPORT\",
\"author\": \"MEP-124810\",
\"date\": \"2024-05-10\",
\"committee\": \"ENVI\",
\"summary\": \"Report on proposed climate legislation...\"
}
],
\"total\": 45,
\"limit\": 20,
\"offset\": 0
}"
}]
}
Example Usage
Claude Desktop:
Search for documents about renewable energy from the ENVI committee
TypeScript:
const result = await client.callTool('search_documents', {
keyword: 'renewable energy',
documentType: 'REPORT',
dateFrom: '2024-01-01',
limit: 25
});
Common Errors
| Error | Cause | Solution |
|---|---|---|
ValidationError: keyword | Invalid characters | Use only alphanumeric, spaces, hyphens, underscores |
SearchError: missing search parameters | Neither keyword nor docId provided | Provide a search term or use docId for direct lookup |
Use Cases
- Legislative Research: Find documents on specific topics
- Committee Work: Search documents by committee
- Author Tracking: Find documents by specific MEP
Tool: get_committee_info
Description: Retrieve detailed information about a European Parliament committee including composition, members, chair, and areas of responsibility. Can also list all current active corporate bodies.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| id | string | No* | - | Committee identifier |
| abbreviation | string | No* | - | Committee abbreviation (e.g., "ENVI", "AGRI") |
| showCurrent | boolean | No | false | If true, returns all current active corporate bodies |
*Either showCurrent: true, id, or abbreviation must be provided.
Response Format
{
"content": [{
"type": "text",
"text": "{
\"id\": \"COMM-ENVI\",
\"name\": \"Committee on Environment, Public Health and Food Safety\",
\"abbreviation\": \"ENVI\",
\"chair\": \"MEP-124820\",
\"viceChairs\": [\"MEP-124821\", \"MEP-124822\"],
\"members\": [\"MEP-124810\", \"MEP-124811\"],
\"responsibilities\": [
\"Environmental policy\",
\"Public health\",
\"Food safety\"
]
}"
}]
}
Example Usage
Claude Desktop:
Get information about the ENVI committee
TypeScript:
const result = await client.callTool('get_committee_info', {
abbreviation: 'ENVI'
});
const committee = JSON.parse(result.content[0].text);
console.log(`${committee.name} has ${committee.members.length} members`);
Use Cases
- Committee Overview: Get committee structure and leadership
- Member Lookup: Find MEPs serving on specific committees
- Responsibility Mapping: Understand committee jurisdictions
Tool: get_parliamentary_questions
Description: Retrieve parliamentary questions (written and oral) with filters for author, topic, and date range. Supports single question lookup by docId.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| docId | string | No | - | Document ID for single question lookup (e.g., "E-000001/2024") |
| type | string | No | - | Question type: WRITTEN or ORAL |
| author | string | No | - | MEP identifier or name of question author |
| topic | string | No | - | Question topic or keyword to search |
| status | string | No | - | Question status: PENDING or ANSWERED |
| dateFrom | string | No | - | Start date (YYYY-MM-DD) |
| dateTo | string | No | - | End date (YYYY-MM-DD) |
| limit | number | No | 50 | Maximum results (1-100) |
| offset | number | No | 0 | Pagination offset |
Note:
dateFrommust be โคdateTowhen both are provided.
Response Format
{
"content": [{
"type": "text",
"text": "{
\"data\": [
{
\"questionId\": \"Q-2024-001\",
\"author\": \"MEP-124810\",
\"type\": \"WRITTEN\",
\"subject\": \"Climate change adaptation funding\",
\"question\": \"What measures is the Commission taking...\",
\"date\": \"2024-03-15\",
\"answered\": true,
\"answerDate\": \"2024-04-10\",
\"answer\": \"The Commission has allocated...\"
}
],
\"total\": 328,
\"limit\": 50,
\"offset\": 0
}"
}]
}
Example Usage
Claude Desktop:
Show me written questions about climate change from 2024
TypeScript:
const result = await client.callTool('get_parliamentary_questions', {
topic: 'climate change',
type: 'WRITTEN',
dateFrom: '2024-01-01',
status: 'ANSWERED',
limit: 50
});
Use Cases
- MEP Accountability: Track questions from specific MEPs
- Topic Research: Find questions on specific policy areas
- Answer Monitoring: Check if questions have been answered
Tool: analyze_voting_patterns
Description: Analyze MEP voting behavior including political group alignment, cross-party voting, attendance rates, and topic-based voting patterns.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| mepId | string | Yes | - | MEP identifier to analyze |
| dateFrom | string | No | - | Analysis start date (YYYY-MM-DD) |
| dateTo | string | No | - | Analysis end date (YYYY-MM-DD) |
| compareWithGroup | boolean | No | true | Compare with political group average |
Response Format
{
"content": [{
"type": "text",
"text": "{
\"mepId\": \"MEP-124810\",
\"mepName\": \"Anna Lindberg\",
\"period\": {
\"from\": \"2024-01-01\",
\"to\": \"2024-12-31\"
},
\"statistics\": {
\"totalVotes\": 1250,
\"votesFor\": 850,
\"votesAgainst\": 200,
\"abstentions\": 200,
\"attendanceRate\": 92.5
},
\"groupAlignment\": {
\"politicalGroup\": \"S&D\",
\"alignmentRate\": 87.5,
\"divergentVotes\": 156
},
\"topTopics\": [
{ \"topic\": \"Climate Change\", \"voteCount\": 45 },
{ \"topic\": \"Agriculture Policy\", \"voteCount\": 38 }
],
\"crossPartyVoting\": {
\"withOtherGroups\": 125,
\"rate\": 10.0
}
}"
}]
}
Example Usage
Claude Desktop:
Analyze voting patterns for MEP-124810 in 2024, compare with their political group
TypeScript:
const result = await client.callTool('analyze_voting_patterns', {
mepId: 'MEP-124810',
dateFrom: '2024-01-01',
dateTo: '2024-12-31',
compareWithGroup: true
});
const analysis = JSON.parse(result.content[0].text);
console.log(`Attendance: ${analysis.statistics.attendanceRate}%`);
console.log(`Group alignment: ${analysis.groupAlignment.alignmentRate}%`);
Use Cases
- MEP Performance: Analyze attendance and voting activity
- Political Alignment: Compare MEP votes with party line
- Cross-Party Analysis: Identify bipartisan voting patterns
- Topic Focus: Discover MEP's key policy areas
Tool: track_legislation
Description: Track European Parliament legislative procedure progress including status, timeline, committees, amendments, and voting records.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| procedureId | string | Yes | - | Legislative procedure identifier (e.g., "2024/0001(COD)") |
Response Format
{
"content": [{
"type": "text",
"text": "{
\"procedureId\": \"2024/0001(COD)\",
\"title\": \"Climate Action and Renewable Energy Directive\",
\"type\": \"Ordinary legislative procedure (COD)\",
\"status\": \"PLENARY\",
\"currentStage\": \"Awaiting plenary vote\",
\"timeline\": [
{
\"date\": \"2024-01-15\",
\"stage\": \"Commission Proposal\",
\"description\": \"Legislative proposal submitted\"
}
],
\"committees\": [
{
\"abbreviation\": \"ENVI\",
\"role\": \"LEAD\",
\"rapporteur\": \"MEP-124810\"
}
],
\"amendments\": {
\"proposed\": 156,
\"adopted\": 89,
\"rejected\": 67
},
\"voting\": [...],
\"documents\": [...],
\"nextSteps\": [
\"Plenary debate scheduled for 2024-06-15\"
]
}"
}]
}
Example Usage
Claude Desktop:
Track the progress of legislative procedure 2024/0001(COD)
TypeScript:
const result = await client.callTool('track_legislation', {
procedureId: '2024/0001(COD)'
});
const procedure = JSON.parse(result.content[0].text);
console.log(`Status: ${procedure.status}`);
console.log(`Current stage: ${procedure.currentStage}`);
console.log(`Next: ${procedure.nextSteps[0]}`);
Use Cases
- Legislation Monitoring: Track bill progress through Parliament
- Timeline Analysis: View complete legislative timeline
- Amendment Tracking: Monitor proposed and adopted amendments
- Committee Work: See committee assignments and rapporteurs
Tool: generate_report
Description: Generate comprehensive analytical reports on European Parliament data. Supports four report types: MEP activity, committee performance, voting statistics, and legislation progress.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| reportType | string | Yes | - | Report type: MEP_ACTIVITY, COMMITTEE_PERFORMANCE, VOTING_STATISTICS, LEGISLATION_PROGRESS |
| subjectId | string | No | - | Subject identifier (MEP ID, Committee ID) - optional for aggregate reports |
| dateFrom | string | No | - | Report period start (YYYY-MM-DD) |
| dateTo | string | No | - | Report period end (YYYY-MM-DD) |
Response Format
{
"content": [{
"type": "text",
"text": "{
\"reportType\": \"MEP_ACTIVITY\",
\"subject\": \"Anna Lindberg\",
\"period\": {
\"from\": \"2024-01-01\",
\"to\": \"2024-12-31\"
},
\"generatedAt\": \"2024-12-31T23:59:59Z\",
\"summary\": \"Activity report for Anna Lindberg...\",
\"sections\": [
{
\"title\": \"Voting Activity\",
\"content\": \"Participated in 1250 votes...\"
}
],
\"statistics\": {
\"totalVotes\": 1250,
\"attendanceRate\": 92.5,
\"questionsSubmitted\": 28
},
\"recommendations\": [
\"Continue active participation...\"
]
}"
}]
}
Example Usage
Claude Desktop:
Generate an MEP activity report for MEP-124810 covering 2024
TypeScript:
// MEP Activity Report
const result = await client.callTool('generate_report', {
reportType: 'MEP_ACTIVITY',
subjectId: 'MEP-124810',
dateFrom: '2024-01-01',
dateTo: '2024-12-31'
});
// Committee Performance Report
const committeReport = await client.callTool('generate_report', {
reportType: 'COMMITTEE_PERFORMANCE',
subjectId: 'COMM-ENVI',
dateFrom: '2024-01-01',
dateTo: '2024-12-31'
});
// Parliament-wide Voting Statistics (no subjectId needed)
const votingStats = await client.callTool('generate_report', {
reportType: 'VOTING_STATISTICS',
dateFrom: '2024-01-01',
dateTo: '2024-12-31'
});
Report Types
-
MEP_ACTIVITY: Individual MEP performance and activity
- Voting participation and statistics
- Committee involvement
- Parliamentary questions submitted
- Reports authored
-
COMMITTEE_PERFORMANCE: Committee productivity analysis
- Meeting frequency
- Legislative output
- Member participation rates
-
VOTING_STATISTICS: Parliament-wide voting analysis
- Overall voting activity
- Adoption rates
- Political group alignment patterns
-
LEGISLATION_PROGRESS: Legislative activity overview
- New proposals submitted
- Completed procedures
- Ongoing procedures and timelines
Use Cases
- Performance Review: Generate MEP activity reports
- Committee Analysis: Assess committee productivity
- Statistical Analysis: Parliament-wide voting trends
- Progress Tracking: Monitor legislative progress
๐ต๏ธ OSINT Intelligence Tools
Tool: assess_mep_influence
Description: Compute a comprehensive MEP influence score using a 5-dimension model: voting activity, legislative output, committee engagement, parliamentary oversight, and coalition building.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| mepId | string | Yes | - | MEP identifier |
| dateFrom | string | No | - | Start date (YYYY-MM-DD) |
| dateTo | string | No | - | End date (YYYY-MM-DD) |
| includeDetails | boolean | No | false | Include detailed breakdown per dimension |
Example Usage
Assess the influence of MEP with ID "124810" over the past year
Data Source & Confidence
The response envelope includes a dataSource field that signals which underlying
source(s) supplied the Voting Activity and Coalition Building dimensions:
dataSource value | Meaning |
|---|---|
EP_API | Only the EP Open Data MEPDetails.votingStatistics placeholder was available (typically zeros). |
DOCEO | Per-MEP roll-call vote (RCV) data was aggregated from DOCEO XML; no EP API stats merged. |
EP_API+DOCEO | DOCEO supplied the RCV counts; EP API filled in fields DOCEO does not expose (e.g. attendanceRate). |
confidenceLevel semantics:
HIGHโ at least one real DOCEO RCV vote was observed for the MEP in the requested period.MEDIUMโ DOCEO data unavailable but EP API reported > 100 placeholder votes.LOWโ fallback path (no DOCEO observations and โค 100 EP API votes).
When DOCEO is unreachable or returns no votes within the requested date window,
the response degrades gracefully to dataSource: 'EP_API' and emits a
dataQualityWarning ("DOCEO RCV enrichment unavailable โฆ"); zero values are
never silently returned without a warning.
Tool: analyze_coalition_dynamics
Description: Analyze coalition cohesion and stress indicators across political groups, detecting voting alliances, defection rates, and fragmentation signals.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| groupIds | string[] | No | - | Political group identifiers to analyze (omit for all groups, 1-10 items) |
| dateFrom | string | No | - | Analysis start date (YYYY-MM-DD) |
| dateTo | string | No | - | Analysis end date (YYYY-MM-DD) |
| minimumCohesion | number | No | 0.5 | Minimum cohesion threshold for alliance detection (0-1) |
Example Usage
Analyze coalition dynamics between EPP and S&D over the last 6 months
Tool: detect_voting_anomalies
Description: Detect statistically unusual voting patterns from EP DOCEO RCV records โ party defections, sudden alignment shifts, abstention spikes, and cross-party movement signals.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| mepId | string | No | - | MEP identifier (omit for broad analysis) |
| groupId | string | No | - | Political group to analyze |
| dateFrom | string | No | - | Analysis start date (YYYY-MM-DD) |
| dateTo | string | No | - | Analysis end date (YYYY-MM-DD) |
| sensitivityThreshold | number | No | 0.3 | Anomaly sensitivity (0-1, lower = more anomalies detected). Default 0.3 matches the spec thresholds (z โฅ 1.5, WoW โฅ 20pp, cross-party โฅ 60%). |
โ ๏ธ Note: Cannot specify both
mepIdandgroupIdโ use one or neither.
Methodology
Each anomaly is detected against the MEP's own rolling baseline derived from
DOCEO roll-call (RCV) records. The fetch loop iterates every plenary week
between dateFrom and dateTo (MondayโFriday), aggregates records into a
deduplicated corpus (by record id), and caps it at up to 200 votes after
sort. A hard server-side cap of 26 plenary weeks (โ6 months) per request
bounds the fan-out โ wider windows are truncated to the most recent 26 weeks
and surface a weeksTruncated: true flag together with an explicit
dataQualityWarnings entry. Corpus results are cached for 5 minutes keyed by
${mepId ?? groupId ?? 'all'}|${dateFrom}|${dateTo} so back-to-back calls reuse
the multi-week fetch.
| Anomaly Type | Trigger |
|---|---|
PARTY_DEFECTION | Weekly defection-rate z-score โฅ 1.5 vs MEP's own baseline |
ABSTENTION_SPIKE | Weekly abstention-rate z-score โฅ 1.5 vs MEP's own baseline |
ALIGNMENT_SHIFT | Week-over-week defection-rate increase โฅ 20 percentage points |
CROSS_PARTY_ALIGNMENT_SHIFT | MEP voted with non-home group majorities on โฅ 60% of decisive RCVs in a weekly sub-window (โฅ3 decisive votes) |
Group majority on a vote is resolved by plurality of the DOCEO
groupBreakdown row, with ties broken alphabetically (ABSTAIN < AGAINST <
FOR) for deterministic results. Each MEP vote is classified as aligned,
defected, abstained, or absent relative to their home-group majority.
Anomaly Schema
{
"type": "PARTY_DEFECTION | ABSTENTION_SPIKE | ALIGNMENT_SHIFT | CROSS_PARTY_ALIGNMENT_SHIFT",
"severity": "HIGH | MEDIUM | LOW",
"mepId": "string",
"mepName": "string",
"description": "string",
"metrics": { "expectedValue": 0, "actualValue": 0, "deviation": 0 },
"detectedDate": "YYYY-MM-DD",
"evidenceVoteIds": ["RCV-...", "..."] // DOCEO LatestVoteRecord.id values โ drill down via get_latest_votes (record.id)
}
Confidence Level
Reflects RCV coverage (votes inspected on which the MEP appeared on the roll) and multi-week dispersion of the corpus:
HIGHfor โฅ 50 RCVs inspected AND โฅ 3 distinct plenary weeks contributing votesMEDIUMfor 10โ49 RCVs, or โฅ50 RCVs but < 3 contributing weeks (no multi-week dispersion)LOWfor < 10 RCVs, or when DOCEO is unreachable
The weeksInspected envelope field reports the number of distinct plenary
weeks that contributed RCV records to the analysed corpus. weeksTruncated
is true when the requested window exceeded the 26-week server cap.
When DOCEO supplies at least one record with a sitting date within the last
72 hours, dataFreshness is reported as NEAR_REALTIME. Multi-week
corpora additionally surface the oldest contributing week so callers can
see the span actually covered.
Example Usage
Detect voting anomalies in the EPP group over the past 3 months
Tool: compare_political_groups
Description: Cross-group comparative analysis of voting discipline, activity levels, policy focus areas, and internal cohesion.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| groupIds | string[] | Yes | - | Political group identifiers to compare (minimum 2, maximum 10) |
| dateFrom | string | No | - | Analysis start date (YYYY-MM-DD) |
| dateTo | string | No | - | Analysis end date (YYYY-MM-DD) |
| dimensions | string[] | No | all | Comparison dimensions: voting_discipline, activity_level, legislative_output, attendance, cohesion |
Example Usage
Compare EPP, S&D, and Renew Europe on voting cohesion and legislative output
Tool: analyze_legislative_effectiveness
Description: Score MEP or committee legislative effectiveness from real EP Open Data Portal sources โ reports authored, opinions delivered, amendments tabled and adopted, parliamentary questions filed, and the resulting legislative success rate. Fans out four EP endpoints in parallel under independent 6 s timeouts and tags every metric with a per-source dataSources flag.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| subjectType | string | Yes | Subject type: MEP or COMMITTEE |
| subjectId | string | Yes | Subject identifier (MEP ID, e.g. person/124810, or committee abbreviation, e.g. IMCO) |
| dateFrom | string | No | Start date (YYYY-MM-DD). Defaults to 1 January of the current year. |
| dateTo | string | No | End date (YYYY-MM-DD). Defaults to today. |
Data Sources
| Source | EP Endpoint | Populates | Per-source budget |
|---|---|---|---|
| procedures | /procedures | metrics.reportsAuthored, metrics.opinionsDelivered (rapporteur attribution) โ paginated up to 5 pages (โค 1000 items); a dataQualityWarnings entry is emitted when truncated | 6 s |
| adoptedTexts | /adopted-texts | metrics.legislativeSuccessRate (success denominator) โ fetched per calendar year in the window (parallel via Promise.allSettled, deduped by id); failed years are warned and skipped, all-year failures mark the source UNAVAILABLE; windows > 5 years fall back to a single unfiltered fetch | 6 s |
| plenaryDocumentItems | /plenary-session-documents-items | metrics.amendmentsTabled, metrics.amendmentsAdopted (author + status flag) | 6 s |
| questions | /parliamentary-questions | metrics.questionsAsked (filtered by author) | 6 s |
Each source's status is reported in dataSources: { procedures, adoptedTexts, plenaryDocumentItems, questions } as one of OK | EMPTY | TIMEOUT | UNAVAILABLE. A single failing source never zeros out the others โ graceful per-field degradation is preserved via Promise.allSettled-equivalent (per-source try/catch in withTimeoutAndAbort).
Methodology
reportsAuthoredโ procedures whoserapporteurfield names the subject MEP (case-insensitive substring match against the normalisedperson/{id}and bare-id tokens) and that lacks ashadow/opinionqualifier in the same field.opinionsDeliveredโ procedures where the same author match exists and therapporteurfield carries ashadow/opinionqualifier.amendmentsTabled/amendmentsAdoptedโ plenary-session document items whosetypeincludesAMENDMENT, whoseauthors[]contains the subject's id, and (forAdopted) whosestatusincludesADOPTED.legislativeSuccessRate=100 ร procedures-with-adopted-text / attributed-procedures. The numerator counts procedures whosereference(orid) appears asprocedureReferencein any/adopted-textsitem within the date window. The denominator counts the union ofreportsAuthoredandopinionsDeliveredprocedure IDs (no double-counting).questionsAskedโ/parliamentary-questionsfiltered upstream byauthor={subjectId}(for MEPs) and re-verified client-side by the aggregator's token set. For committee subjects, questions are fetched unfiltered and matched against any member id.- Committee aggregation โ for
subjectType: 'COMMITTEE', member MEP IDs are resolved from/corporate-bodiesand folded into the aggregator's token set. All four metrics are summed across the committee's membership in a single pass over the shared per-source fetches; the analysis is cached for 15 minutes by(subjectType, subjectId, dateFrom, dateTo)so the same committee window can be re-queried cheaply, but there is no per-member cache reuse โ switching to a different committee or window requires a fresh fan-out. - Deterministic ordering โ every list under
attributionsis sorted ascending by stableprocedureId/documentId/questionId, so repeated runs over the same input produce byte-identical output.
Computed Attributes
amendmentSuccessRate=100 ร amendmentsAdopted / amendmentsTabledlegislativeOutputPerMonth=(reportsAuthored + amendmentsTabled) / months-in-windowpeerComparisonPercentileโ heuristic; refined when corpus benchmarks become available.effectivenessRankโHIGHLY_EFFECTIVE(โฅ70),EFFECTIVE(โฅ50),MODERATE(โฅ30), orDEVELOPINGotherwise.
Example Usage
Analyse a known AI Act rapporteur for 2024:
{
"tool": "analyze_legislative_effectiveness",
"arguments": {
"subjectType": "MEP",
"subjectId": "person/124810", // example MEP id
"dateFrom": "2024-01-01",
"dateTo": "2024-12-31"
}
}
Aggregate the IMCO committee over the same window:
{
"tool": "analyze_legislative_effectiveness",
"arguments": {
"subjectType": "COMMITTEE",
"subjectId": "IMCO",
"dateFrom": "2024-01-01",
"dateTo": "2024-12-31"
}
}
The response envelope contains metrics, scores, computedAttributes, attributions (ID lists, sorted ascending), dataSources (per-source OK | EMPTY | TIMEOUT | UNAVAILABLE), dataQualityWarnings, and methodology. A 15-minute cache is keyed by (subjectType, subjectId, dateFrom, dateTo).
Tool: monitor_legislative_pipeline
Description: Monitor real-time legislative pipeline status with lifecycle-driven bottleneck detection and timeline forecasting. For every procedure in scope the authoritative event sequence is fetched from /procedures/{id}/events (bounded concurrency โค8 parallel) and compared against a corpus-wide historical distribution.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| committee | string | No | - | Filter by committee |
| status | string | No | ACTIVE | Pipeline status filter: ALL, ACTIVE, STALLED, COMPLETED |
| dateFrom | string | No | - | Analysis start date (YYYY-MM-DD) |
| dateTo | string | No | - | Analysis end date (YYYY-MM-DD) |
| limit | number | No | 20 | Maximum results to return (1-100) |
Methodology
daysInCurrentStageโ precise delta in days between the most recent event from/procedures/{id}/eventsandnow. Falls back to procedure-metadata dates when the event timeline is unavailable.bottleneckRiskโ percentile bucket of the current dwell vs. the historical distribution observed for the same(procedureType, stage)across the latest 500 procedures (30-minute cached corpus):HIGHโ dwell โฅ 95th percentile (real stuck procedure)MEDIUMโ dwell โฅ medianLOWโ otherwise
bottlenecks[]โ aggregated only from procedures whose dwell is โฅ the historical 95th percentile (or the legacyisStalledheuristic when no statistics exist). Each entry exposes thethresholdDaysused.estimatedCompletionDaysโ historical median remaining-time at the current stage (medianRemainingDaysโdaysInCurrentStage, clamped to โฅ0). When the matching(type, stage)cell has fewer than 3 observations the value falls back to a heuristic and the envelope reportsforecastBasis: 'INSUFFICIENT_DATA'.forecastBasisโ'HISTORICAL_MEDIAN'when any visible procedure used the historical-median forecast;'INSUFFICIENT_DATA'when matching(type, stage)cells lacked enough samples;'NOT_APPLICABLE'when every visible procedure is already completed (no remaining-time to forecast).lifecycleEvents[]โ per-procedure echo of the underlying event timeline (date, normalised stage, raw event type, title) for traceability.lifecycleCorpusโ metadata about the corpus used for the distribution:corpusSize,totalObservations,computationTimeMs.
Example Usage
Show the current legislative pipeline status and identify bottlenecks
Tool: analyze_committee_activity
Description: Analyze committee workload, document production, meeting frequency, decisions adopted, and member engagement metrics. Provides intelligence on committee operational efficiency and policy focus areas. Fans out four EP sources in parallel under a 5 s per-source timeout and tags every metric with a per-source data-availability status so downstream tools can branch on real coverage.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| committeeId | string | Yes | Committee identifier (e.g., "ENVI", "ITRE") |
| dateFrom | string | No | Start date (YYYY-MM-DD). Defaults to trailing 6 months. |
| dateTo | string | No | End date (YYYY-MM-DD). Defaults to today. |
Data Sources
| Source | EP Endpoint | Populates | Per-source budget |
|---|---|---|---|
| documents | /committee-documents | workload.documentsProduced | 5 s |
| procedures | /procedures | workload.activeLegislativeFiles | 5 s |
| meetings | /meetings | workload.meetingsHeld | 5 s |
| decisions | /meetings/{id}/decisions (fan-out, capped at 8 sittings) | workload.decisionsAdopted | 5 s |
Each source's status is reported in dataSources: { documents, procedures, meetings, decisions } as one of OK | EMPTY | TIMEOUT | UNAVAILABLE. A single failing source never zeros out the others โ graceful per-field degradation is preserved via Promise.allSettled.
Derived Metrics
decisionsPerMeeting=decisionsAdopted / meetingsHelddocumentsPerMonth=documentsProduced / windowMonthsactiveFilesPerMember=activeLegislativeFiles / totalMembers
Caching
Results are cached in-memory for 10 minutes keyed by ${committeeId}|${dateFrom}|${dateTo} to keep within the <200 ms warm-path target.
Example Usage
Analyze the ENVI committee's activity, document output, and member engagement over the last 6 months
Example Worked Output (ENVI, trailing 6 months)
{
"committeeId": "ENVI",
"committeeName": "Environment, Public Health and Food Safety",
"period": { "from": "2024-12-01", "to": "2025-05-31" },
"workload": {
"activeLegislativeFiles": 58,
"documentsProduced": 42,
"meetingsHeld": 11,
"decisionsAdopted": 37,
"opinionsIssued": 0
},
"memberEngagement": { "totalMembers": 88, "averageAttendance": 0, "activeContributors": 0 },
"legislativeOutput": { "reportsAdopted": 18, "amendmentsProcessed": 0, "successRate": 0.31 },
"derivedMetrics": { "decisionsPerMeeting": 3.36, "documentsPerMonth": 7, "activeFilesPerMember": 0.66 },
"dataSources": { "documents": "OK", "procedures": "OK", "meetings": "OK", "decisions": "OK" },
"confidenceLevel": "HIGH"
}
Tool: track_mep_attendance
Description: Track MEP plenary attendance patterns with trend detection, engagement scoring, and participation rate analysis. Supports both individual MEP queries and high-level overviews by country or political group.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| mepId | string | No | MEP identifier for individual attendance analysis |
| country | string | No | ISO 3166-1 alpha-2 country code for delegation overview |
| groupId | string | No | Political group identifier for group-level overview |
| limit | number | No | Maximum number of MEPs to include in overview queries |
| dateFrom | string | No | Start date (ISO 8601) |
| dateTo | string | No | End date (ISO 8601) |
At least one of mepId, country, or groupId is typically provided to scope the analysis.
Example Usage
Track attendance patterns and engagement trends for MEP-124810 over the current parliamentary term
Tool: analyze_country_delegation
Description: Analyze a country's MEP delegation composition, political group distribution, voting behavior, committee representation, and national cohesion metrics.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| country | string | Yes | ISO 3166-1 alpha-2 country code (e.g., "SE", "DE", "FR") |
| dateFrom | string | No | Start date (ISO 8601) |
| dateTo | string | No | End date (ISO 8601) |
Example Usage
Analyze the Swedish delegation's composition, voting behavior, and committee representation
Tool: generate_political_landscape
Description: Generate a comprehensive political landscape overview of the European Parliament, including group composition, power dynamics, coalition thresholds, bloc analysis, and fragmentation metrics. Aggregates the full paginated MEP roster (~720 MEPs in EP10) and normalises EP API native-language acronyms (e.g. PPE โ EPP, Verts-ALE โ Greens/EFA, EP9 ID โ EP10 successor PfE) before computing seat shares.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| dateFrom | string | No | Start date (ISO 8601) |
| dateTo | string | No | End date (ISO 8601) |
Confidence Levels
confidenceLevel | Trigger | Interpretation |
|---|---|---|
HIGH | Full pagination complete and totalMEPs โฅ 600 | Roster covers the full EP10 Parliament |
MEDIUM | Full pagination complete and 200 โค totalMEPs < 600 | Roster is representative but partial term coverage |
LOW | Pagination failed (MEP pagination failed at offset N warning) or totalMEPs < 200 | Treat seat shares as a partial sample |
Example Usage
Generate a current political landscape overview including group sizes, coalition possibilities, and bloc dynamics
Note (since 1.2.15): Earlier releases sampled only the first 100 MEPs (
getCurrentMEPs({ limit: 100 })) and skipped political-group-name normalisation, so reports could showtotalMEPs: 100and the same group split across multiple acronyms (e.g.PPEandEPPas separate entries). Both issues are fixed โ see Hack23/euparliamentmonitor 2026-04-26 reliability audits Defect #3 / D-08 and Defect #1 / D-01 for the original observations.
Tool: network_analysis
Description: MEP relationship network mapping combining committee co-membership and DOCEO roll-call voting similarity. Computes weighted-degree + Brandes betweenness centrality, deterministic label-propagation clusters with Newman modularity Q, depth-bounded BFS ego networks, and cross-cluster bridging MEPs.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| mepId | number | No | - | Focus on ego network for a specific MEP (enables BFS depth limit) |
| analysisType | string | No | combined | committee (shared-committee edges only), voting (DOCEO RCV similarity), or combined (mean of the two normalised weights) |
| depth | number | No | 2 | BFS traversal depth (1-3 hops); applied to the ego network when mepId is provided |
| minSimilarity | number | No | 0.7 | Minimum DOCEO co-vote agreement (0-1) to retain a voting-similarity edge |
Example Usage
Claude Desktop - Natural Language:
Map the immediate (depth 1) ego network for MEP 124810 combining committee + voting similarity, threshold 0.8
MCP Client - TypeScript:
// Committee-only network (legacy behaviour, fastest)
await client.callTool('network_analysis', { analysisType: 'committee' });
// Voting-similarity-only network (requires DOCEO RCV data)
await client.callTool('network_analysis', { analysisType: 'voting', minSimilarity: 0.8 });
// Depth-1 ego network around MEP 124810, combined edges
await client.callTool('network_analysis', {
mepId: 124810,
analysisType: 'combined',
depth: 1,
minSimilarity: 0.7,
});
Depth semantics
When mepId is provided the response is restricted to the ego subnetwork
within depth hops:
depth=1โ only direct neighbours of the focus MEP.depth=2โ adds friends-of-friends.depth=3โ โค3 hops from the focus.
When mepId is omitted a representative sample of up to 100 current MEPs
is analysed (depth is ignored) and clusters are detected globally. Full
roster pagination is not performed to stay within API rate-limit budgets.
Centrality & clusters
weightedDegreeโ sum of incident edge weights per node.betweennessCentralityโ Brandes' algorithm on the weighted subgraph (similarity converted to distance via1 / weight).centralityScoreโ composite0.6 ร weightedDegree + 0.4 ร 100 ร betweennessCentralityrounded to 2dp.modularityScoreโ Newman Q for the label-propagation partition (>0.3indicates meaningful community structure).
EP API Endpoints:
/meps,/corporate-bodies, DOCEO RCV XML (https://www.europarl.europa.eu/doceo/document/PV-.../RCV-...)
Tool: sentiment_tracker
Description: Track political-group sentiment over a configurable time window. Combines current EP API MEP composition with DOCEO roll-call vote (RCV) cohesion / defection data aggregated across last_month (~30d), last_quarter (~90d), or last_year (~365d). Returns per-group sentiment scores (-1 to +1), IMPROVING/STABLE/DECLINING/VOLATILE trends derived from half-window and sub-window DOCEO cohesion deltas, polarization index (1 โ seat-share-weighted mean cohesion), and consensus/divisive vote subjects.
Falls back to a seat-share-only proxy with confidenceLevel: 'LOW' when DOCEO has insufficient coverage in the requested window.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| groupId | string | No | - | Political group identifier (e.g., "EPP", "S&D"). Omit for all groups |
| timeframe | string | No | last_quarter | DOCEO RCV aggregation window: last_month (~30d), last_quarter (~90d), or last_year (~365d) |
Scoring methodology
- sentimentScore =
0.5 ยท DOCEO cohesion(centred at 0.5) +0.2 ยท inverse-dissent+0.3 ยท seat-share momentum, clamped to[-1, +1]. - trend = half-window cohesion delta โ
IMPROVINGwhen latest-half mean > earliest-half mean + 0.05,DECLININGwhen below by 0.05, otherwiseSTABLE.VOLATILEwhen cohesion variance across sub-windows > 0.1. - polarizationIndex =
1 โ seat-share-weighted mean(cohesion)across groups that have observed DOCEO data. Falls back to seat-share-score dispersion when no DOCEO coverage. - consensusTopics / divisiveTopics: DOCEO
LatestVoteRecord.subjectvalues whose per-vote group cohesion โฅ0.95 (consensus) or โค0.55 (divisive). - confidenceLevel:
HIGH(โฅ40 RCVs in window),MEDIUM(10โ39),LOW(<10, fallback to seat-share-only).
Example Usage
Claude Desktop - Natural Language:
Track the institutional positioning sentiment for the EPP group over the last quarter
MCP Client - TypeScript (last_month / 30-day window):
const result = await client.callTool('sentiment_tracker', {
groupId: 'EPP',
timeframe: 'last_month'
});
MCP Client - TypeScript (last_quarter / 90-day window โ default):
const result = await client.callTool('sentiment_tracker', {
timeframe: 'last_quarter'
});
MCP Client - TypeScript (last_year / 365-day window, capped at 300 RCVs):
const result = await client.callTool('sentiment_tracker', {
timeframe: 'last_year'
});
Example Response (abbreviated, with DOCEO coverage):
{
"content": [{
"type": "text",
"text": "{\"timeframe\":\"last_quarter\",\"groupSentiments\":[{\"groupId\":\"EPP\",\"sentimentScore\":0.41,\"trend\":\"IMPROVING\",\"volatility\":0.07,\"memberCount\":180,\"cohesionProxy\":0.93}],\"polarizationIndex\":0.12,\"consensusTopics\":[\"Ukraine humanitarian aid\"],\"divisiveTopics\":[\"Migration enforcement directive\"],\"confidenceLevel\":\"HIGH\",\"methodology\":\"Sentiment score = 0.5 ยท DOCEO cohesion ... polarizationIndex = 1 โ seat-share-weighted mean(cohesion)...\"}"
}]
}
Example Response (abbreviated, fallback path with no DOCEO coverage):
{
"content": [{
"type": "text",
"text": "{\"timeframe\":\"last_month\",\"groupSentiments\":[{\"groupId\":\"EPP\",\"sentimentScore\":0.3,\"trend\":\"STABLE\",\"cohesionProxy\":0.59}],\"polarizationIndex\":0.36,\"consensusTopics\":[],\"divisiveTopics\":[],\"confidenceLevel\":\"LOW\",\"methodology\":\"FALLBACK PATH (no DOCEO RCV coverage in 30d window โ 0 usable RCVs)...\"}"
}]
}
EP API Endpoints:
/meps(composition) + DOCEO RCV XML (https://www.europarl.europa.eu/doceo/document/PV-...)
Tool: early_warning_system
Description: Detect emerging political shifts, coalition fracture signals, and unusual patterns. Generates warnings with severity levels (CRITICAL/HIGH/MEDIUM/LOW), computes stability score (0-100).
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| sensitivity | string | No | medium | Detection sensitivity: low, medium, or high |
| focusArea | string | No | all | Focus area: coalitions, attendance, or all |
Example Usage
Claude Desktop - Natural Language:
Run the early warning system with high sensitivity focused on coalition dynamics
MCP Client - TypeScript:
const result = await client.callTool('early_warning_system', {
sensitivity: 'high',
focusArea: 'coalitions'
});
Example Response (abbreviated):
{
"content": [{
"type": "text",
"text": "{\"stabilityScore\":72,\"warnings\":[{\"severity\":\"HIGH\",\"type\":\"coalition_fracture\",\"description\":\"Unusual voting divergence detected in EPP-Renew bloc\",\"confidence\":0.85}],\"overallAssessment\":\"Moderate instability signals detected\"}"
}]
}
EP API Endpoints:
/meps,/meetings
Tool: comparative_intelligence
Description: Cross-reference 2-10 MEP activities across voting, committee, legislative, and attendance dimensions. Returns ranked profiles, correlation matrix, outlier detection, and cluster analysis.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| mepIds | array of numbers | Yes | - | List of 2-10 MEP identifiers to compare |
| dimensions | array of strings | No | all | Dimensions to compare: voting, committee, legislative, attendance |
Example Usage
Claude Desktop - Natural Language:
Compare MEPs 124810, 124811, and 124812 across voting and committee dimensions
MCP Client - TypeScript:
const result = await client.callTool('comparative_intelligence', {
mepIds: [124810, 124811, 124812],
dimensions: ['voting', 'committee']
});
Example Response (abbreviated):
{
"content": [{
"type": "text",
"text": "{\"rankedProfiles\":[{\"mepId\":124810,\"overallScore\":0.87,\"rank\":1}],\"correlationMatrix\":[[1.0,0.65,0.42],[0.65,1.0,0.71],[0.42,0.71,1.0]],\"outliers\":[],\"clusters\":[{\"members\":[124811,124812],\"label\":\"high-committee-engagement\"}]}"
}]
}
EP API Endpoints:
/meps,/meetings
Tool: correlate_intelligence
Description: Cross-tool OSINT intelligence correlation engine. Combines outputs from assess_mep_influence + detect_voting_anomalies (ELEVATED_ATTENTION alerts), early_warning_system + analyze_coalition_dynamics (COALITION_FRACTURE alerts), and optionally network_analysis + comparative_intelligence (COMPREHENSIVE_PROFILE alerts). Returns consolidated intelligence alerts with evidence chains and recommendations.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| mepIds | array of strings | Yes | - | MEP identifiers to cross-correlate (minimum 1, maximum 5) |
| groups | array of strings | No | - | Political groups for coalition fracture analysis (max 8, omit to use all major groups) |
| sensitivityLevel | string | No | MEDIUM | Alert sensitivity: HIGH, MEDIUM, or LOW โ HIGH surfaces more signals, LOW reduces noise |
| includeNetworkAnalysis | boolean | No | false | Run network centrality analysis (increases response time) |
Example Usage
Claude Desktop - Natural Language:
Run intelligence correlation for MEPs 124810 and 124811 with high sensitivity
MCP Client - TypeScript:
const result = await client.callTool('correlate_intelligence', {
mepIds: ['124810', '124811'],
groups: ['EPP', 'S&D'],
sensitivityLevel: 'HIGH',
includeNetworkAnalysis: true
});
Example Response (abbreviated):
{
"content": [{
"type": "text",
"text": "{\"alerts\":[{\"severity\":\"HIGH\",\"type\":\"cross_tool_correlation\",\"sources\":[\"early_warning_system\",\"analyze_coalition_dynamics\"],\"finding\":\"Coalition stress between EPP and S&D on migration policy\",\"evidenceChain\":[\"Voting divergence: 34%\",\"Attendance drop in joint committee sessions\"],\"confidence\":0.78}],\"summary\":{\"totalAlerts\":3,\"criticalCount\":0,\"highCount\":1}}"
}]
}
EP API Endpoints: Multiple (orchestrates other tools)
๐๏ธ EP API v2 Endpoint Tools
These tools provide direct access to all European Parliament Open Data API v2 endpoints.
Tool: get_current_meps
Description: Get currently active Members of European Parliament (today's date). Returns only MEPs with active mandates. Unlike get_meps, this tool uses the EP API /meps/show-current endpoint which returns accurate country and politicalGroup data in responses.
โ Recommended for use when you need MEP country or political group information. All OSINT intelligence tools use this endpoint internally.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| limit | number | No | 50 | Maximum results (1-100) |
| offset | number | No | 0 | Pagination offset |
Example Usage
Claude Desktop - Natural Language:
Show me all currently active MEPs
MCP Client - TypeScript:
const result = await client.callTool('get_current_meps', { limit: 50 });
Tool: get_incoming_meps
Description: Get incoming Members of European Parliament for the current parliamentary term. Returns MEPs who are newly joining.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| limit | number | No | 50 | Maximum results (1-100) |
| offset | number | No | 0 | Pagination offset |
Example Usage
List the newly arriving MEPs for the current parliamentary term
MCP Client - TypeScript:
const result = await client.callTool('get_incoming_meps', { limit: 20 });
Tool: get_outgoing_meps
Description: Get outgoing Members of European Parliament for the current parliamentary term. Returns MEPs who are leaving parliament.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| limit | number | No | 50 | Maximum results (1-100) |
| offset | number | No | 0 | Pagination offset |
Example Usage
Which MEPs are leaving the European Parliament this term?
MCP Client - TypeScript:
const result = await client.callTool('get_outgoing_meps', { limit: 20 });
Tool: get_homonym_meps
Description: Get homonym Members of European Parliament (MEPs with identical names) for the current parliamentary term. Useful for name disambiguation.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| limit | number | No | 50 | Maximum results (1-100) |
| offset | number | No | 0 | Pagination offset |
Example Usage
Are there any MEPs with identical names in the current parliament?
MCP Client - TypeScript:
const result = await client.callTool('get_homonym_meps', { limit: 50 });
Tool: get_speeches
Description: Get European Parliament plenary speeches and debate contributions. Supports single speech lookup by speechId or list with date range filtering.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| speechId | string | No | - | Specific speech ID for single lookup |
| year | number | No | - | Filter by calendar year (1900-2100, recommended for annual counts) |
| dateFrom | string | No | - | Start date filter (YYYY-MM-DD) |
| dateTo | string | No | - | End date filter (YYYY-MM-DD) |
| limit | number | No | 50 | Maximum results (1-100) |
| offset | number | No | 0 | Pagination offset |
Example Usage
Claude Desktop - Natural Language:
Get plenary speeches from January 2024
MCP Client - TypeScript:
// List speeches by year
const result = await client.callTool('get_speeches', {
year: 2024,
limit: 20
});
// List speeches in a date range
const rangeResult = await client.callTool('get_speeches', {
dateFrom: '2024-01-01',
dateTo: '2024-01-31',
limit: 20
});
// Get a specific speech
const speech = await client.callTool('get_speeches', {
speechId: 'SPEECH-12345'
});
Tool: get_procedures
Description: Get European Parliament legislative procedures. Supports single procedure lookup by processId or list with year filter.
โ ๏ธ Performance note: Always use a
yearfilter orprocessIdwhen querying procedures. Unfiltered queries can take 60+ seconds and may time out with the default 60s timeout.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| processId | string | No | - | Specific procedure ID (YYYY-NNNN format) for single lookup |
| year | number | No | - | Filter by year |
| limit | number | No | 50 | Maximum results (1-100) |
| offset | number | No | 0 | Pagination offset |
Example Usage
Claude Desktop - Natural Language:
Show me legislative procedures from 2024
MCP Client - TypeScript:
// List procedures by year (recommended โ avoids timeout)
const result = await client.callTool('get_procedures', { year: 2024, limit: 20 });
// Get a specific procedure
const procedure = await client.callTool('get_procedures', {
processId: '2024-0006'
});
Tool: get_procedure_events
Description: Get events linked to a specific EP legislative procedure (hearings, debates, votes). Returns the timeline of events for a procedure.
โ ๏ธ EP API note: This endpoint can be slow (30โ60+ s) and may return 404 for some procedure IDs. Use the
eli/dl/proc/prefixed IDs returned byget_proceduresfor best results.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| processId | string | Yes | - | Procedure process ID (e.g., eli/dl/proc/2024-0006 or 2024-0006) |
| limit | number | No | 50 | Maximum results (1-100) |
| offset | number | No | 0 | Pagination offset |
Example Usage
Show me the timeline of events for procedure 2024-0006
MCP Client - TypeScript:
const result = await client.callTool('get_procedure_events', {
processId: 'eli/dl/proc/2024-0006',
limit: 50
});
Tool: get_adopted_texts
Description: Get European Parliament adopted texts including legislative resolutions, positions, and non-legislative resolutions. Supports single document lookup by docId or list with year filter.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| docId | string | No | - | Specific document ID for single lookup |
| year | number | No | - | Filter by year |
| limit | number | No | 50 | Maximum results (1-100) |
| offset | number | No | 0 | Pagination offset |
Example Usage
Claude Desktop - Natural Language:
Get adopted texts from 2024
MCP Client - TypeScript:
const result = await client.callTool('get_adopted_texts', { year: 2024, limit: 20 });
Tool: get_events
Description: Get European Parliament events including hearings, conferences, seminars, and institutional events. Supports single event lookup by eventId or paginated list. Note: The EP API /events endpoint has no date filtering โ only eventId, limit, and offset are supported.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| eventId | string | No | - | Specific event ID for single lookup |
| limit | number | No | 50 | Maximum results (1-100) |
| offset | number | No | 0 | Pagination offset |
Example Usage
Show me recent European Parliament events
MCP Client - TypeScript:
const result = await client.callTool('get_events', {
limit: 20
});
Tool: get_meeting_activities
Description: Get activities linked to a specific EP plenary sitting (debates, votes, presentations). Requires a sitting ID.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| sittingId | string | Yes | - | Plenary sitting ID |
| limit | number | No | 20 | Maximum results (1-100). Default 20 โ activities endpoint can be slow |
| offset | number | No | 0 | Pagination offset |
Example Usage
What activities took place during plenary sitting MTG-PL-2024-01-15?
MCP Client - TypeScript:
const result = await client.callTool('get_meeting_activities', {
sittingId: 'MTG-PL-2024-01-15',
limit: 20
});
Tool: get_meeting_decisions
Description: Get decisions made in a specific EP plenary sitting. Returns adopted decisions and voting outcomes. Requires a sitting ID.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| sittingId | string | Yes | - | Plenary sitting ID |
| limit | number | No | 50 | Maximum results (1-100) |
| offset | number | No | 0 | Pagination offset |
Example Usage
What decisions were made in plenary sitting MTG-PL-2024-01-15?
MCP Client - TypeScript:
const result = await client.callTool('get_meeting_decisions', {
sittingId: 'MTG-PL-2024-01-15',
limit: 50
});
Tool: get_meeting_foreseen_activities
Description: Get foreseen (planned) activities for a specific EP meeting/plenary sitting. Returns scheduled agenda items.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| sittingId | string | Yes | - | Plenary sitting ID |
| limit | number | No | 20 | Maximum results (1-100). Default 20 โ foreseen-activities endpoint can be slow |
| offset | number | No | 0 | Pagination offset |
Example Usage
What is planned for the upcoming plenary sitting MTG-PL-2024-03-11?
MCP Client - TypeScript:
const result = await client.callTool('get_meeting_foreseen_activities', {
sittingId: 'MTG-PL-2024-03-11',
limit: 20
});
Tool: get_meeting_plenary_session_documents
Description: Get plenary session documents for a specific EP meeting/plenary sitting. Returns session documents associated with the meeting. Data source: European Parliament Open Data Portal.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| sittingId | string | Yes | - | Meeting / sitting identifier |
| limit | number | No | 20 | Maximum results (1-100). Default 20 โ plenary-session-documents endpoint can be slow |
| offset | number | No | 0 | Pagination offset |
Example Usage
Claude Desktop - Natural Language:
Get plenary session documents for sitting MTG-PL-2024-03-11
MCP Client - TypeScript:
const result = await client.callTool('get_meeting_plenary_session_documents', {
sittingId: 'MTG-PL-2024-03-11',
limit: 20
});
Tool: get_meeting_plenary_session_document_items
Description: Get plenary session document items for a specific EP meeting/plenary sitting. Returns individual agenda item documents for the meeting. Data source: European Parliament Open Data Portal.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| sittingId | string | Yes | - | Meeting / sitting identifier |
| limit | number | No | 20 | Maximum results (1-100). Default 20 โ plenary-session-document-items endpoint can be slow |
| offset | number | No | 0 | Pagination offset |
Example Usage
Claude Desktop - Natural Language:
Get individual agenda item documents for plenary sitting MTG-PL-2024-03-11
MCP Client - TypeScript:
const result = await client.callTool('get_meeting_plenary_session_document_items', {
sittingId: 'MTG-PL-2024-03-11',
limit: 20
});
Tool: get_mep_declarations
Description: Get MEP declarations of financial interests filed under the Rules of Procedure. Supports single declaration lookup by docId or list with year filter. GDPR: Access is audit-logged.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| docId | string | No | - | Specific declaration document ID for single lookup |
| year | number | No | - | Filter by year |
| limit | number | No | 50 | Maximum results (1-100) |
| offset | number | No | 0 | Pagination offset |
Example Usage
Claude Desktop - Natural Language:
Get MEP financial declarations from 2024
MCP Client - TypeScript:
const result = await client.callTool('get_mep_declarations', { year: 2024, limit: 20 });
Tool: get_plenary_documents
Description: Get European Parliament plenary documents. Supports single document lookup by docId or list with year filter.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| docId | string | No | - | Specific document ID for single lookup |
| year | number | No | - | Filter by year |
| limit | number | No | 50 | Maximum results (1-100) |
| offset | number | No | 0 | Pagination offset |
Example Usage
List plenary documents from 2024
MCP Client - TypeScript:
const result = await client.callTool('get_plenary_documents', { year: 2024, limit: 20 });
Tool: get_committee_documents
Description: Get European Parliament committee documents. Supports single document lookup by docId or list with year filter.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| docId | string | No | - | Specific document ID for single lookup |
| year | number | No | - | Filter by year |
| limit | number | No | 50 | Maximum results (1-100) |
| offset | number | No | 0 | Pagination offset |
Example Usage
Get committee documents from 2024
MCP Client - TypeScript:
const result = await client.callTool('get_committee_documents', { year: 2024, limit: 20 });
Tool: get_plenary_session_documents
Description: Get European Parliament plenary session documents (agendas, minutes, voting lists). Supports single document lookup by docId.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| docId | string | No | - | Specific document ID for single lookup |
| limit | number | No | 50 | Maximum results (1-100) |
| offset | number | No | 0 | Pagination offset |
Example Usage
Get plenary session documents including agendas and minutes
MCP Client - TypeScript:
const result = await client.callTool('get_plenary_session_documents', { limit: 20 });
Tool: get_plenary_session_document_items
Description: Get European Parliament plenary session document items. Returns individual items within plenary session documents.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| limit | number | No | 50 | Maximum results (1-100) |
| offset | number | No | 0 | Pagination offset |
Example Usage
Get individual items from plenary session documents
MCP Client - TypeScript:
const result = await client.callTool('get_plenary_session_document_items', {
limit: 50,
offset: 0
});
Tool: get_controlled_vocabularies
Description: Get European Parliament controlled vocabularies (standardized classification terms). Supports single vocabulary lookup by vocId.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| vocId | string | No | - | Specific vocabulary ID for single lookup (e.g., ep-document-types) |
| limit | number | No | 50 | Maximum results (1-100) |
| offset | number | No | 0 | Pagination offset |
Note: The
vocIdparameter should use the short identifier form (e.g.,ep-document-types), not the full URI form (def/ep-document-types). The list endpoint returns one entry:def/ep-document-types. Use the short form for single-vocabulary lookup.
Example Usage
Get the controlled vocabularies used by the European Parliament
MCP Client - TypeScript:
// List all vocabularies
const result = await client.callTool('get_controlled_vocabularies', { limit: 50 });
// Get a specific vocabulary by short ID
const vocab = await client.callTool('get_controlled_vocabularies', {
vocId: 'ep-document-types'
});
EP Controlled Vocabularies Reference
The EP Open Data Portal exposes the following controlled vocabulary schemes. These are available at https://data.europarl.europa.eu/api/v2/controlled-vocabularies/{vocId}:
Document Types (ep-document-types) โ 114 terms
Key document type identifiers used across EP API responses:
| Identifier | Label | Description |
|---|---|---|
TEXT_ADOPTED | Text adopted | Text adopted by a vote in plenary |
REPORT | Report | A report document |
REPORT_PLENARY | EP plenary report | Report for plenary debate/vote |
REPORT_OWN_INITIATIVE | Own initiative report | Text drawn up on Parliament's own initiative |
RESOLUTION | Resolution | Text expressing opinion on a matter/topic |
RESOLUTION_LEGISLATIVE | Legislative resolution | Legislative resolution text |
RESOLUTION_MOTION | Motion for a resolution | Motion declaring EP's opinion |
RESOLUTION_MOTION_JOINT | Joint motion for a resolution | Joint motion from multiple groups |
OPINION | Opinion | Non-binding institutional statement |
OPINION_PARLIAMENTARY_COMMITTEE | Parliamentary committee opinion | Committee opinion with amendments |
AMENDMENT | Amendment | Change to original text |
AMENDMENT_PLENARY | EP plenary amendment | Amendment tabled to plenary |
CRE_PLENARY | EP plenary verbatim report | Plenary sitting proceedings record |
CRE_SPEECH | Speech | Individual speech in proceedings |
MINUTES_PLENARY | EP plenary sitting minutes | Written meeting record |
QUESTION_WRITTEN | Written question | Written form question |
QUESTION_ORAL | Oral question | Oral question to plenary |
QUESTION_WRITTEN_ANSWER | Written answer | Answer to written question |
MEMBER_DECLARATION | Members' declaration | MEP code of conduct declaration |
MEMBER_DECLARATION_INTEREST_PRIVATE | Declaration of private interests | MEP private interests declaration |
MEMBER_DECLARATION_INTEREST_CONFLICT | Declaration on conflicts of interest | MEP conflict of interest declaration |
DIRECTIVE | Directive | EU legislative act (goals for member states) |
REGULATION | Regulation | Binding legislative act (EU-wide) |
DECISION | Decision | Binding act for specific addressees |
ACT_FOLLOWUP | Follow-up of acts | Commission follow-up document |
AGENDA_PLENARY_WEEK | EP plenary part-session agenda | Plenary session agenda |
VOTE_ROLLCALL_PLENARY | EP plenary roll-call votes | Roll-call vote results |
VOTE_RESULTS_PLENARY | EP plenary vote results | Vote results record |
ANNEX | Annex | Appended document section |
CORRIGENDUM | Corrigendum | Corrections document |
Activity Types (ep-activities) โ 70 terms
Key activity type identifiers used in events and procedure events:
| Identifier | Label |
|---|---|
PLENARY_SESSION | European Parliament plenary session |
PLENARY_SITTING | European Parliament plenary sitting |
PLENARY_DEBATE | Debates in plenary sitting |
PLENARY_VOTE | Vote in plenary sitting |
PLENARY_ADOPT_POSITION | EP position at 1st reading |
PLENARY_AMEND_PROPOSAL | EP position at 1st reading with amendments |
PLENARY_APPROVE_COUNCIL_POSITION | Approval of Council's position at 2nd reading |
PLENARY_REJECT_PROPOSAL | Plenary reject proposal |
PLENARY_DECISION | EP decision |
COMMITTEE_MEETING | Committee meeting |
COMMITTEE_ADOPTING_REPORT | Adoption of report by committee |
COMMITTEE_APPOINT_RAPPORTEUR | Appointment of rapporteur |
COMMITTEE_DEBATE | Deliberations in committee |
COMMITTEE_VOTE | Committee vote |
REFERRAL | Proposal referred to plenary |
INTERINSTITUTIONAL_NEGOTIATION | Interinstitutional negotiation (trilogue) |
PUBLICATION_OFFICIAL_JOURNAL | Publication in Official Journal |
SIGNATURE | Signature |
PROCEEDING_ACTIVITY | Proceeding activity |
Procedure Types (ep-procedure-types) โ 40+ terms
Key legislative procedure type identifiers:
| Identifier | Label | Description |
|---|---|---|
COD | Ordinary legislative procedure | Main EU legislative process (co-decision) |
CNS | Consultation procedure | Council consults Parliament |
APP | Consent procedure | Parliament must give consent |
NLE | Non-legislative procedure | Non-legislative enactment |
BUD | Budgetary procedure | EU budget process |
DEC | Discharge procedure | Budget discharge |
INI | Own-initiative procedure | Parliament's own initiative |
INL | Legislative initiative procedure | Parliament's legislative initiative |
INS | Institutional procedure | Institutional matters |
IMM | Members' immunity | Immunity proceedings |
DEA | Delegated acts | Examination of delegated acts |
RSP | Resolutions on topical subjects | Topical resolutions |
Statuses (ep-statuses) โ 24 terms
| Identifier | Label |
|---|---|
ACTIVE | Active |
ACTIVE_PROC | Active procedure |
ADOPTED | Adopted |
CANCELLED | Cancelled |
COMPLETED | Completed |
COMPLETED_PROC | Completed procedure |
LAPSED | Lapsed |
PENDING | Pending |
REJECTED | Rejected |
SUBMITTED | Submitted |
WITHDRAWN | Withdrawn |
WITHDRAWN_PROC | Withdrawn procedure |
Tool: get_external_documents
Description: Get external documents (non-EP documents such as Council positions, Commission proposals) from the European Parliament data portal. Supports single document lookup by docId.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| docId | string | No | - | Specific document ID for single lookup |
| year | number | No | - | Filter by year |
| limit | number | No | 50 | Maximum results (1-100) |
| offset | number | No | 0 | Pagination offset |
Example Usage
Get external documents like Council positions and Commission proposals from 2024
MCP Client - TypeScript:
const result = await client.callTool('get_external_documents', { year: 2024, limit: 20 });
Tool: get_procedure_event_by_id
Description: Get a specific event linked to a legislative procedure. Returns a single event for the specified procedure and event identifiers.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| processId | string | Yes | - | Legislative procedure identifier (e.g., "2024-0006") |
| eventId | string | Yes | - | Event identifier within the procedure |
Example Usage
Claude Desktop - Natural Language:
Get event EVT-001 from legislative procedure 2024-0006
MCP Client - TypeScript:
const result = await client.callTool('get_procedure_event_by_id', {
processId: '2024-0006',
eventId: 'EVT-001'
});
Example Response (abbreviated):
{
"content": [{
"type": "text",
"text": "{\"event\":{\"eventId\":\"EVT-001\",\"processId\":\"2024-0006\",\"type\":\"COMMITTEE_VOTE\",\"date\":\"2024-03-15\",\"title\":\"Committee vote on amendments\",\"outcome\":\"ADOPTED\",\"details\":{\"votesFor\":42,\"votesAgainst\":12,\"abstentions\":3}}}"
}]
}
Tool: get_all_generated_stats
Description: Retrieve precomputed European Parliament activity statistics covering parliamentary terms EP6โEP10 (2004โ2026), including monthly activity breakdowns, category rankings with percentiles, statistical analysis, political landscape history (group composition, fragmentation index, coalition dynamics), 30 OSINT-derived intelligence metrics (legislative efficiency, engagement indices, political concentration, 3-axis political compass, institutional stability, year-over-year dynamics), analytical commentary, and average-based predictions for 2027โ2031. Static data refreshed weekly by agentic workflow โ no live API calls.
๐ Visual Dashboard: See EP Political Landscape for comprehensive Mermaid chart visualizations of all statistics, political compass analysis, coalition scenarios, and derived intelligence metrics.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| yearFrom | number | No | 2004 | Start year for filtering (2004โ2031) |
| yearTo | number | No | 2026 | End year for filtering (2004โ2031) |
| category | string | No | all | Activity category: all, plenary_sessions, legislative_acts, roll_call_votes, committee_meetings, parliamentary_questions, resolutions, speeches, adopted_texts, political_groups, procedures, events, documents, mep_turnover, declarations |
| includePredictions | boolean | No | true | Include trend-based predictions for 2027โ2031 |
| includeMonthlyBreakdown | boolean | No | false | Include month-by-month activity data |
| includeRankings | boolean | No | true | Include percentile rankings and statistical analysis |
Example Usage
Get European Parliament activity statistics for 2019-2023 with predictions
MCP Client - TypeScript:
const result = await client.callTool('get_all_generated_stats', {
yearFrom: 2019,
yearTo: 2023,
category: 'all',
includePredictions: true,
includeRankings: true
});
Response Structure
The response includes:
| Field | Description |
|---|---|
coveragePeriod | Underlying dataset range (always { from: 2004, to: 2026 }) |
requestedPeriod | User-supplied year filter ({ from: yearFrom, to: yearTo }) |
yearlyStats | Annual statistics per year with 13 activity metrics, political landscape, and derived intelligence |
yearlyStats[].derivedIntelligence | 30 OSINT metrics: legislative efficiency, engagement, concentration, 3-axis political compass, stability, YoY dynamics |
yearlyStats[].politicalLandscape | Group composition, fragmentation index, coalition dynamics, quadrant distribution |
categoryRankings | Per-category percentile rankings recomputed for the filtered range |
predictions | Average-based extrapolations for 2027โ2031 with term-cycle adjustments |
analysisSummary | Trend analysis, peak/lowest years, OSINT key findings, coverage note |
methodology | Description of the statistical approach and data sources |
Category Filter Options
| Category | Description | Corresponding Tools |
|---|---|---|
plenary_sessions | Plenary sessions held | get_plenary_sessions |
legislative_acts | Legislative acts adopted | get_adopted_texts |
roll_call_votes | Roll-call votes conducted | get_voting_records |
committee_meetings | Committee meetings | get_committee_info |
parliamentary_questions | Questions tabled | get_parliamentary_questions |
resolutions | Resolutions adopted | get_adopted_texts |
speeches | Speeches delivered | get_speeches |
adopted_texts | Adopted texts | get_adopted_texts |
political_groups | Political group composition | compare_political_groups |
procedures | Legislative procedures | get_procedures |
events | Parliamentary events | get_events |
documents | Documents produced | search_documents |
mep_turnover | MEP arrivals/departures | get_incoming_meps, get_outgoing_meps |
declarations | MEP declarations | get_mep_declarations |
๐ง Server Diagnostics Tools
Tool: get_server_health
Description: Check server health and feed availability status. Returns server version, uptime, per-feed health status (ok/error/unknown), and overall availability level (Full/Degraded/Sparse/Unavailable). Does not make upstream API calls โ reports cached status from recent tool invocations. Use this to check which feeds are healthy before making data requests and to adapt data collection strategy.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| (none) | - | - | - | No parameters required |
Example Usage
Check server health and feed availability
MCP Client - TypeScript:
const result = await client.callTool('get_server_health', {});
Response Structure
| Field | Description |
|---|---|
server | Server health summary object |
server.version | Server version string |
server.uptime_seconds | Server uptime in seconds |
server.status | Overall server status (healthy, degraded, unhealthy) |
feeds | Object keyed by feed name, each value is a per-feed health status object |
feeds.<feed_name>.status | Feed status (ok, error, unknown) |
feeds.<feed_name>.lastSuccess | Timestamp of last successful call (if any) |
feeds.<feed_name>.lastAttempt | Timestamp of the most recent health check attempt (if any) |
feeds.<feed_name>.lastError | Last error message (if any) |
availability | Availability summary object |
availability.operational_feeds | Number of feeds currently operational |
availability.total_feeds | Total number of tracked feeds |
availability.level | Overall availability level (Full, Degraded, Sparse, Unavailable) |
๐ก EP API v2 Feed Endpoint Tools
These tools provide access to European Parliament Open Data API v2 feed endpoints. Feed endpoints return recently updated records, enabling change-tracking and incremental data synchronization workflows.
The 13 feed tools fall into two groups per the EP OpenAPI spec:
- Configurable-window feeds (6 tools): Accept a
timeframeparameter (today,one-day,one-week,one-month,custom) and optionalstartDate. Some also accept domain-specific filters. - Fixed-window feeds (7 tools): Accept no parameters. They return updates from a server-defined default window (typically one month).
All feed tools return a JSON-LD envelope with a data array and gracefully handle empty results (EP API returns 404 during recess or low-activity periods, or HTTP 200 with an error-in-body response).
Feed Response Format
All feed tools return the same response structure:
{
"content": [{
"type": "text",
"text": "{
\"data\": [
{ \"id\": \"...\", \"type\": \"...\", ... },
{ \"id\": \"...\", \"type\": \"...\", ... }
],
\"@context\": [ ... ],
\"dataQualityWarnings\": []
}"
}]
}
When no updates exist in the requested timeframe (EP API returns 404):
{
"content": [{
"type": "text",
"text": "{
\"data\": [],
\"@context\": [],
\"dataQualityWarnings\": [
\"EP Open Data Portal returned no data for this feed โ likely no updates in the requested timeframe\"
]
}"
}]
}
Important: An empty
dataarray with adataQualityWarningsmessage is not an error โ it means the EP API had no updates in the requested timeframe. Always checkdataQualityWarningsbefore assuming the feed is broken.
โ ๏ธ Known EP API Behavior & Limitations
Slow Feed Endpoints
Several EP API feed endpoints are significantly slower than standard data endpoints. The response times below reflect real-world measurements (April 2026). Note: EP API response times are highly variable โ during high-load periods, even "fast" feeds may exceed the default 60s timeout.
| Feed Endpoint | Type | Best-Case Response Time | Peak-Load Response Time | Notes |
|---|---|---|---|---|
adopted-texts/feed | Configurable | ~1 s | 30โ60+ s | โ Usually fast; may slow during peak load |
meps-declarations/feed | Configurable | ~1 s | 10โ30 s | โ Usually fast and reliable |
external-documents/feed | Configurable | ~1 s | 5โ15 s | โ Usually fast and reliable |
controlled-vocabularies/feed | Fixed | HTTP 204 | HTTP 204 | Returns 204 No Content (vocabularies rarely change) |
meps/feed | Configurable | ~9 s | 30โ60+ s | โ ๏ธ May time out under load |
plenary-session-documents/feed | Fixed | 20โ40 s | 60โ120+ s | โ ๏ธ Slow; may return error-in-body |
parliamentary-questions/feed | Fixed | 30โ60 s | 60โ120+ s | โ ๏ธ Slow; may return error-in-body |
procedures/feed | Configurable | 30โ60 s | 60โ120+ s | โ ๏ธ May time out |
plenary-documents/feed | Fixed | 30โ60 s | 60โ120+ s | โ ๏ธ May return error-in-body |
events/feed | Configurable | 30โ60 s | 60โ120+ s | โ ๏ธ May time out |
committee-documents/feed | Fixed | 30โ60 s | 60โ120+ s | โ ๏ธ May return error-in-body |
documents/feed | Fixed | 60โ120 s | 120+ s | โ ๏ธ Very slow; frequently times out |
corporate-bodies/feed | Fixed | 60โ180 s | 180+ s | โ ๏ธ Slowest feed; frequently times out |
The MCP server applies a minimum 120-second timeout to the following feed tools regardless of the global timeout setting:
- Always (fixed-window):
get_documents_feed,get_plenary_documents_feed,get_committee_documents_feed,get_plenary_session_documents_feed,get_parliamentary_questions_feed,get_corporate_bodies_feed, and the configurableget_procedures_feed. - Only when
timeframe === "one-month"(configurable):get_meps_feed,get_mep_declarations_feed,get_adopted_texts_feed,get_external_documents_feedโ shorter timeframes use the global EP request timeout. - No per-request floor (uses the global EP request timeout):
get_controlled_vocabularies_feed(returns HTTP 204 almost instantly) andget_events_feed. The latter surfaces timeouts/rate-limits/upstream failures via the normalized feed envelope (see Tool: get_events_feed).
If the global timeout (set via --timeout <ms> CLI argument or EP_REQUEST_TIMEOUT_MS environment variable) is higher than 120 seconds, that higher value is used instead for tools that apply the 120-second floor.
Tip: For production use, set
--timeout 180000(180 seconds) to accommodate the slowest feeds. The default 60-second timeout is sufficient for most data endpoints but too short for many feeds during peak load.
Recommended fallbacks when feeds time out:
get_procedures_feedโ useget_procedures({ year: 2026, limit: 20 })insteadget_events_feedโ useget_events({ limit: 50 })instead (note:get_eventssupports onlyeventId,limit, andoffsetโ no date filtering)get_meps_feedโ useget_current_meps({ limit: 50 })insteadget_adopted_texts_feedโ useget_adopted_texts({ year: 2026 })instead
Feed 404 Responses (Empty Feeds)
During EP recess periods or low-activity windows, feed endpoints may return HTTP 404. The MCP server converts these to empty-but-successful responses with dataQualityWarnings. This is expected behavior โ not an error.
Voting Records Data Delay
The EP publishes roll-call voting data with a delay of several weeks. Queries to get_voting_records for the most recent 1โ2 months may return empty results โ this is expected EP API behavior, not an error. For recent legislative activity, use get_adopted_texts or get_adopted_texts_feed instead.
Feed Parameters
Configurable-window feeds (6 tools)
These tools accept a timeframe parameter to control the data window:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| timeframe | string | No | one-week | Time window: today, one-day, one-week, one-month, or custom |
| startDate | string | Conditional | - | Start date in YYYY-MM-DD format. Required when timeframe is custom |
Validation rule: When
timeframeiscustom, thestartDateparameter becomes required. The server returns a validation error ifstartDateis missing or empty for custom timeframes.
Tools: get_meps_feed, get_events_feed, get_procedures_feed, get_adopted_texts_feed, get_mep_declarations_feed, get_external_documents_feed
Some also accept an additional filter: activityType (events), processType (procedures), workType (adopted-texts, declarations, external-documents).
Fixed-window feeds (7 tools)
These tools accept no parameters. The EP API returns updates from a server-defined default window (typically one month). Per the EP OpenAPI spec, these endpoints only accept a user-agent header โ no timeframe or start-date query parameters.
Tools: get_documents_feed, get_plenary_documents_feed, get_committee_documents_feed, get_plenary_session_documents_feed, get_parliamentary_questions_feed, get_corporate_bodies_feed, get_controlled_vocabularies_feed
Feed Tools by Category
| Category | Feed Tools | Type | Extra Filter |
|---|---|---|---|
| MEP Data | get_meps_feed, get_mep_declarations_feed | Configurable | workType (declarations) |
| Legislative | get_procedures_feed, get_adopted_texts_feed | Configurable | processType / workType |
| Documents | get_documents_feed โถ, get_plenary_documents_feed โถ, get_committee_documents_feed โถ, get_plenary_session_documents_feed โถ, get_external_documents_feed | Mixed | workType (external only) |
| Events | get_events_feed | Configurable | activityType |
| Questions | get_parliamentary_questions_feed โถ | Fixed | โ |
| Institutional | get_corporate_bodies_feed โถ, get_controlled_vocabularies_feed โถ | Fixed | โ |
โถ = Fixed-window feed (no parameters)
Working with Feed Responses (TypeScript)
// Standard feed consumption pattern
const result = await client.callTool('get_meps_feed', {
timeframe: 'one-week'
});
const response = JSON.parse(result.content[0].text);
// Check for empty feed (404 converted to empty result)
if (response.dataQualityWarnings?.length > 0) {
console.log('Feed warning:', response.dataQualityWarnings[0]);
}
// Process data
if (response.data.length > 0) {
for (const item of response.data) {
console.log(`Updated: ${item.id} (${item.type})`);
}
} else {
console.log('No updates in the requested timeframe');
}
// Custom timeframe with specific start date
const result = await client.callTool('get_adopted_texts_feed', {
timeframe: 'custom',
startDate: '2026-01-01'
});
// Using type filters
const result = await client.callTool('get_external_documents_feed', {
timeframe: 'one-month',
workType: 'COUNCIL_POSITION'
});
Tool: get_meps_feed
Description: Get recently updated MEPs from the European Parliament feed endpoint. Returns MEP records that have been modified within the specified timeframe.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| timeframe | string | No | one-week | Time window: today, one-day, one-week, one-month, or custom |
| startDate | string | Conditional | - | Start date (YYYY-MM-DD). Required when timeframe is custom |
Example Usage
Claude Desktop - Natural Language:
Show me MEPs updated in the last week
MCP Client - TypeScript:
const result = await client.callTool('get_meps_feed', {
timeframe: 'one-week'
});
Tool: get_events_feed
Description: Get recently updated events from the European Parliament feed endpoint. Returns event records that have been modified within the specified timeframe.
โ ๏ธ Slow endpoint: The EP API
events/feedendpoint is significantly slower than other feeds โone-monthqueries may take 60+ seconds. The global EP request timeout (default 60s, configurable via--timeout/EP_REQUEST_TIMEOUT_MS) applies; this tool no longer forces an extended per-request minimum. For faster results, useget_eventswithlimit/offsetpagination instead (note:get_eventshas no date filtering โ onlyeventId,limit, andoffsetare supported).
โ Normalized error envelope (since v1.3.x): The following known transient upstream failure modes are caught and returned as the uniform feed response shape (with
status: "unavailable"plus machine-readableerrorCode/retryable/ optionalupstreamandretryAfterMsmetadata). Unclassified or unexpected errors (e.g., network socket failures, schema validation errors) still throw โ callers should combine envelope inspection with standard exception handling:
errorCodeWhen retryableupstreampresentNOT_FOUNDUpstream HTTP 404 (empty timeframe / recess window) falsestatusCode: 404UPSTREAM_TIMEOUTRequest exceeded the configured timeout trueomitted RATE_LIMIT(local)Local token-bucket limiter rejected the call before any HTTP request trueomitted โ retryAfterMsis setRATE_LIMIT(upstream)EP API returned HTTP 429 truestatusCode: 429UPSTREAM_ERROREP API returned HTTP 5xx truestatusCode: 5xxENRICHMENT_FAILEDHTTP 200 with errorfield and nodataarraytrueparsed upstream status when present
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| timeframe | string | No | one-week | Time window: today, one-day, one-week, one-month, or custom |
| startDate | string | Conditional | - | Start date (YYYY-MM-DD). Required when timeframe is custom |
| activityType | string | No | - | Filter by activity type |
Example Usage
Claude Desktop - Natural Language:
Show me EP events updated today
MCP Client - TypeScript:
const result = await client.callTool('get_events_feed', {
timeframe: 'today'
});
const envelope = JSON.parse(result.content[0].text);
if (envelope.status === 'operational') {
for (const event of envelope.items) {
console.log(event['@id']);
}
} else if (envelope.status === 'degraded') {
// Items are present but there are data-quality warnings โ still process them.
console.warn(`get_events_feed degraded: ${envelope.dataQualityWarnings?.join('; ')}`);
for (const event of envelope.items) {
console.log(event['@id']);
}
} else {
// status === 'unavailable' โ no items to process.
console.warn(`get_events_feed unavailable: ${envelope.errorCode} โ ${envelope.reason}`);
if (envelope.retryable && envelope.retryAfterMs) {
// Honor the precise retry hint from the local rate limiter.
// Re-invoke the same call after the suggested delay.
await new Promise(resolve => setTimeout(resolve, envelope.retryAfterMs));
// โฆ then retry the callTool request
}
}
Tool: get_procedures_feed
Description: Get recently updated legislative procedures from the European Parliament feed endpoint. Returns procedure records that have been modified within the specified timeframe.
โ ๏ธ Slow endpoint: The EP API
procedures/feedendpoint is significantly slower than other feeds โone-monthqueries may take 120+ seconds. An extended timeout (120s) is applied automatically. For faster results, useget_procedureswith ayearfilter instead.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| timeframe | string | No | one-week | Time window: today, one-day, one-week, one-month, or custom |
| startDate | string | Conditional | - | Start date (YYYY-MM-DD). Required when timeframe is custom |
| processType | string | No | - | Filter by procedure/process type |
Example Usage
Claude Desktop - Natural Language:
What legislative procedures were updated this month?
MCP Client - TypeScript:
const result = await client.callTool('get_procedures_feed', {
timeframe: 'one-month'
});
Tool: get_adopted_texts_feed
Description: Get recently updated adopted texts from the European Parliament feed endpoint. Returns adopted text records that have been modified within the specified timeframe.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| timeframe | string | No | one-week | Time window: today, one-day, one-week, one-month, or custom |
| startDate | string | Conditional | - | Start date (YYYY-MM-DD). Required when timeframe is custom |
| workType | string | No | - | Filter by work type |
Example Usage
Claude Desktop - Natural Language:
Show me adopted texts updated in the past week
MCP Client - TypeScript:
const result = await client.callTool('get_adopted_texts_feed', {
timeframe: 'one-week'
});
Tool: get_mep_declarations_feed
Description: Get recently updated MEP declarations from the European Parliament feed endpoint. Returns MEP declaration records that have been modified within the specified timeframe.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| timeframe | string | No | one-week | Time window: today, one-day, one-week, one-month, or custom |
| startDate | string | Conditional | - | Start date (YYYY-MM-DD). Required when timeframe is custom |
| workType | string | No | - | Filter by work type |
Example Usage
Claude Desktop - Natural Language:
Show me MEP declarations updated this month
MCP Client - TypeScript:
const result = await client.callTool('get_mep_declarations_feed', {
timeframe: 'one-month'
});
Tool: get_documents_feed
Description: Get recently updated documents from the EP Open Data Portal feed. This is a fixed-window feed โ no parameters needed. Returns items updated within the server-defined default window (typically one month).
โ ๏ธ Slow endpoint: Response times typically 60โ120 s. The EP API often returns an error-in-body response (HTTP 200 with
errorfield) during low-activity periods.
Parameters
No parameters โ this feed uses a server-defined default window (typically one month).
Example Usage
Claude Desktop - Natural Language:
Get the latest documents feed from the European Parliament
MCP Client - TypeScript:
const result = await client.callTool('get_documents_feed', {});
Tool: get_plenary_documents_feed
Description: Get recently updated plenary documents from the EP Open Data Portal feed. This is a fixed-window feed โ no parameters needed. Returns items updated within the server-defined default window (typically one month).
โ ๏ธ Slow endpoint: Response times typically 30โ60 s. The EP API often returns an error-in-body response during low-activity periods.
Parameters
No parameters โ this feed uses a server-defined default window (typically one month).
Example Usage
Claude Desktop - Natural Language:
Show me the latest plenary documents feed
MCP Client - TypeScript:
const result = await client.callTool('get_plenary_documents_feed', {});
Tool: get_committee_documents_feed
Description: Get recently updated committee documents from the EP Open Data Portal feed. This is a fixed-window feed โ no parameters needed. Returns items updated within the server-defined default window (typically one month).
โ ๏ธ Slow endpoint: Response times typically 30โ60 s. The EP API often returns an error-in-body response during low-activity periods.
Parameters
No parameters โ this feed uses a server-defined default window (typically one month).
Example Usage
Claude Desktop - Natural Language:
Get the latest committee documents feed
MCP Client - TypeScript:
const result = await client.callTool('get_committee_documents_feed', {});
Tool: get_plenary_session_documents_feed
Description: Get recently updated plenary session documents from the EP Open Data Portal feed. This is a fixed-window feed โ no parameters needed. Returns items updated within the server-defined default window (typically one month).
Parameters
No parameters โ this feed uses a server-defined default window (typically one month).
Example Usage
Claude Desktop - Natural Language:
Show me the plenary session documents feed
MCP Client - TypeScript:
const result = await client.callTool('get_plenary_session_documents_feed', {});
Tool: get_external_documents_feed
Description: Get recently updated external documents from the European Parliament feed endpoint. Returns external document records (Council positions, Commission proposals) that have been modified within the specified timeframe.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| timeframe | string | No | one-week | Time window: today, one-day, one-week, one-month, or custom |
| startDate | string | Conditional | - | Start date (YYYY-MM-DD). Required when timeframe is custom |
| workType | string | No | - | Filter by work type |
Example Usage
Claude Desktop - Natural Language:
Show me external documents updated in the last month
MCP Client - TypeScript:
const result = await client.callTool('get_external_documents_feed', {
timeframe: 'one-month'
});
Tool: get_parliamentary_questions_feed
Description: Get recently updated parliamentary questions from the EP Open Data Portal feed. This is a fixed-window feed โ no parameters needed. Returns items updated within the server-defined default window (typically one month).
โ ๏ธ Slow endpoint: Response times typically 30โ60 s. The EP API often returns an error-in-body response during low-activity periods.
Parameters
No parameters โ this feed uses a server-defined default window (typically one month).
Example Usage
Claude Desktop - Natural Language:
Check the parliamentary questions feed for recent updates
MCP Client - TypeScript:
const result = await client.callTool('get_parliamentary_questions_feed', {});
Tool: get_corporate_bodies_feed
Description: Get recently updated corporate bodies (committees, delegations, inter-parliamentary delegations) from the EP Open Data Portal feed. This is a fixed-window feed โ no parameters needed. Returns items updated within the server-defined default window (typically one month).
โ ๏ธ Very slow endpoint: Response times typically 60โ180 s. May time out with default timeout settings.
Parameters
No parameters โ this feed uses a server-defined default window (typically one month).
Example Usage
Claude Desktop - Natural Language:
Check the corporate bodies feed for recent updates
MCP Client - TypeScript:
const result = await client.callTool('get_corporate_bodies_feed', {});
Tool: get_controlled_vocabularies_feed
Description: Get recently updated controlled vocabularies from the EP Open Data Portal feed. This is a fixed-window feed โ no parameters needed. Returns items updated within the server-defined default window (typically one month).
โน๏ธ This endpoint typically returns HTTP 204 (No Content) when vocabularies have not changed โ the MCP server converts this to an empty feed response.
Parameters
No parameters โ this feed uses a server-defined default window (typically one month).
Example Usage
Claude Desktop - Natural Language:
Have any controlled vocabularies been updated recently?
MCP Client - TypeScript:
const result = await client.callTool('get_controlled_vocabularies_feed', {});
๐ MCP Prompts
Pre-built intelligence analysis prompt templates for common parliamentary research workflows. For the exact argument schemas, refer to the prompt definitions in src/prompts/index.ts.
| Prompt | Description | Arguments |
|---|---|---|
mep_briefing | Comprehensive MEP intelligence briefing with voting record, committee work, and influence assessment | mepId (required), period? |
coalition_analysis | Coalition dynamics and voting bloc analysis across political groups | policyArea?, period? |
legislative_tracking | Legislative procedure tracking report with timeline and status | procedureId?, committee? |
political_group_comparison | Multi-dimensional comparison of political groups | groups? |
committee_activity_report | Committee workload, engagement, and document production report | committeeId (required) |
voting_pattern_analysis | Voting pattern trend detection and anomaly identification | topic?, mepId? |
country_delegation_analysis | Country delegation composition, voting cohesion, and cross-party dynamics | country (required), period? |
Example: Using MCP Prompts
// Request a pre-built prompt template
const prompt = await client.getPrompt('mep_briefing', { mepId: 'MEP-124810' });
// Returns structured messages for LLM consumption
๐ฆ MCP Resources
Direct data access via European Parliament resource URIs using the ep:// scheme.
| Resource URI | Description |
|---|---|
ep://meps | List of all current MEPs |
ep://meps/{mepId} | Individual MEP profile and details |
ep://committees/{committeeId} | Committee information and membership |
ep://plenary-sessions | Recent plenary session listing |
ep://votes/{sessionId} | Voting records for a specific session |
ep://political-groups | Political group listing with seat counts |
ep://procedures/{procedureId} | Legislative procedure details (YYYY-NNNN format) |
ep://plenary/{plenaryId} | Specific plenary session details |
ep://documents/{documentId} | Legislative document details |
Example: Reading MCP Resources
// Read a resource directly
const meps = await client.readResource('ep://meps');
const mepDetails = await client.readResource('ep://meps/MEP-124810');
const committee = await client.readResource('ep://committees/ENVI');
const procedure = await client.readResource('ep://procedures/2024-0006');
const document = await client.readResource('ep://documents/DOC-12345');
const plenary = await client.readResource('ep://plenary/MTG-PL-2024-01-15');
๐ฏ Common Use Cases
Use Case 1: Research a Specific MEP
// Step 1: Find MEP by country
const meps = await client.callTool('get_meps', {
country: 'SE',
limit: 10
});
// Step 2: Get detailed information
const mepDetails = await client.callTool('get_mep_details', {
id: 'MEP-124810'
});
// Step 3: Analyze voting patterns
const votingAnalysis = await client.callTool('analyze_voting_patterns', {
mepId: 'MEP-124810',
dateFrom: '2024-01-01',
compareWithGroup: true
});
// Step 4: Generate activity report
const report = await client.callTool('generate_report', {
reportType: 'MEP_ACTIVITY',
subjectId: 'MEP-124810',
dateFrom: '2024-01-01',
dateTo: '2024-12-31'
});
Use Case 2: Track Climate Legislation
// Step 1: Search for climate-related documents
const documents = await client.callTool('search_documents', {
keyword: 'climate change renewable',
documentType: 'REPORT',
dateFrom: '2024-01-01',
limit: 50
});
// Step 2: Track specific legislation
const tracking = await client.callTool('track_legislation', {
procedureId: '2024/0001(COD)'
});
// Step 3: Get voting records on climate topics
const votes = await client.callTool('get_voting_records', {
topic: 'climate',
dateFrom: '2024-01-01',
limit: 100
});
Use Case 3: Committee Analysis
// Step 1: Get committee information
const committee = await client.callTool('get_committee_info', {
abbreviation: 'ENVI'
});
// Step 2: List committee members
const members = await client.callTool('get_meps', {
committee: 'ENVI',
active: true,
limit: 100
});
// Step 3: Generate committee report
const report = await client.callTool('generate_report', {
reportType: 'COMMITTEE_PERFORMANCE',
subjectId: 'COMM-ENVI',
dateFrom: '2024-01-01',
dateTo: '2024-12-31'
});
Use Case 4: Political Group Analysis
// Step 1: Get all MEPs from political group
const groupMEPs = await client.callTool('get_meps', {
group: 'S&D',
active: true,
limit: 100
});
// Step 2: Analyze each MEP's voting patterns
for (const mep of groupMEPs.data) {
const analysis = await client.callTool('analyze_voting_patterns', {
mepId: mep.id,
dateFrom: '2024-01-01',
compareWithGroup: true
});
// Process analysis...
}
// Step 3: Generate voting statistics
const stats = await client.callTool('generate_report', {
reportType: 'VOTING_STATISTICS',
dateFrom: '2024-01-01',
dateTo: '2024-12-31'
});
โ Best Practices
1. Efficient Pagination
// Good: Reasonable page size with pagination
async function getAllMEPs() {
const meps = [];
let offset = 0;
const limit = 50; // Optimal page size
while (true) {
const result = await client.callTool('get_meps', {
limit,
offset,
active: true
});
const data = JSON.parse(result.content[0].text);
meps.push(...data.data);
if (data.data.length < limit) break; // No more pages
offset += limit;
}
return meps;
}
2. Rate Limit Handling
// Implement exponential backoff
async function callToolWithRetry(toolName, params, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await client.callTool(toolName, params);
} catch (error) {
if (error.message.includes('Rate limit')) {
const delay = Math.pow(2, i) * 1000; // Exponential backoff
await new Promise(resolve => setTimeout(resolve, delay));
} else {
throw error;
}
}
}
throw new Error('Max retries exceeded');
}
3. Input Validation
// Validate inputs before calling tools
function validateCountryCode(code: string): boolean {
return /^[A-Z]{2}$/.test(code);
}
function validateDateFormat(date: string): boolean {
return /^\d{4}-\d{2}-\d{2}$/.test(date);
}
// Use validation
if (!validateCountryCode(countryInput)) {
throw new Error('Invalid country code format. Use ISO 3166-1 alpha-2 (e.g., "SE")');
}
const meps = await client.callTool('get_meps', {
country: countryInput,
limit: 50
});
4. Error Handling
// Comprehensive error handling
async function safeFetchMEP(mepId: string) {
try {
const result = await client.callTool('get_mep_details', { id: mepId });
return JSON.parse(result.content[0].text);
} catch (error) {
if (error instanceof Error) {
if (error.message.includes('ValidationError')) {
console.error('Invalid MEP ID format:', mepId);
} else if (error.message.includes('NotFoundError')) {
console.error('MEP not found:', mepId);
} else if (error.message.includes('RateLimitError')) {
console.error('Rate limit exceeded, retry later');
} else {
console.error('Unexpected error:', error.message);
}
}
return null;
}
}
5. Caching Strategy
// Implement client-side caching for frequently accessed data
class MEPCache {
private cache = new Map<string, { data: any, timestamp: number }>();
private readonly TTL = 15 * 60 * 1000; // 15 minutes
async getMEP(client: any, mepId: string) {
const cached = this.cache.get(mepId);
if (cached && Date.now() - cached.timestamp < this.TTL) {
return cached.data; // Return cached data
}
// Fetch fresh data
const result = await client.callTool('get_mep_details', { id: mepId });
const data = JSON.parse(result.content[0].text);
this.cache.set(mepId, { data, timestamp: Date.now() });
return data;
}
}
6. Date Range Queries
// Query data in manageable chunks
async function getVotesForYear(mepId: string, year: number) {
const months = [];
for (let month = 1; month <= 12; month++) {
const dateFrom = `${year}-${String(month).padStart(2, '0')}-01`;
const dateTo = `${year}-${String(month).padStart(2, '0')}-${getDaysInMonth(month, year)}`;
const result = await client.callTool('get_voting_records', {
mepId,
dateFrom,
dateTo,
limit: 100
});
months.push(JSON.parse(result.content[0].text));
}
return months;
}
โ ๏ธ Error Handling
Common Error Types
ValidationError
Cause: Invalid input parameters
Example:
{
"error": "ValidationError: country must match pattern ^[A-Z]{2}$"
}
Solution:
- Verify parameter format against schema
- Use ISO standard codes (country, language)
- Validate dates as YYYY-MM-DD
- Check min/max constraints
RateLimitError
Cause: Exceeded 100 requests per 15 minutes
Example:
{
"error": "RateLimitError: Rate limit exceeded, retry in 300 seconds"
}
Solution:
- Implement request throttling
- Use exponential backoff
- Cache frequently accessed data
- Batch requests when possible
NotFoundError
Cause: Resource doesn't exist
Example:
{
"error": "NotFoundError: MEP with ID 'MEP-999999' not found"
}
Solution:
- Verify ID exists using list tools first
- Handle 404 gracefully in application
- Provide user-friendly error messages
APIError
Cause: European Parliament API issues
Example:
{
"error": "APIError: Failed to fetch data from European Parliament API"
}
Solution:
- Implement retry logic with backoff
- Check EP API status
- Provide fallback behavior
- Log errors for monitoring
Error Handling Pattern
async function robustToolCall(toolName: string, params: any) {
try {
const result = await client.callTool(toolName, params);
return {
success: true,
data: JSON.parse(result.content[0].text)
};
} catch (error) {
if (error instanceof Error) {
// Log error details
console.error(`Tool ${toolName} failed:`, error.message);
// Categorize error
let errorType = 'UNKNOWN';
if (error.message.includes('ValidationError')) errorType = 'VALIDATION';
else if (error.message.includes('RateLimitError')) errorType = 'RATE_LIMIT';
else if (error.message.includes('NotFoundError')) errorType = 'NOT_FOUND';
else if (error.message.includes('APIError')) errorType = 'API_ERROR';
return {
success: false,
error: errorType,
message: error.message
};
}
return {
success: false,
error: 'UNKNOWN',
message: 'An unexpected error occurred'
};
}
}
๐ Security & Compliance
GDPR Compliance
Personal Data Handling:
- MEP contact information (email, phone) is public but must be handled responsibly
- Do not cache personal data longer than necessary (max 15 minutes)
- All data access is logged for audit purposes
- Support data subject rights (access, rectification, erasure)
Best Practices:
// Don't store MEP personal data long-term
const mep = await client.callTool('get_mep_details', { id: mepId });
// Use data immediately
displayMEPInfo(mep);
// Don't persist in database without explicit purpose
ISMS Policy References
This MCP server complies with:
- ISO 27001 A.12.4.1 - Event logging and monitoring
- NIST CSF 2.0 PR.DS-2 - Data-in-transit protection
- CIS Controls v8.1 3.3 - Data protection in transit
For complete security documentation, see SECURITY.md.
Rate Limiting
Limits:
- 100 requests per 15 minutes per IP address
- Applied per tool, not globally
- Shared across all MCP clients from same IP
Headers (when available):
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 85
X-RateLimit-Reset: 1640995200
๐ Hack23 Ecosystem Integration
This MCP server powers Hack23's political intelligence ecosystem โ disrupting journalism with AI-generated news coverage and real-time analysis of democratic governments.
How Hack23 Projects Use This Server
| Project | Integration | Use Case |
|---|---|---|
| EU Parliament Monitor | MCP tools + prompts | Automated MEP activity tracking, voting pattern dashboards, committee workload monitoring |
| Riksdagsmonitor (GitHub) | Riksdag MCP + this server | Cross-parliament comparison between EU and Swedish Parliament data |
| Citizen Intelligence Agency | Full OSINT tool suite | Comprehensive political intelligence analysis across institutions |
Example: Cross-Platform Intelligence Workflow
// Step 1: Get Swedish MEPs from EU Parliament
const swedishMEPs = await epClient.callTool('get_meps', { country: 'SE' });
// Step 2: Analyze Swedish delegation cohesion
const delegation = await epClient.callTool('analyze_country_delegation', { country: 'SE' });
// Step 3: Score individual MEP influence
const influence = await epClient.callTool('assess_mep_influence', { mepId: 'MEP-124810' });
// Step 4: Compare with riksdagsmonitor.com data for full picture
// โ Cross-reference EU voting patterns with national parliament positions
๐บ๏ธ Global Political OSINT MCP Landscape
The European Parliament MCP Server is the most feature-rich political MCP server in a growing global ecosystem of 35+ government and parliamentary open data MCP servers spanning 15+ countries.
Parliament-Specific MCP Servers
| Country | Server | Key Capabilities |
|---|---|---|
| ๐ช๐บ EU | European Parliament MCP | 62 tools โ MEP profiling, coalition analysis, anomaly detection, political landscape, longitudinal statistics |
| ๐บ๐ธ USA | Congress.gov API MCP | Bills, members, votes, committees |
| ๐ฌ๐ง UK | Parliament MCP | Hansard, members, debates, divisions |
| ๐ธ๐ช Sweden | Riksdag & Regering MCP | Parliament & government data |
| ๐ณ๐ฑ Netherlands | OpenTK MCP | Tweede Kamer documents |
| ๐ต๐ฑ Poland | Sejm MCP | Parliament data + legislation |
| ๐ฎ๐ฑ Israel | Knesset MCP | Knesset parliament API |
| ๐ง๐ท Brazil | Senado BR MCP | Federal Senate data |
Government Open Data MCP Servers
| Country | Server | Data Portal |
|---|---|---|
| ๐ซ๐ท France | data.gouv.fr MCP | data.gouv.fr |
| ๐ฎ๐ฑ Israel | Data.gov.il MCP | data.gov.il |
| ๐ฎ๐ณ India | Data.gov.in MCP | data.gov.in |
| ๐ธ๐ฌ Singapore | Gahmen MCP | data.gov.sg |
| ๐ฆ๐บ Australia | ABS MCP | abs.gov.au |
| ๐ Global | CKAN MCP Server | Any CKAN portal |
| ๐ Global | OpenGov MCP Server | Socrata portals |
๐ See README.md for the complete 35+ server directory with OSINT capability comparison.
๐ Additional Resources
Documentation
- Architecture Diagrams - Visual architecture and data flow
- Troubleshooting Guide - Common issues and solutions
- Developer Guide - Contributing and development
- Deployment Guide - Installation and configuration
- Performance Guide - Optimization strategies
External Resources
- MCP Specification - Protocol documentation
- European Parliament Open Data - Data source
- Hack23 ISMS Policies - Security standards
Hack23 Ecosystem
- Hack23 โ AI-powered democratic transparency platform
- EU Parliament Monitor โ European Parliament monitoring
- Riksdagsmonitor ยท GitHub โ Swedish Parliament monitoring
- Citizen Intelligence Agency โ Comprehensive political intelligence
๐ค Support
Issues & Questions:
Security Issues:
- See SECURITY.md for vulnerability reporting
๐ Cancelling Requests with abortSignal
Every public method on the typed EP clients accepts an optional
abortSignal?: AbortSignal field that is forwarded to the underlying
fetch call. Use it to cancel long-running requests pre-emptively โ for
example, when a parent deadline expires or a user navigates away.
import { epClient } from '@hack23/european-parliament-mcp-server';
const controller = new AbortController();
setTimeout(() => controller.abort(new Error('5s budget')), 5_000);
try {
const procedures = await epClient.getProcedures({
limit: 100,
abortSignal: controller.signal,
});
// โฆuse procedures
} catch (err) {
// APIError with statusCode === 0 indicates a cancellation
if ((err as { statusCode?: number }).statusCode === 0) {
console.log('Request was cancelled');
} else {
throw err;
}
}
Semantics:
- Signal already aborted when the call starts โ rejects immediately with
APIError(0)and no HTTP request is issued (rate-limit token preserved). - Signal aborts mid-flight โ underlying
fetchis cancelled and the call rejects withAPIError(0, { cause: signal.reason }). - Signal omitted โ behaviour is identical to all prior client versions.
- Aborted requests are never retried even when
enableRetry: true.
The same parameter is accepted by every public method on
EuropeanParliamentClient (getMEPs, getProcedures, getAdoptedTexts,
getCommitteeDocuments, getParliamentaryQuestions, the *Feed helpers,
the *ById helpers, etc.) and by doceoClient.getLatestVotes.
Built with โค๏ธ by Hack23 AB
ISMS-compliant open source demonstrating security excellence