reunion_list_landmarks
List tourism landmarks in La Réunion: viewpoints, waterfalls, beaches, historical sites. Returns name, commune, major flag, UNESCO, and accessibility info. Ideal for travel guides and accessibility-aware itineraries.
Instructions
List remarkable tourism landmarks (lieux remarquables) in La Réunion from the SIT Soubik catalog: scenic viewpoints, waterfalls, beaches, cirque-belvédères, historical sites, etc. Returns landmark name, tagline (accroche), commune, "lieu majeur" flag (highlights), national-park flag, UNESCO World Heritage flag, characteristics, reduced-mobility accessibility. Useful for travel guides, must-see lists, accessibility-aware itineraries.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| commune | No | Commune name prefix match | |
| major_only | No | If true, return only landmarks flagged "lieu majeur" (top must-see sites) | |
| limit | No | Max landmarks to return (1-200, default 50) |
Implementation Reference
- src/modules/tourism.ts:226-252 (handler)The handler function that executes the 'reunion_list_landmarks' tool logic. It queries the OpenDataSoft API for landmarks from the 'lieux-remarquables-lareunion-wssoubik' dataset, applies optional filters (commune prefix, major_only), and maps results to a structured JSON response with fields like name, tagline, commune, major flag, national park flag, UNESCO flag, characteristics, and reduced mobility accessibility.
async ({ commune, major_only, limit }) => { try { const data = await client.getRecords<RecordObject>(DATASET_LANDMARKS, { where: buildWhere([ commune ? `commune LIKE ${quote(`${commune}%`)}` : undefined, major_only ? 'lieu_majeur = 1' : undefined, ]), limit, }); return jsonResult({ total_landmarks: data.total_count, landmarks: data.results.map((row) => ({ name: pickString(row, ['nom_du_lieu_remarquable']), tagline: pickString(row, ['accroche']), commune: pickString(row, ['commune']), major: pickNumber(row, ['lieu_majeur']) === 1, in_national_park: pickNumber(row, ['situe_dans_un_parc_national']) === 1, unesco_world_heritage: pickNumber(row, ['appartient_au_patrimoine_mondial']) === 1, characteristics: pickString(row, ['caracteristiques']), reduced_mobility_accessible: pickString(row, ['accessible_mobilite_reduite']), })), }); } catch (error) { return errorResult(error instanceof Error ? error.message : 'Failed to fetch landmarks'); } } ); - src/modules/tourism.ts:221-225 (schema)Input schema for the 'reunion_list_landmarks' tool using Zod. Parameters: commune (optional string, prefix match), major_only (boolean, default false), limit (integer 1-200, default 50).
{ commune: z.string().optional().describe('Commune name prefix match'), major_only: z.boolean().default(false).describe('If true, return only landmarks flagged "lieu majeur" (top must-see sites)'), limit: z.number().int().min(1).max(200).default(50).describe('Max landmarks to return (1-200, default 50)'), }, - src/modules/tourism.ts:218-252 (registration)Registration of the 'reunion_list_landmarks' tool via server.tool() call, which defines the tool name, description, input schema, and handler function.
server.tool( 'reunion_list_landmarks', 'List remarkable tourism landmarks (lieux remarquables) in La Réunion from the SIT Soubik catalog: scenic viewpoints, waterfalls, beaches, cirque-belvédères, historical sites, etc. Returns landmark name, tagline (accroche), commune, "lieu majeur" flag (highlights), national-park flag, UNESCO World Heritage flag, characteristics, reduced-mobility accessibility. Useful for travel guides, must-see lists, accessibility-aware itineraries.', { commune: z.string().optional().describe('Commune name prefix match'), major_only: z.boolean().default(false).describe('If true, return only landmarks flagged "lieu majeur" (top must-see sites)'), limit: z.number().int().min(1).max(200).default(50).describe('Max landmarks to return (1-200, default 50)'), }, async ({ commune, major_only, limit }) => { try { const data = await client.getRecords<RecordObject>(DATASET_LANDMARKS, { where: buildWhere([ commune ? `commune LIKE ${quote(`${commune}%`)}` : undefined, major_only ? 'lieu_majeur = 1' : undefined, ]), limit, }); return jsonResult({ total_landmarks: data.total_count, landmarks: data.results.map((row) => ({ name: pickString(row, ['nom_du_lieu_remarquable']), tagline: pickString(row, ['accroche']), commune: pickString(row, ['commune']), major: pickNumber(row, ['lieu_majeur']) === 1, in_national_park: pickNumber(row, ['situe_dans_un_parc_national']) === 1, unesco_world_heritage: pickNumber(row, ['appartient_au_patrimoine_mondial']) === 1, characteristics: pickString(row, ['caracteristiques']), reduced_mobility_accessible: pickString(row, ['accessible_mobilite_reduite']), })), }); } catch (error) { return errorResult(error instanceof Error ? error.message : 'Failed to fetch landmarks'); } } ); - src/modules/tourism.ts:17-17 (registration)The 'registerTourismTools' function that is exported and called from the index module to register all tourism tools including 'reunion_list_landmarks'.
export function registerTourismTools(server: McpServer): void { - src/utils/helpers.ts:36-41 (helper)The buildWhere helper used to construct the ODSQL WHERE clause from optional conditions (commune filter and major_only filter).
export function buildWhere( conditions: Array<string | undefined | null | false> ): string | undefined { const valid = conditions.filter((condition): condition is string => Boolean(condition)); return valid.length > 0 ? valid.join(' AND ') : undefined; } - src/utils/helpers.ts:108-120 (helper)The pickString helper used to extract string values from record fields (e.g., name, tagline, commune, characteristics, accessibility).
export function pickString( record: RecordObject, candidates: string[] ): string | undefined { const value = pickValue(record, candidates); if (typeof value === 'string') { return value; } if (typeof value === 'number' || typeof value === 'boolean') { return String(value); } return undefined; } - src/utils/helpers.ts:125-138 (helper)The pickNumber helper used to extract numeric values from record fields (e.g., lieu_majeur, situe_dans_un_parc_national, appartient_au_patrimoine_mondial).
export function pickNumber( record: RecordObject, candidates: string[] ): number | undefined { const value = pickValue(record, candidates); if (typeof value === 'number' && Number.isFinite(value)) { return value; } if (typeof value === 'string' && value.trim() !== '') { const parsed = Number(value); return Number.isFinite(parsed) ? parsed : undefined; } return undefined; } - src/utils/helpers.ts:53-55 (helper)The quote helper used to safely quote string values in ODSQL WHERE clause conditions.
export function quote(value: string): string { return `'${escapeOdSqlString(value)}'`; }