reunion_search_boamp
Search public procurement notices for La Réunion from BOAMP. Retrieve open tenders, contract awards, and framework agreements with buyer, awardee, and deadline details.
Instructions
Search the BOAMP (Bulletin Officiel des Annonces de Marchés Publics) for public-procurement notices concerning La Réunion: open tenders (appels d'offres ouverts/restreints), MAPA (procédures adaptées), contract awards (avis d'attribution), framework agreements (accords-cadres), and concession contracts. Returns notice ID, web ID, object/description, buyer name, awardee (if any), procurement family/nature, procedure type and label, publication date, response deadline, status, official BOAMP URL. Sorted by publication date descending. Source: DILA / BOAMP via data.regionreunion.com.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Free-text search across notice object, buyer, awardee, descriptions | |
| buyer | No | Buyer / contracting authority name prefix match. Examples: "Région Réunion", "Mairie de Saint-Denis", "CHU" | |
| procedure_type | No | Procedure category prefix match. Examples: "Appel d'offres ouvert", "Procédure adaptée (MAPA)", "Marché négocié" | |
| limit | No | Max notices to return (1-100, default 25) |
Implementation Reference
- src/modules/administration.ts:362-397 (handler)Async handler function that executes the reunion_search_boamp tool logic: queries the BOAMP dataset via the API client, builds WHERE filters from optional query/buyer/procedure_type parameters, orders by publication date descending, and maps results to structured notice objects (id, web_id, object, buyer, awardee, family_label, procedure_type, procedure_label, procedure_category, nature, sub_nature, published_at, response_deadline, state, url).
async ({ query, buyer, procedure_type, limit }) => { try { const data = await client.getRecords<RecordObject>(DATASET_BOAMP, { where: buildWhere([ query ? `search(${quote(query)})` : undefined, buyer ? `nomacheteur LIKE ${quote(`${buyer}%`)}` : undefined, procedure_type ? `procedure_categorise LIKE ${quote(`${procedure_type}%`)}` : undefined, ]), order_by: 'dateparution DESC', limit, }); return jsonResult({ total_notices: data.total_count, notices: data.results.map((row) => ({ id: pickString(row, ['id']), web_id: pickString(row, ['idweb']), object: pickString(row, ['objet']), buyer: pickString(row, ['nomacheteur']), awardee: pickString(row, ['titulaire']), family_label: pickString(row, ['famille_libelle']), procedure_type: pickString(row, ['type_procedure']), procedure_label: pickString(row, ['procedure_libelle']), procedure_category: pickString(row, ['procedure_categorise']), nature: pickString(row, ['nature_libelle']), sub_nature: pickString(row, ['sousnature_libelle']), published_at: pickString(row, ['dateparution']), response_deadline: pickString(row, ['datelimitereponse']), state: pickString(row, ['etat']), url: pickString(row, ['url_avis']), })), }); } catch (error) { return errorResult(error instanceof Error ? error.message : 'Failed to search BOAMP'); } } ); - Schema definition for the reunion_search_boamp tool: optional 'query' (free-text), 'buyer' (contracting authority name prefix), 'procedure_type' (procedure category prefix), and 'limit' (1-100, default 25) parameters with Zod validation.
{ query: z.string().optional().describe('Free-text search across notice object, buyer, awardee, descriptions'), buyer: z.string().optional().describe('Buyer / contracting authority name prefix match. Examples: "Région Réunion", "Mairie de Saint-Denis", "CHU"'), procedure_type: z.string().optional().describe('Procedure category prefix match. Examples: "Appel d\'offres ouvert", "Procédure adaptée (MAPA)", "Marché négocié"'), limit: z.number().int().min(1).max(100).default(25).describe('Max notices to return (1-100, default 25)'), }, - src/modules/administration.ts:353-397 (registration)Registration of the 'reunion_search_boamp' tool via server.tool() with description, schema, and handler. Exported via registerAdministrationTools() called from src/modules/index.ts.
server.tool( 'reunion_search_boamp', 'Search the BOAMP (Bulletin Officiel des Annonces de Marchés Publics) for public-procurement notices concerning La Réunion: open tenders (appels d\'offres ouverts/restreints), MAPA (procédures adaptées), contract awards (avis d\'attribution), framework agreements (accords-cadres), and concession contracts. Returns notice ID, web ID, object/description, buyer name, awardee (if any), procurement family/nature, procedure type and label, publication date, response deadline, status, official BOAMP URL. Sorted by publication date descending. Source: DILA / BOAMP via data.regionreunion.com.', { query: z.string().optional().describe('Free-text search across notice object, buyer, awardee, descriptions'), buyer: z.string().optional().describe('Buyer / contracting authority name prefix match. Examples: "Région Réunion", "Mairie de Saint-Denis", "CHU"'), procedure_type: z.string().optional().describe('Procedure category prefix match. Examples: "Appel d\'offres ouvert", "Procédure adaptée (MAPA)", "Marché négocié"'), limit: z.number().int().min(1).max(100).default(25).describe('Max notices to return (1-100, default 25)'), }, async ({ query, buyer, procedure_type, limit }) => { try { const data = await client.getRecords<RecordObject>(DATASET_BOAMP, { where: buildWhere([ query ? `search(${quote(query)})` : undefined, buyer ? `nomacheteur LIKE ${quote(`${buyer}%`)}` : undefined, procedure_type ? `procedure_categorise LIKE ${quote(`${procedure_type}%`)}` : undefined, ]), order_by: 'dateparution DESC', limit, }); return jsonResult({ total_notices: data.total_count, notices: data.results.map((row) => ({ id: pickString(row, ['id']), web_id: pickString(row, ['idweb']), object: pickString(row, ['objet']), buyer: pickString(row, ['nomacheteur']), awardee: pickString(row, ['titulaire']), family_label: pickString(row, ['famille_libelle']), procedure_type: pickString(row, ['type_procedure']), procedure_label: pickString(row, ['procedure_libelle']), procedure_category: pickString(row, ['procedure_categorise']), nature: pickString(row, ['nature_libelle']), sub_nature: pickString(row, ['sousnature_libelle']), published_at: pickString(row, ['dateparution']), response_deadline: pickString(row, ['datelimitereponse']), state: pickString(row, ['etat']), url: pickString(row, ['url_avis']), })), }); } catch (error) { return errorResult(error instanceof Error ? error.message : 'Failed to search BOAMP'); } } ); - src/modules/administration.ts:7-7 (helper)Imports of helper utilities used by the handler: buildWhere, errorResult, jsonResult, pickString, quote from '../utils/helpers.js'.
import { buildWhere, errorResult, jsonResult, pickNumber, pickString, quote } from '../utils/helpers.js'; - src/modules/administration.ts:20-20 (helper)Dataset constant DATASET_BOAMP = 'boamp' defining the data source used by the reunion_search_boamp tool.
const DATASET_BOAMP = 'boamp';