reunion_get_legislative_2024_round2
Retrieve results of the 2024 French legislative election second round in La Réunion, per constituency, including vote counts and elected deputies.
Instructions
Results of the 2024 anticipated legislative elections, 2nd round (July 7, 2024) in La Réunion, aggregated per circonscription (1-7). Same schema as round 1 but with elected flag populated for the winners (one elected per circonscription, so 7 députés total for Réunion). Returns base voting stats and the candidate-level data with vote count, percentages, and elected flag. Use to identify the deputies who won.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| circumscription | No | Réunion circonscription number, integer 1 to 7. Omit to return all 7 circonscriptions |
Implementation Reference
- Handler for reunion_get_legislative_2024_round2 tool. Fetches data from data.gouv.fr resource RES_LEGIS_2024_T2 (id '41ed46cd-77c2-4ecc-b8eb-374aa953ca39'), filters by département 974 and optional circumscription, maps results into department name, circumscription code/name, base voting stats, and candidate details with vote counts and elected flag.
server.tool( 'reunion_get_legislative_2024_round2', 'Results of the 2024 anticipated legislative elections, 2nd round (July 7, 2024) in La Réunion, aggregated per circonscription (1-7). Same schema as round 1 but with elected flag populated for the winners (one elected per circonscription, so 7 députés total for Réunion). Returns base voting stats and the candidate-level data with vote count, percentages, and elected flag. Use to identify the deputies who won.', { circumscription: z .number() .int() .min(1) .max(7) .optional() .describe('Réunion circonscription number, integer 1 to 7. Omit to return all 7 circonscriptions'), }, async ({ circumscription }) => { try { const data = await fetchLegislative2024(RES_LEGIS_2024_T2, circumscription); return jsonResult({ source: 'data.gouv.fr (Ministère de l\'Intérieur)', round: 2, rows: data.data.map((row) => ({ department: str(row['Libellé département']), circumscription_code: str(row['Code circonscription législative']), circumscription_name: str(row['Libellé circonscription législative']), ...mapBaseStats(row), candidates: meltCandidates(row), })), }); } catch (error) { return errorResult(error instanceof Error ? error.message : 'Failed to fetch legislative 2024 R2'); } } ); - Input schema for reunion_get_legislative_2024_round2: optional circumscription number (1-7, integer). Omit to get all 7 circonscriptions.
{ circumscription: z .number() .int() .min(1) .max(7) .optional() .describe('Réunion circonscription number, integer 1 to 7. Omit to return all 7 circonscriptions'), }, - src/modules/national-elections.ts:99-99 (registration)Registration: server.tool('reunion_get_legislative_2024_round2', ...) called inside registerNationalElectionsTools. This function is invoked from src/modules/index.ts line 47 via registerAllTools.
export function registerNationalElectionsTools(server: McpServer): void { - Helper function that queries the data.gouv.fr tabular API with resource ID, filters for département 974 and optionally by circumscription code.
async function fetchLegislative2024(resourceId: string, circumscription?: number) { const filters: Record<string, string | number | undefined> = { 'Code département': '974', }; if (circumscription !== undefined) { // The CSV stores the full code (974 + 0N), e.g. circo 1 → "97401". filters['Code circonscription législative'] = `9740${circumscription}`; } return dataGouvClient.query<Row>(resourceId, { filters, pageSize: 50 }); } - src/clients/data-gouv.ts:27-67 (helper)DataGouvTabularClient.query() — HTTP client that fetches data from tabular-api.data.gouv.fr with exact-match filters, pagination, and timeout.
export class DataGouvTabularClient { private readonly timeout = 30000; async query<T = Record<string, unknown>>( resourceId: string, options: TabularQuery = {} ): Promise<TabularResponse<T>> { const url = new URL(`${BASE}/resources/${resourceId}/data/`); if (options.filters) { for (const [column, value] of Object.entries(options.filters)) { if (value === undefined || value === null || value === '') continue; // tabular-api expects `<column>__exact=<value>` url.searchParams.set(`${column}__exact`, String(value)); } } if (options.pageSize) url.searchParams.set('page_size', String(options.pageSize)); if (options.page) url.searchParams.set('page', String(options.page)); const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), this.timeout); try { const response = await fetch(url.toString(), { headers: { Accept: 'application/json', 'User-Agent': 'mcp-reunion/1.2', }, signal: controller.signal, }); if (!response.ok) { const body = await response.text(); throw new Error(`tabular-api ${response.status}: ${body.slice(0, 300)}`); } return (await response.json()) as TabularResponse<T>; } finally { clearTimeout(timeoutId); } } } export const dataGouvClient = new DataGouvTabularClient();