API Usage Guide

July 10, 2026 ยท View on GitHub

Hack23 Logo

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

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

ToolPurposeKey ParametersResponse Type
get_mepsList MEPs with filterscountry, group, committeePaginated list
get_mep_detailsMEP detailsidSingle object
get_current_mepsCurrently active MEPslimit, offsetPaginated list
get_incoming_mepsNewly arriving MEPslimit, offsetPaginated list
get_outgoing_mepsDeparting MEPslimit, offsetPaginated list
get_homonym_mepsMEPs with identical nameslimit, offsetPaginated list
get_mep_declarationsMEP financial declarationsdocId, yearPaginated list

๐Ÿ›๏ธ Plenary & Meeting Tools

ToolPurposeKey ParametersResponse TypeNotes
get_plenary_sessionsList plenary sessionsdateFrom, dateTo, eventId, year, locationPaginated listโœ… Fast with year filter
get_voting_recordsAggregate voting datasessionId, topic, dateFromPaginated listโš ๏ธ Roll-call data delayed by weeks
get_latest_votesNear-real-time DOCEO vote datadate, weekStart, term, includeIndividualVotesVote recordsโœ… Hours fresh โ€” RCV preferred; falls back to VOT
get_speechesPlenary speechesspeechId, year, dateFrom, dateToPaginated list
get_eventsEP eventseventId, limit, offsetPaginated listโš ๏ธ No date filtering
get_meeting_activitiesMeeting activitiessittingId (required)Paginated listโœ… Works with session IDs like MTG-PL-2025-01-20
get_meeting_decisionsMeeting decisionssittingId (required)Paginated listโœ… Works with session IDs
get_meeting_foreseen_activitiesPlanned agenda itemssittingId (required)Paginated listโœ… Works with session IDs
get_meeting_plenary_session_documentsMeeting session documentssittingId (required)Paginated listโš ๏ธ Returns 404 for many sittingIds
get_meeting_plenary_session_document_itemsMeeting session doc itemssittingId (required)Paginated listโš ๏ธ Returns 404 for many sittingIds

๐Ÿข Committee Tools

ToolPurposeKey ParametersResponse Type
get_committee_infoCommittee dataid, abbreviation, showCurrentSingle object
get_committee_documentsCommittee documentsdocId, yearPaginated list

๐Ÿ“„ Document Tools

ToolPurposeKey ParametersResponse TypeNotes
search_documentsFind documentskeyword, documentType, dateFrom, dateToPaginated listโš ๏ธ Always use date filters โ€” unfiltered searches time out
get_adopted_textsAdopted textsdocId, yearPaginated listโœ… Fast with year filter
get_plenary_documentsPlenary documentsdocId, yearPaginated listโœ… Fast with year filter
get_plenary_session_documentsSession documentsdocIdPaginated list
get_plenary_session_document_itemsSession document itemslimit, offsetPaginated listโš ๏ธ EP API returns 404 โ€” endpoint may require specific parameters
get_external_documentsExternal documentsdocId, yearPaginated listโœ… Fast with year filter
get_parliamentary_questionsQ&A datadocId, type, author, topic, status, dateFromPaginated list

โš–๏ธ Legislative Procedure Tools

ToolPurposeKey ParametersResponse TypeNotes
get_proceduresLegislative proceduresprocessId, yearPaginated listโš ๏ธ Use year filter โ€” unfiltered queries may time out
get_procedure_eventsProcedure timeline eventsprocessId (required)Paginated listUse short processId (e.g., 2025-0012), not full URI
get_procedure_event_by_idSingle procedure eventprocessId, eventId (both required)Single objectUse short IDs for both parameters
get_controlled_vocabulariesClassification termsvocIdPaginated listโœ… Fast; use short vocId (e.g., ep-document-types)

๐Ÿ“Š Advanced Analysis Tools

ToolPurposeKey ParametersResponse Type
analyze_voting_patternsVoting analysismepId, dateFromAnalysis object
track_legislationTrack procedureprocedureIdProcedure object
generate_reportCreate reportsreportType, subjectIdReport object
get_all_generated_statsPrecomputed EP stats (2004-2026) + 30 OSINT metricsyearFrom, yearTo, categoryStatistics object

๐Ÿ•ต๏ธ OSINT Intelligence Tools

ToolPurposeKey ParametersResponse Type
assess_mep_influenceMEP influence scoringmepId (required), includeDetailsInfluence scorecard
analyze_coalition_dynamicsCoalition cohesion analysisgroupIds, dateFrom, minimumCohesionCoalition metrics
detect_voting_anomaliesAnomaly detectionmepId, groupId, sensitivityThresholdAnomaly report
compare_political_groupsCross-group comparisongroupIds (required), dimensionsComparison matrix
analyze_legislative_effectivenessLegislative scoringsubjectType (required), subjectId (required)Effectiveness score
monitor_legislative_pipelinePipeline monitoringcommittee, status, limitPipeline status
analyze_committee_activityCommittee workload & engagementcommitteeId (required)Activity report
track_mep_attendanceMEP attendance patternsmepId, country, groupId, limitAttendance report
analyze_country_delegationCountry delegation analysiscountry (required)Delegation analysis
generate_political_landscapeParliament-wide landscapedateFrom, dateToLandscape overview
network_analysisMEP relationship network mappingmepId, analysisType, depthNetwork metrics
sentiment_trackerPolitical group positioning scoresgroupId, timeframeSentiment report
early_warning_systemDetect emerging political shiftssensitivity, focusAreaWarning alerts
comparative_intelligenceCross-reference MEP activitiesmepIds (required), dimensionsComparison matrix
correlate_intelligenceCross-tool OSINT correlationmepIds (required), groups, sensitivityLevelIntelligence alerts

๐Ÿ“ก Feed Tools

EP API v2 feed endpoints fall into two groups per the OpenAPI spec:

Configurable-window feeds (accept timeframe + startDate):

ToolPurposeKey ParametersResponse TypeTested Response Time
get_meps_feedRecently updated MEPstimeframe, startDateFeed list~9 s
get_events_feedRecently updated eventstimeframe, startDate, activityTypeFeed list30โ€“120 s โš ๏ธ
get_procedures_feedRecently updated procedurestimeframe, startDate, processTypeFeed list30โ€“120 s โš ๏ธ
get_adopted_texts_feedRecently updated adopted textstimeframe, startDate, workTypeFeed list~1 s โœ…
get_mep_declarations_feedRecently updated MEP declarationstimeframe, startDate, workTypeFeed list~1 s โœ…
get_external_documents_feedRecently updated external documentstimeframe, startDate, workTypeFeed list~1 s โœ…

Fixed-window feeds (no parameters โ€” server-defined default window, typically one month):

ToolPurposeKey ParametersResponse TypeTested Response Time
get_documents_feedRecently updated documents(none)Feed list60โ€“120+ s โš ๏ธ
get_plenary_documents_feedRecently updated plenary documents(none)Feed list30โ€“120+ s โš ๏ธ
get_committee_documents_feedRecently updated committee documents(none)Feed list30โ€“120+ s โš ๏ธ
get_plenary_session_documents_feedRecently updated plenary session docs(none)Feed list20โ€“120+ s โš ๏ธ
get_parliamentary_questions_feedRecently updated questions(none)Feed list30โ€“120+ s โš ๏ธ
get_corporate_bodies_feedRecently updated corporate bodies(none)Feed list60โ€“180+ s โš ๏ธ
get_controlled_vocabularies_feedRecently updated vocabularies(none)Feed listReturns 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 180000 for 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 with error field) 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 timeframe or startDate will 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_meps tool uses the EP API /meps endpoint which supports server-side filtering but does not return country or politicalGroup in responses. Results will show country: "Unknown" and politicalGroup: "Unknown". For country and political group data, use get_current_meps instead. All OSINT intelligence tools automatically use get_current_meps for accurate MEP metadata.

Parameters

ParameterTypeRequiredDefaultDescription
countrystringNo-ISO 3166-1 alpha-2 country code (e.g., "SE", "FR", "DE")
groupstringNo-Political group identifier (e.g., "EPP", "S&D", "Greens/EFA")
committeestringNo-Committee identifier (e.g., "ENVI", "AGRI")
activebooleanNotrueFilter by active status
limitnumberNo50Maximum results (1-100)
offsetnumberNo0Pagination 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

ErrorCauseSolution
ValidationError: countryInvalid country code formatUse 2-letter ISO code (e.g., "SE" not "Sweden")
RateLimitErrorToo many requestsWait 15 minutes or implement request throttling
APIError: 500European Parliament API downCheck EP API status, implement retry logic

Use Cases

  1. Find MEPs by Country: Filter by country code to get national delegation
  2. Political Group Analysis: List all members of a specific political group
  3. Committee Membership: Find MEPs serving on specific committees
  4. Pagination: Use limit and offset for 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

ParameterTypeRequiredDefaultDescription
idstringYes-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

ErrorCauseSolution
ValidationError: id requiredMissing ID parameterProvide MEP ID (get from get_meps)
NotFoundErrorInvalid MEP IDVerify ID exists in get_meps results
ValidationError: id formatEmpty or invalid ID formatUse non-empty string ID

Use Cases

  1. MEP Profile: Get complete EP biographical information for profile pages
  2. Mandate History: Inspect parliamentary terms and represented countries
  3. Committee Work: Resolve assignments from membership classifications
  4. 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

ParameterTypeRequiredDefaultDescription
eventIdstringNo-Meeting event ID for single meeting lookup
yearnumberNo-Filter by calendar year (1900-2100, recommended for annual counts)
dateFromstringNo-Start date (YYYY-MM-DD format)
dateTostringNo-End date (YYYY-MM-DD format)
locationstringNo-Session location (e.g., "Strasbourg", "Brussels")
limitnumberNo50Maximum results (1-100)
offsetnumberNo0Pagination offset

Note: dateFrom must be โ‰ค dateTo when 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

ErrorCauseSolution
ValidationError: dateFromInvalid date formatUse YYYY-MM-DD format
ValidationError: dateTo before dateFromDate range invalidEnsure dateTo >= dateFrom

Use Cases

  1. Session Calendar: List upcoming plenary sessions
  2. Historical Analysis: Query past sessions by date range
  3. 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

ParameterTypeRequiredDefaultDescription
sessionIdstringNo-Filter by plenary session
topicstringNo-Filter by topic/keyword
dateFromstringNo-Start date (YYYY-MM-DD)
dateTostringNo-End date (YYYY-MM-DD)
limitnumberNo50Maximum results (1-100)
offsetnumberNo0Pagination 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

  1. Topic Analysis: Find all votes on specific topics
  2. Session Votes: Get all votes from a plenary session
  3. 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_stats enrichment: When includeRankings=true, get_all_generated_stats also 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 missing recentVoteActivity in that case.

โš ๏ธ analyze_coalition_dynamics enrichment: Coalition cohesion scores are enriched with DOCEO RCV group-breakdown data (bounded 3s timeout, cached 5 minutes). If DOCEO is unavailable, cohesion falls back to null and dataFreshness will indicate no DOCEO data was used.

Parameters

ParameterTypeRequiredDefaultDescription
datestringNo-Specific date (YYYY-MM-DD, real calendar date). Mutually exclusive with weekStart.
weekStartstringNo-Monday date of a specific plenary week (YYYY-MM-DD). Mutually exclusive with date. Fetches Monโ€“Thu of that week.
termnumberNo10Parliamentary term (1โ€“15; default 10 = 2024โ€“2029 term)
includeIndividualVotesbooleanNotrueInclude individual MEP vote positions from RCV data
limitnumberNo50Maximum vote records to return (1โ€“100)
offsetnumberNo0Pagination offset (โ‰ฅ 0)

Mutual exclusivity: Passing both date and weekStart simultaneously is a validation error. Calendar date enforcement: Both date and weekStart must be real calendar dates (e.g., 2026-13-40 is rejected). weekStart must 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

ErrorCauseSolution
Invalid parameters: date: date must be a valid calendar dateDate 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 MondayThe weekStart date is valid but falls on a non-MondayUse the Monday of the desired plenary week
Invalid parameters: weekStart: date and weekStart are mutually exclusiveBoth date and weekStart were providedProvide only one, or omit both for the most recent plenary week
Failed to retrieve latest votes from DOCEODOCEO upstream network error or document not yet publishedThe documents may not be published yet; retry later

Use Cases

  1. Near-Real-Time Vote Monitoring: Get vote results within hours of plenary sessions
  2. Group Cohesion Analysis: Use groupBreakdown to compare how political groups voted
  3. MEP Position Tracking: With includeIndividualVotes: true, trace each MEP's vote
  4. Historical Week Lookup: Use weekStart (must be a Monday) to fetch an entire plenary week
  5. Coalition Intelligence: Feed vote data into analyze_coalition_dynamics for enriched cohesion scores

Tool: search_documents

Description: Search European Parliament legislative documents with keyword and type filters.

Parameters

ParameterTypeRequiredDefaultDescription
docIdstringNo-Document ID for single document lookup (bypasses keyword search)
keywordstringNo-Search keyword or phrase (alphanumeric, spaces, hyphens, underscores)
documentTypestringNo-Document type: REPORT, RESOLUTION, DECISION, DIRECTIVE, REGULATION, OPINION, AMENDMENT
dateFromstringNo-Start date (YYYY-MM-DD)
dateTostringNo-End date (YYYY-MM-DD)
committeestringNo-Committee identifier
limitnumberNo20Maximum results (1-100)
offsetnumberNo0Pagination offset

Note: Provide docId for single document lookup, or keyword for 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

ErrorCauseSolution
ValidationError: keywordInvalid charactersUse only alphanumeric, spaces, hyphens, underscores
SearchError: missing search parametersNeither keyword nor docId providedProvide a search term or use docId for direct lookup

Use Cases

  1. Legislative Research: Find documents on specific topics
  2. Committee Work: Search documents by committee
  3. 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

ParameterTypeRequiredDefaultDescription
idstringNo*-Committee identifier
abbreviationstringNo*-Committee abbreviation (e.g., "ENVI", "AGRI")
showCurrentbooleanNofalseIf 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

  1. Committee Overview: Get committee structure and leadership
  2. Member Lookup: Find MEPs serving on specific committees
  3. 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

ParameterTypeRequiredDefaultDescription
docIdstringNo-Document ID for single question lookup (e.g., "E-000001/2024")
typestringNo-Question type: WRITTEN or ORAL
authorstringNo-MEP identifier or name of question author
topicstringNo-Question topic or keyword to search
statusstringNo-Question status: PENDING or ANSWERED
dateFromstringNo-Start date (YYYY-MM-DD)
dateTostringNo-End date (YYYY-MM-DD)
limitnumberNo50Maximum results (1-100)
offsetnumberNo0Pagination offset

Note: dateFrom must be โ‰ค dateTo when 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

  1. MEP Accountability: Track questions from specific MEPs
  2. Topic Research: Find questions on specific policy areas
  3. 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

ParameterTypeRequiredDefaultDescription
mepIdstringYes-MEP identifier to analyze
dateFromstringNo-Analysis start date (YYYY-MM-DD)
dateTostringNo-Analysis end date (YYYY-MM-DD)
compareWithGroupbooleanNotrueCompare 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

  1. MEP Performance: Analyze attendance and voting activity
  2. Political Alignment: Compare MEP votes with party line
  3. Cross-Party Analysis: Identify bipartisan voting patterns
  4. 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

ParameterTypeRequiredDefaultDescription
procedureIdstringYes-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

  1. Legislation Monitoring: Track bill progress through Parliament
  2. Timeline Analysis: View complete legislative timeline
  3. Amendment Tracking: Monitor proposed and adopted amendments
  4. 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

ParameterTypeRequiredDefaultDescription
reportTypestringYes-Report type: MEP_ACTIVITY, COMMITTEE_PERFORMANCE, VOTING_STATISTICS, LEGISLATION_PROGRESS
subjectIdstringNo-Subject identifier (MEP ID, Committee ID) - optional for aggregate reports
dateFromstringNo-Report period start (YYYY-MM-DD)
dateTostringNo-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

  1. MEP_ACTIVITY: Individual MEP performance and activity

    • Voting participation and statistics
    • Committee involvement
    • Parliamentary questions submitted
    • Reports authored
  2. COMMITTEE_PERFORMANCE: Committee productivity analysis

    • Meeting frequency
    • Legislative output
    • Member participation rates
  3. VOTING_STATISTICS: Parliament-wide voting analysis

    • Overall voting activity
    • Adoption rates
    • Political group alignment patterns
  4. LEGISLATION_PROGRESS: Legislative activity overview

    • New proposals submitted
    • Completed procedures
    • Ongoing procedures and timelines

Use Cases

  1. Performance Review: Generate MEP activity reports
  2. Committee Analysis: Assess committee productivity
  3. Statistical Analysis: Parliament-wide voting trends
  4. 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

ParameterTypeRequiredDefaultDescription
mepIdstringYes-MEP identifier
dateFromstringNo-Start date (YYYY-MM-DD)
dateTostringNo-End date (YYYY-MM-DD)
includeDetailsbooleanNofalseInclude 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 valueMeaning
EP_APIOnly the EP Open Data MEPDetails.votingStatistics placeholder was available (typically zeros).
DOCEOPer-MEP roll-call vote (RCV) data was aggregated from DOCEO XML; no EP API stats merged.
EP_API+DOCEODOCEO 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

ParameterTypeRequiredDefaultDescription
groupIdsstring[]No-Political group identifiers to analyze (omit for all groups, 1-10 items)
dateFromstringNo-Analysis start date (YYYY-MM-DD)
dateTostringNo-Analysis end date (YYYY-MM-DD)
minimumCohesionnumberNo0.5Minimum 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

ParameterTypeRequiredDefaultDescription
mepIdstringNo-MEP identifier (omit for broad analysis)
groupIdstringNo-Political group to analyze
dateFromstringNo-Analysis start date (YYYY-MM-DD)
dateTostringNo-Analysis end date (YYYY-MM-DD)
sensitivityThresholdnumberNo0.3Anomaly 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 mepId and groupId โ€” 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 TypeTrigger
PARTY_DEFECTIONWeekly defection-rate z-score โ‰ฅ 1.5 vs MEP's own baseline
ABSTENTION_SPIKEWeekly abstention-rate z-score โ‰ฅ 1.5 vs MEP's own baseline
ALIGNMENT_SHIFTWeek-over-week defection-rate increase โ‰ฅ 20 percentage points
CROSS_PARTY_ALIGNMENT_SHIFTMEP 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:

  • HIGH for โ‰ฅ 50 RCVs inspected AND โ‰ฅ 3 distinct plenary weeks contributing votes
  • MEDIUM for 10โ€“49 RCVs, or โ‰ฅ50 RCVs but < 3 contributing weeks (no multi-week dispersion)
  • LOW for < 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

ParameterTypeRequiredDefaultDescription
groupIdsstring[]Yes-Political group identifiers to compare (minimum 2, maximum 10)
dateFromstringNo-Analysis start date (YYYY-MM-DD)
dateTostringNo-Analysis end date (YYYY-MM-DD)
dimensionsstring[]NoallComparison 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

ParameterTypeRequiredDescription
subjectTypestringYesSubject type: MEP or COMMITTEE
subjectIdstringYesSubject identifier (MEP ID, e.g. person/124810, or committee abbreviation, e.g. IMCO)
dateFromstringNoStart date (YYYY-MM-DD). Defaults to 1 January of the current year.
dateTostringNoEnd date (YYYY-MM-DD). Defaults to today.

Data Sources

SourceEP EndpointPopulatesPer-source budget
procedures/proceduresmetrics.reportsAuthored, metrics.opinionsDelivered (rapporteur attribution) โ€” paginated up to 5 pages (โ‰ค 1000 items); a dataQualityWarnings entry is emitted when truncated6 s
adoptedTexts/adopted-textsmetrics.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 fetch6 s
plenaryDocumentItems/plenary-session-documents-itemsmetrics.amendmentsTabled, metrics.amendmentsAdopted (author + status flag)6 s
questions/parliamentary-questionsmetrics.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 whose rapporteur field names the subject MEP (case-insensitive substring match against the normalised person/{id} and bare-id tokens) and that lacks a shadow / opinion qualifier in the same field.
  • opinionsDelivered โ€” procedures where the same author match exists and the rapporteur field carries a shadow / opinion qualifier.
  • amendmentsTabled / amendmentsAdopted โ€” plenary-session document items whose type includes AMENDMENT, whose authors[] contains the subject's id, and (for Adopted) whose status includes ADOPTED.
  • legislativeSuccessRate = 100 ร— procedures-with-adopted-text / attributed-procedures. The numerator counts procedures whose reference (or id) appears as procedureReference in any /adopted-texts item within the date window. The denominator counts the union of reportsAuthored and opinionsDelivered procedure IDs (no double-counting).
  • questionsAsked โ€” /parliamentary-questions filtered upstream by author={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-bodies and 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 attributions is sorted ascending by stable procedureId / documentId / questionId, so repeated runs over the same input produce byte-identical output.

Computed Attributes

  • amendmentSuccessRate = 100 ร— amendmentsAdopted / amendmentsTabled
  • legislativeOutputPerMonth = (reportsAuthored + amendmentsTabled) / months-in-window
  • peerComparisonPercentile โ€” heuristic; refined when corpus benchmarks become available.
  • effectivenessRank โ€” HIGHLY_EFFECTIVE (โ‰ฅ70), EFFECTIVE (โ‰ฅ50), MODERATE (โ‰ฅ30), or DEVELOPING otherwise.

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

ParameterTypeRequiredDefaultDescription
committeestringNo-Filter by committee
statusstringNoACTIVEPipeline status filter: ALL, ACTIVE, STALLED, COMPLETED
dateFromstringNo-Analysis start date (YYYY-MM-DD)
dateTostringNo-Analysis end date (YYYY-MM-DD)
limitnumberNo20Maximum results to return (1-100)

Methodology

  • daysInCurrentStage โ€” precise delta in days between the most recent event from /procedures/{id}/events and now. 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 โ‰ฅ median
    • LOW โ€” otherwise
  • bottlenecks[] โ€” aggregated only from procedures whose dwell is โ‰ฅ the historical 95th percentile (or the legacy isStalled heuristic when no statistics exist). Each entry exposes the thresholdDays used.
  • 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 reports forecastBasis: '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

ParameterTypeRequiredDescription
committeeIdstringYesCommittee identifier (e.g., "ENVI", "ITRE")
dateFromstringNoStart date (YYYY-MM-DD). Defaults to trailing 6 months.
dateTostringNoEnd date (YYYY-MM-DD). Defaults to today.

Data Sources

SourceEP EndpointPopulatesPer-source budget
documents/committee-documentsworkload.documentsProduced5 s
procedures/proceduresworkload.activeLegislativeFiles5 s
meetings/meetingsworkload.meetingsHeld5 s
decisions/meetings/{id}/decisions (fan-out, capped at 8 sittings)workload.decisionsAdopted5 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 / meetingsHeld
  • documentsPerMonth = documentsProduced / windowMonths
  • activeFilesPerMember = 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

ParameterTypeRequiredDescription
mepIdstringNoMEP identifier for individual attendance analysis
countrystringNoISO 3166-1 alpha-2 country code for delegation overview
groupIdstringNoPolitical group identifier for group-level overview
limitnumberNoMaximum number of MEPs to include in overview queries
dateFromstringNoStart date (ISO 8601)
dateTostringNoEnd 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

ParameterTypeRequiredDescription
countrystringYesISO 3166-1 alpha-2 country code (e.g., "SE", "DE", "FR")
dateFromstringNoStart date (ISO 8601)
dateTostringNoEnd 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

ParameterTypeRequiredDescription
dateFromstringNoStart date (ISO 8601)
dateTostringNoEnd date (ISO 8601)

Confidence Levels

confidenceLevelTriggerInterpretation
HIGHFull pagination complete and totalMEPs โ‰ฅ 600Roster covers the full EP10 Parliament
MEDIUMFull pagination complete and 200 โ‰ค totalMEPs < 600Roster is representative but partial term coverage
LOWPagination failed (MEP pagination failed at offset N warning) or totalMEPs < 200Treat 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 show totalMEPs: 100 and the same group split across multiple acronyms (e.g. PPE and EPP as 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

ParameterTypeRequiredDefaultDescription
mepIdnumberNo-Focus on ego network for a specific MEP (enables BFS depth limit)
analysisTypestringNocombinedcommittee (shared-committee edges only), voting (DOCEO RCV similarity), or combined (mean of the two normalised weights)
depthnumberNo2BFS traversal depth (1-3 hops); applied to the ego network when mepId is provided
minSimilaritynumberNo0.7Minimum 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 via 1 / weight).
  • centralityScore โ€” composite 0.6 ร— weightedDegree + 0.4 ร— 100 ร— betweennessCentrality rounded to 2dp.
  • modularityScore โ€” Newman Q for the label-propagation partition (>0.3 indicates 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

ParameterTypeRequiredDefaultDescription
groupIdstringNo-Political group identifier (e.g., "EPP", "S&D"). Omit for all groups
timeframestringNolast_quarterDOCEO 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 โ€” IMPROVING when latest-half mean > earliest-half mean + 0.05, DECLINING when below by 0.05, otherwise STABLE. VOLATILE when 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.subject values 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

ParameterTypeRequiredDefaultDescription
sensitivitystringNomediumDetection sensitivity: low, medium, or high
focusAreastringNoallFocus 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

ParameterTypeRequiredDefaultDescription
mepIdsarray of numbersYes-List of 2-10 MEP identifiers to compare
dimensionsarray of stringsNoallDimensions 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

ParameterTypeRequiredDefaultDescription
mepIdsarray of stringsYes-MEP identifiers to cross-correlate (minimum 1, maximum 5)
groupsarray of stringsNo-Political groups for coalition fracture analysis (max 8, omit to use all major groups)
sensitivityLevelstringNoMEDIUMAlert sensitivity: HIGH, MEDIUM, or LOW โ€” HIGH surfaces more signals, LOW reduces noise
includeNetworkAnalysisbooleanNofalseRun 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

ParameterTypeRequiredDefaultDescription
limitnumberNo50Maximum results (1-100)
offsetnumberNo0Pagination 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

ParameterTypeRequiredDefaultDescription
limitnumberNo50Maximum results (1-100)
offsetnumberNo0Pagination 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

ParameterTypeRequiredDefaultDescription
limitnumberNo50Maximum results (1-100)
offsetnumberNo0Pagination 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

ParameterTypeRequiredDefaultDescription
limitnumberNo50Maximum results (1-100)
offsetnumberNo0Pagination 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

ParameterTypeRequiredDefaultDescription
speechIdstringNo-Specific speech ID for single lookup
yearnumberNo-Filter by calendar year (1900-2100, recommended for annual counts)
dateFromstringNo-Start date filter (YYYY-MM-DD)
dateTostringNo-End date filter (YYYY-MM-DD)
limitnumberNo50Maximum results (1-100)
offsetnumberNo0Pagination 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 year filter or processId when querying procedures. Unfiltered queries can take 60+ seconds and may time out with the default 60s timeout.

Parameters

ParameterTypeRequiredDefaultDescription
processIdstringNo-Specific procedure ID (YYYY-NNNN format) for single lookup
yearnumberNo-Filter by year
limitnumberNo50Maximum results (1-100)
offsetnumberNo0Pagination 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 by get_procedures for best results.

Parameters

ParameterTypeRequiredDefaultDescription
processIdstringYes-Procedure process ID (e.g., eli/dl/proc/2024-0006 or 2024-0006)
limitnumberNo50Maximum results (1-100)
offsetnumberNo0Pagination 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

ParameterTypeRequiredDefaultDescription
docIdstringNo-Specific document ID for single lookup
yearnumberNo-Filter by year
limitnumberNo50Maximum results (1-100)
offsetnumberNo0Pagination 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

ParameterTypeRequiredDefaultDescription
eventIdstringNo-Specific event ID for single lookup
limitnumberNo50Maximum results (1-100)
offsetnumberNo0Pagination 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

ParameterTypeRequiredDefaultDescription
sittingIdstringYes-Plenary sitting ID
limitnumberNo20Maximum results (1-100). Default 20 โ€” activities endpoint can be slow
offsetnumberNo0Pagination 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

ParameterTypeRequiredDefaultDescription
sittingIdstringYes-Plenary sitting ID
limitnumberNo50Maximum results (1-100)
offsetnumberNo0Pagination 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

ParameterTypeRequiredDefaultDescription
sittingIdstringYes-Plenary sitting ID
limitnumberNo20Maximum results (1-100). Default 20 โ€” foreseen-activities endpoint can be slow
offsetnumberNo0Pagination 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

ParameterTypeRequiredDefaultDescription
sittingIdstringYes-Meeting / sitting identifier
limitnumberNo20Maximum results (1-100). Default 20 โ€” plenary-session-documents endpoint can be slow
offsetnumberNo0Pagination 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

ParameterTypeRequiredDefaultDescription
sittingIdstringYes-Meeting / sitting identifier
limitnumberNo20Maximum results (1-100). Default 20 โ€” plenary-session-document-items endpoint can be slow
offsetnumberNo0Pagination 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

ParameterTypeRequiredDefaultDescription
docIdstringNo-Specific declaration document ID for single lookup
yearnumberNo-Filter by year
limitnumberNo50Maximum results (1-100)
offsetnumberNo0Pagination 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

ParameterTypeRequiredDefaultDescription
docIdstringNo-Specific document ID for single lookup
yearnumberNo-Filter by year
limitnumberNo50Maximum results (1-100)
offsetnumberNo0Pagination 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

ParameterTypeRequiredDefaultDescription
docIdstringNo-Specific document ID for single lookup
yearnumberNo-Filter by year
limitnumberNo50Maximum results (1-100)
offsetnumberNo0Pagination 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

ParameterTypeRequiredDefaultDescription
docIdstringNo-Specific document ID for single lookup
limitnumberNo50Maximum results (1-100)
offsetnumberNo0Pagination 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

ParameterTypeRequiredDefaultDescription
limitnumberNo50Maximum results (1-100)
offsetnumberNo0Pagination 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

ParameterTypeRequiredDefaultDescription
vocIdstringNo-Specific vocabulary ID for single lookup (e.g., ep-document-types)
limitnumberNo50Maximum results (1-100)
offsetnumberNo0Pagination offset

Note: The vocId parameter 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:

IdentifierLabelDescription
TEXT_ADOPTEDText adoptedText adopted by a vote in plenary
REPORTReportA report document
REPORT_PLENARYEP plenary reportReport for plenary debate/vote
REPORT_OWN_INITIATIVEOwn initiative reportText drawn up on Parliament's own initiative
RESOLUTIONResolutionText expressing opinion on a matter/topic
RESOLUTION_LEGISLATIVELegislative resolutionLegislative resolution text
RESOLUTION_MOTIONMotion for a resolutionMotion declaring EP's opinion
RESOLUTION_MOTION_JOINTJoint motion for a resolutionJoint motion from multiple groups
OPINIONOpinionNon-binding institutional statement
OPINION_PARLIAMENTARY_COMMITTEEParliamentary committee opinionCommittee opinion with amendments
AMENDMENTAmendmentChange to original text
AMENDMENT_PLENARYEP plenary amendmentAmendment tabled to plenary
CRE_PLENARYEP plenary verbatim reportPlenary sitting proceedings record
CRE_SPEECHSpeechIndividual speech in proceedings
MINUTES_PLENARYEP plenary sitting minutesWritten meeting record
QUESTION_WRITTENWritten questionWritten form question
QUESTION_ORALOral questionOral question to plenary
QUESTION_WRITTEN_ANSWERWritten answerAnswer to written question
MEMBER_DECLARATIONMembers' declarationMEP code of conduct declaration
MEMBER_DECLARATION_INTEREST_PRIVATEDeclaration of private interestsMEP private interests declaration
MEMBER_DECLARATION_INTEREST_CONFLICTDeclaration on conflicts of interestMEP conflict of interest declaration
DIRECTIVEDirectiveEU legislative act (goals for member states)
REGULATIONRegulationBinding legislative act (EU-wide)
DECISIONDecisionBinding act for specific addressees
ACT_FOLLOWUPFollow-up of actsCommission follow-up document
AGENDA_PLENARY_WEEKEP plenary part-session agendaPlenary session agenda
VOTE_ROLLCALL_PLENARYEP plenary roll-call votesRoll-call vote results
VOTE_RESULTS_PLENARYEP plenary vote resultsVote results record
ANNEXAnnexAppended document section
CORRIGENDUMCorrigendumCorrections document
Activity Types (ep-activities) โ€” 70 terms

Key activity type identifiers used in events and procedure events:

IdentifierLabel
PLENARY_SESSIONEuropean Parliament plenary session
PLENARY_SITTINGEuropean Parliament plenary sitting
PLENARY_DEBATEDebates in plenary sitting
PLENARY_VOTEVote in plenary sitting
PLENARY_ADOPT_POSITIONEP position at 1st reading
PLENARY_AMEND_PROPOSALEP position at 1st reading with amendments
PLENARY_APPROVE_COUNCIL_POSITIONApproval of Council's position at 2nd reading
PLENARY_REJECT_PROPOSALPlenary reject proposal
PLENARY_DECISIONEP decision
COMMITTEE_MEETINGCommittee meeting
COMMITTEE_ADOPTING_REPORTAdoption of report by committee
COMMITTEE_APPOINT_RAPPORTEURAppointment of rapporteur
COMMITTEE_DEBATEDeliberations in committee
COMMITTEE_VOTECommittee vote
REFERRALProposal referred to plenary
INTERINSTITUTIONAL_NEGOTIATIONInterinstitutional negotiation (trilogue)
PUBLICATION_OFFICIAL_JOURNALPublication in Official Journal
SIGNATURESignature
PROCEEDING_ACTIVITYProceeding activity
Procedure Types (ep-procedure-types) โ€” 40+ terms

Key legislative procedure type identifiers:

IdentifierLabelDescription
CODOrdinary legislative procedureMain EU legislative process (co-decision)
CNSConsultation procedureCouncil consults Parliament
APPConsent procedureParliament must give consent
NLENon-legislative procedureNon-legislative enactment
BUDBudgetary procedureEU budget process
DECDischarge procedureBudget discharge
INIOwn-initiative procedureParliament's own initiative
INLLegislative initiative procedureParliament's legislative initiative
INSInstitutional procedureInstitutional matters
IMMMembers' immunityImmunity proceedings
DEADelegated actsExamination of delegated acts
RSPResolutions on topical subjectsTopical resolutions
Statuses (ep-statuses) โ€” 24 terms
IdentifierLabel
ACTIVEActive
ACTIVE_PROCActive procedure
ADOPTEDAdopted
CANCELLEDCancelled
COMPLETEDCompleted
COMPLETED_PROCCompleted procedure
LAPSEDLapsed
PENDINGPending
REJECTEDRejected
SUBMITTEDSubmitted
WITHDRAWNWithdrawn
WITHDRAWN_PROCWithdrawn 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

ParameterTypeRequiredDefaultDescription
docIdstringNo-Specific document ID for single lookup
yearnumberNo-Filter by year
limitnumberNo50Maximum results (1-100)
offsetnumberNo0Pagination 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

ParameterTypeRequiredDefaultDescription
processIdstringYes-Legislative procedure identifier (e.g., "2024-0006")
eventIdstringYes-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

ParameterTypeRequiredDefaultDescription
yearFromnumberNo2004Start year for filtering (2004โ€“2031)
yearTonumberNo2026End year for filtering (2004โ€“2031)
categorystringNoallActivity 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
includePredictionsbooleanNotrueInclude trend-based predictions for 2027โ€“2031
includeMonthlyBreakdownbooleanNofalseInclude month-by-month activity data
includeRankingsbooleanNotrueInclude 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:

FieldDescription
coveragePeriodUnderlying dataset range (always { from: 2004, to: 2026 })
requestedPeriodUser-supplied year filter ({ from: yearFrom, to: yearTo })
yearlyStatsAnnual statistics per year with 13 activity metrics, political landscape, and derived intelligence
yearlyStats[].derivedIntelligence30 OSINT metrics: legislative efficiency, engagement, concentration, 3-axis political compass, stability, YoY dynamics
yearlyStats[].politicalLandscapeGroup composition, fragmentation index, coalition dynamics, quadrant distribution
categoryRankingsPer-category percentile rankings recomputed for the filtered range
predictionsAverage-based extrapolations for 2027โ€“2031 with term-cycle adjustments
analysisSummaryTrend analysis, peak/lowest years, OSINT key findings, coverage note
methodologyDescription of the statistical approach and data sources

Category Filter Options

CategoryDescriptionCorresponding Tools
plenary_sessionsPlenary sessions heldget_plenary_sessions
legislative_actsLegislative acts adoptedget_adopted_texts
roll_call_votesRoll-call votes conductedget_voting_records
committee_meetingsCommittee meetingsget_committee_info
parliamentary_questionsQuestions tabledget_parliamentary_questions
resolutionsResolutions adoptedget_adopted_texts
speechesSpeeches deliveredget_speeches
adopted_textsAdopted textsget_adopted_texts
political_groupsPolitical group compositioncompare_political_groups
proceduresLegislative proceduresget_procedures
eventsParliamentary eventsget_events
documentsDocuments producedsearch_documents
mep_turnoverMEP arrivals/departuresget_incoming_meps, get_outgoing_meps
declarationsMEP declarationsget_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

ParameterTypeRequiredDefaultDescription
(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

FieldDescription
serverServer health summary object
server.versionServer version string
server.uptime_secondsServer uptime in seconds
server.statusOverall server status (healthy, degraded, unhealthy)
feedsObject keyed by feed name, each value is a per-feed health status object
feeds.<feed_name>.statusFeed status (ok, error, unknown)
feeds.<feed_name>.lastSuccessTimestamp of last successful call (if any)
feeds.<feed_name>.lastAttemptTimestamp of the most recent health check attempt (if any)
feeds.<feed_name>.lastErrorLast error message (if any)
availabilityAvailability summary object
availability.operational_feedsNumber of feeds currently operational
availability.total_feedsTotal number of tracked feeds
availability.levelOverall 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 timeframe parameter (today, one-day, one-week, one-month, custom) and optional startDate. 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 data array with a dataQualityWarnings message is not an error โ€” it means the EP API had no updates in the requested timeframe. Always check dataQualityWarnings before 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 EndpointTypeBest-Case Response TimePeak-Load Response TimeNotes
adopted-texts/feedConfigurable~1 s30โ€“60+ sโœ… Usually fast; may slow during peak load
meps-declarations/feedConfigurable~1 s10โ€“30 sโœ… Usually fast and reliable
external-documents/feedConfigurable~1 s5โ€“15 sโœ… Usually fast and reliable
controlled-vocabularies/feedFixedHTTP 204HTTP 204Returns 204 No Content (vocabularies rarely change)
meps/feedConfigurable~9 s30โ€“60+ sโš ๏ธ May time out under load
plenary-session-documents/feedFixed20โ€“40 s60โ€“120+ sโš ๏ธ Slow; may return error-in-body
parliamentary-questions/feedFixed30โ€“60 s60โ€“120+ sโš ๏ธ Slow; may return error-in-body
procedures/feedConfigurable30โ€“60 s60โ€“120+ sโš ๏ธ May time out
plenary-documents/feedFixed30โ€“60 s60โ€“120+ sโš ๏ธ May return error-in-body
events/feedConfigurable30โ€“60 s60โ€“120+ sโš ๏ธ May time out
committee-documents/feedFixed30โ€“60 s60โ€“120+ sโš ๏ธ May return error-in-body
documents/feedFixed60โ€“120 s120+ sโš ๏ธ Very slow; frequently times out
corporate-bodies/feedFixed60โ€“180 s180+ 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 configurable get_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) and get_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 โ†’ use get_procedures({ year: 2026, limit: 20 }) instead
  • get_events_feed โ†’ use get_events({ limit: 50 }) instead (note: get_events supports only eventId, limit, and offset โ€” no date filtering)
  • get_meps_feed โ†’ use get_current_meps({ limit: 50 }) instead
  • get_adopted_texts_feed โ†’ use get_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:

ParameterTypeRequiredDefaultDescription
timeframestringNoone-weekTime window: today, one-day, one-week, one-month, or custom
startDatestringConditional-Start date in YYYY-MM-DD format. Required when timeframe is custom

Validation rule: When timeframe is custom, the startDate parameter becomes required. The server returns a validation error if startDate is 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

CategoryFeed ToolsTypeExtra Filter
MEP Dataget_meps_feed, get_mep_declarations_feedConfigurableworkType (declarations)
Legislativeget_procedures_feed, get_adopted_texts_feedConfigurableprocessType / workType
Documentsget_documents_feed โ›ถ, get_plenary_documents_feed โ›ถ, get_committee_documents_feed โ›ถ, get_plenary_session_documents_feed โ›ถ, get_external_documents_feedMixedworkType (external only)
Eventsget_events_feedConfigurableactivityType
Questionsget_parliamentary_questions_feed โ›ถFixedโ€”
Institutionalget_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

ParameterTypeRequiredDefaultDescription
timeframestringNoone-weekTime window: today, one-day, one-week, one-month, or custom
startDatestringConditional-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/feed endpoint is significantly slower than other feeds โ€” one-month queries 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, use get_events with limit/offset pagination instead (note: get_events has no date filtering โ€” only eventId, limit, and offset are 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-readable errorCode / retryable / optional upstream and retryAfterMs metadata). Unclassified or unexpected errors (e.g., network socket failures, schema validation errors) still throw โ€” callers should combine envelope inspection with standard exception handling:

errorCodeWhenretryableupstream present
NOT_FOUNDUpstream HTTP 404 (empty timeframe / recess window)falsestatusCode: 404
UPSTREAM_TIMEOUTRequest exceeded the configured timeouttrueomitted
RATE_LIMIT (local)Local token-bucket limiter rejected the call before any HTTP requesttrueomitted โ€” retryAfterMs is set
RATE_LIMIT (upstream)EP API returned HTTP 429truestatusCode: 429
UPSTREAM_ERROREP API returned HTTP 5xxtruestatusCode: 5xx
ENRICHMENT_FAILEDHTTP 200 with error field and no data arraytrueparsed upstream status when present

Parameters

ParameterTypeRequiredDefaultDescription
timeframestringNoone-weekTime window: today, one-day, one-week, one-month, or custom
startDatestringConditional-Start date (YYYY-MM-DD). Required when timeframe is custom
activityTypestringNo-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/feed endpoint is significantly slower than other feeds โ€” one-month queries may take 120+ seconds. An extended timeout (120s) is applied automatically. For faster results, use get_procedures with a year filter instead.

Parameters

ParameterTypeRequiredDefaultDescription
timeframestringNoone-weekTime window: today, one-day, one-week, one-month, or custom
startDatestringConditional-Start date (YYYY-MM-DD). Required when timeframe is custom
processTypestringNo-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

ParameterTypeRequiredDefaultDescription
timeframestringNoone-weekTime window: today, one-day, one-week, one-month, or custom
startDatestringConditional-Start date (YYYY-MM-DD). Required when timeframe is custom
workTypestringNo-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

ParameterTypeRequiredDefaultDescription
timeframestringNoone-weekTime window: today, one-day, one-week, one-month, or custom
startDatestringConditional-Start date (YYYY-MM-DD). Required when timeframe is custom
workTypestringNo-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 error field) 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

ParameterTypeRequiredDefaultDescription
timeframestringNoone-weekTime window: today, one-day, one-week, one-month, or custom
startDatestringConditional-Start date (YYYY-MM-DD). Required when timeframe is custom
workTypestringNo-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.

PromptDescriptionArguments
mep_briefingComprehensive MEP intelligence briefing with voting record, committee work, and influence assessmentmepId (required), period?
coalition_analysisCoalition dynamics and voting bloc analysis across political groupspolicyArea?, period?
legislative_trackingLegislative procedure tracking report with timeline and statusprocedureId?, committee?
political_group_comparisonMulti-dimensional comparison of political groupsgroups?
committee_activity_reportCommittee workload, engagement, and document production reportcommitteeId (required)
voting_pattern_analysisVoting pattern trend detection and anomaly identificationtopic?, mepId?
country_delegation_analysisCountry delegation composition, voting cohesion, and cross-party dynamicscountry (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 URIDescription
ep://mepsList of all current MEPs
ep://meps/{mepId}Individual MEP profile and details
ep://committees/{committeeId}Committee information and membership
ep://plenary-sessionsRecent plenary session listing
ep://votes/{sessionId}Voting records for a specific session
ep://political-groupsPolitical 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

ProjectIntegrationUse Case
EU Parliament MonitorMCP tools + promptsAutomated MEP activity tracking, voting pattern dashboards, committee workload monitoring
Riksdagsmonitor (GitHub)Riksdag MCP + this serverCross-parliament comparison between EU and Swedish Parliament data
Citizen Intelligence AgencyFull OSINT tool suiteComprehensive 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

CountryServerKey Capabilities
๐Ÿ‡ช๐Ÿ‡บ EUEuropean Parliament MCP62 tools โ€” MEP profiling, coalition analysis, anomaly detection, political landscape, longitudinal statistics
๐Ÿ‡บ๐Ÿ‡ธ USACongress.gov API MCPBills, members, votes, committees
๐Ÿ‡ฌ๐Ÿ‡ง UKParliament MCPHansard, members, debates, divisions
๐Ÿ‡ธ๐Ÿ‡ช SwedenRiksdag & Regering MCPParliament & government data
๐Ÿ‡ณ๐Ÿ‡ฑ NetherlandsOpenTK MCPTweede Kamer documents
๐Ÿ‡ต๐Ÿ‡ฑ PolandSejm MCPParliament data + legislation
๐Ÿ‡ฎ๐Ÿ‡ฑ IsraelKnesset MCPKnesset parliament API
๐Ÿ‡ง๐Ÿ‡ท BrazilSenado BR MCPFederal Senate data

Government Open Data MCP Servers

CountryServerData Portal
๐Ÿ‡ซ๐Ÿ‡ท Francedata.gouv.fr MCPdata.gouv.fr
๐Ÿ‡ฎ๐Ÿ‡ฑ IsraelData.gov.il MCPdata.gov.il
๐Ÿ‡ฎ๐Ÿ‡ณ IndiaData.gov.in MCPdata.gov.in
๐Ÿ‡ธ๐Ÿ‡ฌ SingaporeGahmen MCPdata.gov.sg
๐Ÿ‡ฆ๐Ÿ‡บ AustraliaABS MCPabs.gov.au
๐ŸŒ GlobalCKAN MCP ServerAny CKAN portal
๐ŸŒ GlobalOpenGov MCP ServerSocrata portals

๐Ÿ“– See README.md for the complete 35+ server directory with OSINT capability comparison.


๐Ÿ“š Additional Resources

Documentation

External Resources

Hack23 Ecosystem


๐Ÿค Support

Issues & Questions:

Security Issues:


๐Ÿ›‘ 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 fetch is cancelled and the call rejects with APIError(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