reunion_search_ban_addresses
Search geocoded addresses in La Réunion from the Base Adresse Nationale, including coordinates and address components. Useful for address validation and mapping.
Instructions
Search the Base Adresse Nationale (BAN) — France's authoritative geocoded address database — restricted to La Réunion (~353k addresses). Each address has lat/lon, street name, number, postal code, INSEE code, and a position type (entrance, parcel, segment). Use this for geocoding, address validation, last-mile delivery, mapping. Source: IGN / La Poste / DINUM via data.regionreunion.com.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Free-text search across street name and city | |
| commune | No | Commune name prefix match (e.g. "Saint-Denis") | |
| insee | No | INSEE commune code (5 digits as integer, e.g. 97411 for Saint-Denis) | |
| postal_code | No | Postal code as integer (5 digits, Réunion uses 974xx) | |
| limit | No | Max addresses to return (1-100, default 20) |
Implementation Reference
- src/modules/geography.ts:18-57 (handler)The MCP tool handler for 'reunion_search_ban_addresses'. Registers the tool via server.tool() with the name 'reunion_search_ban_addresses', accepts query/commune/insee/postal_code/limit parameters, queries the 'ban-lareunion' OpenDataSoft dataset via the ReunionClient, and returns formatted address results (number, suffix, street, postal_code, insee_code, commune, lon, lat, position_type).
server.tool( 'reunion_search_ban_addresses', 'Search the Base Adresse Nationale (BAN) — France\'s authoritative geocoded address database — restricted to La Réunion (~353k addresses). Each address has lat/lon, street name, number, postal code, INSEE code, and a position type (entrance, parcel, segment). Use this for geocoding, address validation, last-mile delivery, mapping. Source: IGN / La Poste / DINUM via data.regionreunion.com.', { query: z.string().optional().describe('Free-text search across street name and city'), commune: z.string().optional().describe('Commune name prefix match (e.g. "Saint-Denis")'), insee: z.number().int().optional().describe('INSEE commune code (5 digits as integer, e.g. 97411 for Saint-Denis)'), postal_code: z.number().int().optional().describe('Postal code as integer (5 digits, Réunion uses 974xx)'), limit: z.number().int().min(1).max(100).default(20).describe('Max addresses to return (1-100, default 20)'), }, async ({ query, commune, insee, postal_code, limit }) => { try { const data = await client.getRecords<RecordObject>(DATASET_BAN, { where: buildWhere([ query ? `search(${quote(query)})` : undefined, commune ? `nom_commune LIKE ${quote(`${commune}%`)}` : undefined, insee !== undefined ? `code_insee = ${insee}` : undefined, postal_code !== undefined ? `code_postal = ${postal_code}` : undefined, ]), limit, }); return jsonResult({ total_addresses: data.total_count, addresses: data.results.map((row) => ({ number: pickNumber(row, ['numero']), suffix: pickString(row, ['rep']), street: pickString(row, ['nom_voie']), postal_code: pickNumber(row, ['code_postal']), insee_code: pickNumber(row, ['code_insee']), commune: pickString(row, ['nom_commune']), lon: pickNumber(row, ['lon']), lat: pickNumber(row, ['lat']), position_type: pickString(row, ['type_position']), })), }); } catch (error) { return errorResult(error instanceof Error ? error.message : 'Failed to search BAN addresses'); } } ); - src/modules/geography.ts:21-27 (schema)Zod-based input schema for the tool. Defines optional parameters: query (string), commune (string), insee (integer), postal_code (integer), and limit (integer, 1-100, default 20).
{ query: z.string().optional().describe('Free-text search across street name and city'), commune: z.string().optional().describe('Commune name prefix match (e.g. "Saint-Denis")'), insee: z.number().int().optional().describe('INSEE commune code (5 digits as integer, e.g. 97411 for Saint-Denis)'), postal_code: z.number().int().optional().describe('Postal code as integer (5 digits, Réunion uses 974xx)'), limit: z.number().int().min(1).max(100).default(20).describe('Max addresses to return (1-100, default 20)'), }, - src/modules/index.ts:43-43 (registration)Where registerGeographyTools (which contains the tool registration) is called within registerAllTools.
registerGeographyTools(server); - src/modules/index.ts:14-14 (registration)Import of the registerGeographyTools function from geography module.
import { registerGeographyTools } from './geography.js'; - src/utils/helpers.ts:36-41 (helper)buildWhere helper: constructs an ODSQL WHERE clause from an array of conditions, joining them with AND.
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; }