reunion_search_catalog
Search the La Réunion open data catalog by keywords, theme, or publisher to find datasets not yet wired to dedicated tools.
Instructions
Search the full data.regionreunion.com catalog (~270 datasets) by keywords and/or theme. Use this to discover datasets that are not wired to a dedicated tool yet, then call reunion_inspect_dataset and reunion_query_dataset to work with them.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Free-text search on titles, descriptions, keywords | |
| theme | No | Theme filter (prefix match), e.g. "Environnement", "Transports", "Éducation" | |
| publisher | No | Publisher filter (substring match) | |
| limit | No |
Implementation Reference
- src/modules/catalog.ts:19-50 (handler)Handler function for the 'reunion_search_catalog' tool. Accepts optional query, theme, publisher, and limit parameters. Builds ODSQL conditions using buildWhere helper, calls client.listDatasets() to search the catalog, maps results to a structured response with dataset_id, title, description (stripped of HTML, truncated to 400 chars), theme, publisher, records_count, and modified. Returns total_matches and datasets array on success, or error on failure.
async ({ query, theme, publisher, limit }) => { try { const conditions = buildWhere([ query ? `search(${quote(query)})` : undefined, theme ? `theme LIKE ${quote(`${theme}%`)}` : undefined, publisher ? `publisher LIKE ${quote(`%${publisher}%`)}` : undefined, ]); const data = await client.listDatasets({ where: conditions, limit }); return jsonResult({ total_matches: data.total_count, datasets: data.results.map((row) => { const metas = (row.metas?.default ?? {}) as RecordObject; return { dataset_id: row.dataset_id, title: metas.title, description: typeof metas.description === 'string' ? metas.description.replace(/<[^>]+>/g, '').slice(0, 400) : undefined, theme: metas.theme, publisher: metas.publisher, records_count: metas.records_count, modified: metas.modified, }; }), }); } catch (error) { return errorResult(error instanceof Error ? error.message : 'Failed to search catalog'); } } - src/modules/catalog.ts:13-18 (schema)Input schema for reunion_search_catalog tool: query (optional free-text string), theme (optional string for prefix-match filter), publisher (optional string for substring-match filter), limit (integer 1-100, defaults to 20).
{ query: z.string().optional().describe('Free-text search on titles, descriptions, keywords'), theme: z.string().optional().describe('Theme filter (prefix match), e.g. "Environnement", "Transports", "Éducation"'), publisher: z.string().optional().describe('Publisher filter (substring match)'), limit: z.number().int().min(1).max(100).default(20), }, - src/modules/catalog.ts:10-51 (registration)Registration of the 'reunion_search_catalog' tool via server.tool() in the registerCatalogTools function. The tool description tells the LLM to search the full data.regionreunion.com catalog (~270 datasets) by keywords and/or theme, and hints at using reunion_inspect_dataset and reunion_query_dataset for further interaction.
server.tool( 'reunion_search_catalog', 'Search the full data.regionreunion.com catalog (~270 datasets) by keywords and/or theme. Use this to discover datasets that are not wired to a dedicated tool yet, then call reunion_inspect_dataset and reunion_query_dataset to work with them.', { query: z.string().optional().describe('Free-text search on titles, descriptions, keywords'), theme: z.string().optional().describe('Theme filter (prefix match), e.g. "Environnement", "Transports", "Éducation"'), publisher: z.string().optional().describe('Publisher filter (substring match)'), limit: z.number().int().min(1).max(100).default(20), }, async ({ query, theme, publisher, limit }) => { try { const conditions = buildWhere([ query ? `search(${quote(query)})` : undefined, theme ? `theme LIKE ${quote(`${theme}%`)}` : undefined, publisher ? `publisher LIKE ${quote(`%${publisher}%`)}` : undefined, ]); const data = await client.listDatasets({ where: conditions, limit }); return jsonResult({ total_matches: data.total_count, datasets: data.results.map((row) => { const metas = (row.metas?.default ?? {}) as RecordObject; return { dataset_id: row.dataset_id, title: metas.title, description: typeof metas.description === 'string' ? metas.description.replace(/<[^>]+>/g, '').slice(0, 400) : undefined, theme: metas.theme, publisher: metas.publisher, records_count: metas.records_count, modified: metas.modified, }; }), }); } catch (error) { return errorResult(error instanceof Error ? error.message : 'Failed to search catalog'); } } ); - src/modules/index.ts:34-36 (registration)registerCatalogTools(server) is called from registerAllTools() in src/modules/index.ts, which is invoked during server startup in src/index.ts.
registerAdministrationTools(server); registerCatalogTools(server); registerCommuneTools(server); - src/utils/helpers.ts:36-41 (helper)buildWhere helper used by the handler to construct an ODSQL WHERE clause from an array of optional 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; }