list_persons
Retrieve detailed information on all Members of Parliament, including IDs, names, titles, party affiliations, and faction memberships. Use this to analyze parliamentary composition, create reports, or find MP details for further queries.
Instructions
Provides a complete directory of current Members of Parliament with their IDs, names, titles, party affiliations, and faction memberships. The response is a JSON array where each entry contains an MP's full details. Use this tool when a user needs comprehensive information about all MPs, wants to analyze the composition of parliament by party, or needs to find specific MPs by name or party. This tool is particularly useful for creating reports about parliamentary representation or for finding the IDs of MPs that can be used with other tools like 'get_photo'. This tool takes no parameters as it returns all current MPs. For a more targeted approach when looking for specific MPs, consider using the 'search_tk' tool with the MP's name.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/index.ts:78-106 (registration)Registration of the 'list_persons' MCP tool, including tool description, empty input schema, and handler function that calls apiService.getPersons() to retrieve and return the list of MPs as JSON.mcp.tool( "list_persons", "Provides a complete directory of current Members of Parliament with their IDs, names, titles, party affiliations, and faction memberships. The response is a JSON array where each entry contains an MP's full details including unique MP IDs that can be referenced by other tools. This tool takes no parameters as it returns all current MPs. Applicable when comprehensive information about all MPs is needed or when analyzing the composition of parliament by party.", {}, async () => { try { // Use the tkconv API to get the MP list const persons = await apiService.getPersons(); if (persons.length === 0) { return { content: [{ type: "text", text: "No MPs found or there was an error retrieving the MP list. Please try again later." }] }; } return { content: [{ type: "text", text: JSON.stringify(persons, null, 2) }] }; } catch (error: any) { return { content: [{ type: "text", text: `Error fetching MP list: ${error.message || 'Unknown error'}` }] }; } } );
- src/services/api.ts:398-410 (handler)The getPersons() method in ApiService class, which fetches the kamerleden.html page and extracts the list of persons using the private extractPersonsFromHtml method.async getPersons(): Promise<any[]> { try { // Fetch the HTML page that contains the MP list const html = await this.fetchHtml("/kamerleden.html"); // Extract MP data from the HTML const persons = this.extractPersonsFromHtml(html); return persons; } catch (error) { return []; } }
- src/services/api.ts:417-490 (helper)Private helper method extractPersonsFromHtml that uses regex to parse the HTML table from kamerleden.html, extracting MP details like ID, full name (split into first/last), party/fractie, and constructs standardized person objects.private extractPersonsFromHtml(html: string): any[] { const persons: any[] = []; try { // Extract the table rows containing MP data const tableRegex = /<table[^>]*>[\s\S]*?<tbody>([\s\S]*?)<\/tbody>/gi; const tableMatch = tableRegex.exec(html); if (!tableMatch || !tableMatch[1]) { return []; } const tableContent = tableMatch[1]; // Extract each row (MP) from the table const rowRegex = /<tr[^>]*>([\s\S]*?)<\/tr>/gi; let rowMatch; while ((rowMatch = rowRegex.exec(tableContent)) !== null) { if (!rowMatch[1]) continue; const rowContent = rowMatch[1]; // Extract the MP ID from the link const idRegex = /persoon\.html\?nummer=(\d+)/i; const idMatch = rowContent.match(idRegex); const id = idMatch?.[1] ? parseInt(idMatch[1], 10) : null; if (!id) continue; // Extract the MP name const nameRegex = /<a[^>]*>([\s\S]*?)<\/a>/i; const nameMatch = rowContent.match(nameRegex); const fullName = nameMatch?.[1]?.trim() || ""; // Split the name into first and last name (simple approach) const nameParts = fullName.split(" "); const firstName = nameParts.length > 1 ? nameParts[0] : ""; const lastName = nameParts.length > 1 ? nameParts.slice(1).join(" ") : fullName; // Extract the party const partyRegex = /<td[^>]*>([\s\S]*?)<\/td>/gi; const cells = []; let cellMatch; while ((cellMatch = partyRegex.exec(rowContent)) !== null) { if (cellMatch[1]) { cells.push(cellMatch[1].trim()); } } // Party is typically in the second or third cell const party = cells.length > 2 ? cells[2] : (cells.length > 1 ? cells[1] : ""); // Create the person object persons.push({ Id: id, Persoonsnummer: id, Voornaam: firstName, Achternaam: lastName, Fullname: fullName, Fractie: party, FractieAfkorting: party, Functie: "Tweede Kamerlid", // Assuming all are MPs Links: { self: `/persoon.html?nummer=${id}` } }); } return persons; } catch (error) { return []; } }