Skip to main content
Glama
Hug0x0

mcp-reunion

reunion_list_water_management_points

List water management infrastructure points in La Réunion, including intakes, treatment plants, and reservoirs. Supports water-resource analysis and infrastructure mapping.

Instructions

List points of activity / interest related to water management in La Réunion: water intakes (captages), treatment plants (stations d'épuration / potabilisation), reservoirs, pumping stations, etc. Returns ID, origin/source, nature, toponym, importance level. Useful for water-resource analysis, infrastructure mapping, environmental studies.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
natureNoNature prefix match. Examples: "Captage", "Station de traitement", "Forage", "Réservoir", "Pompage"
origineNoOrigin / source prefix match (organization that produced the data)
limitNoMax points to return (1-200, default 50)

Implementation Reference

  • The MCP tool handler for 'reunion_list_water_management_points'. It queries the dataset 'les-points-d-activite-ou-d-interet-la-gestion-des-eaux' with optional filters (nature, origine) and limit, then returns a list of water management points with id, origin, nature, toponym, and importance.
    server.tool(
      'reunion_list_water_management_points',
      'List points of activity / interest related to water management in La Réunion: water intakes (captages), treatment plants (stations d\'épuration / potabilisation), reservoirs, pumping stations, etc. Returns ID, origin/source, nature, toponym, importance level. Useful for water-resource analysis, infrastructure mapping, environmental studies.',
      {
        nature: z.string().optional().describe('Nature prefix match. Examples: "Captage", "Station de traitement", "Forage", "Réservoir", "Pompage"'),
        origine: z.string().optional().describe('Origin / source prefix match (organization that produced the data)'),
        limit: z.number().int().min(1).max(200).default(50).describe('Max points to return (1-200, default 50)'),
      },
      async ({ nature, origine, limit }) => {
        try {
          const data = await client.getRecords<RecordObject>(DATASET_WATER_POIS, {
            where: buildWhere([
              nature ? `nature LIKE ${quote(`${nature}%`)}` : undefined,
              origine ? `origine LIKE ${quote(`${origine}%`)}` : undefined,
            ]),
            limit,
          });
          return jsonResult({
            total_points: data.total_count,
            points: data.results.map((row) => ({
              id: pickString(row, ['id']),
              origin: pickString(row, ['origine']),
              nature: pickString(row, ['nature']),
              toponym: pickString(row, ['toponyme']),
              importance: pickString(row, ['importance']),
            })),
          });
        } catch (error) {
          return errorResult(error instanceof Error ? error.message : 'Failed to list water points');
        }
      }
    );
  • Input schema for the tool: nature (string, optional), origine (string, optional), limit (number 1-200, default 50).
    {
      nature: z.string().optional().describe('Nature prefix match. Examples: "Captage", "Station de traitement", "Forage", "Réservoir", "Pompage"'),
      origine: z.string().optional().describe('Origin / source prefix match (organization that produced the data)'),
      limit: z.number().int().min(1).max(200).default(50).describe('Max points to return (1-200, default 50)'),
    },
  • The tool is registered via server.tool() inside registerEnvironmentTools(). This function is exported and called from src/modules/index.ts line 41.
    export function registerEnvironmentTools(server: McpServer): void {
      server.tool(
        'reunion_get_air_quality',
        'Air-quality station measurements in La Réunion exposed via OpenAQ. Each row is one measurement at one station for one pollutant. Returns city, location/station, pollutant code, value, unit, last update timestamp, source name. Sorted by last-update descending. Useful for environmental monitoring, public-health analysis, pollution-event tracking.',
        {
          pollutant: z
            .enum(['pm25', 'pm10', 'no2', 'o3', 'so2', 'co', 'bc'])
            .optional()
            .describe('Pollutant filter (OpenAQ code): pm25 (fine particles ≤2.5µm), pm10 (≤10µm), no2 (nitrogen dioxide), o3 (ozone), so2 (sulfur dioxide), co (carbon monoxide), bc (black carbon)'),
          city: z.string().optional().describe('City name prefix match (e.g. "Saint-Denis", "Le Port")'),
          limit: z.number().int().min(1).max(200).default(50).describe('Max measurements to return (1-200, default 50)'),
        },
        async ({ pollutant, city, limit }) => {
          try {
            const data = await client.getRecords<RecordObject>(DATASET_AIR_QUALITY, {
              where: buildWhere([
                `country = ${quote('FR')}`,
                `country_name_en = ${quote('France')}`,
                `search(${quote('Réunion')}) OR city LIKE ${quote('Saint-%')}`,
                pollutant ? `measurements_parameter = ${quote(pollutant)}` : undefined,
                city ? `city LIKE ${quote(`${city}%`)}` : undefined,
              ]),
              order_by: 'measurements_lastupdated DESC',
              limit,
            });
    
            return jsonResult({
              total_measurements: data.total_count,
              measurements: data.results.map((row) => ({
                city: pickString(row, ['city']),
                location: pickString(row, ['location']),
                pollutant: pickString(row, ['measurements_parameter']),
                value: pickNumber(row, ['measurements_value']),
                unit: pickString(row, ['measurements_unit']),
                last_updated: pickString(row, ['measurements_lastupdated']),
                source: pickString(row, ['measurements_sourcename']),
              })),
            });
          } catch (error) {
            return errorResult(error instanceof Error ? error.message : 'Failed to fetch air quality');
          }
        }
      );
    
      server.tool(
        'reunion_get_waste_tonnage',
        'Annual tonnage of Déchets Ménagers et Assimilés (DMA, household + assimilated waste) collected in La Réunion, broken down by waste type (ordures ménagères résiduelles, collecte sélective, déchèteries, encombrants, déchets verts, etc.). Returns year, waste-type code and label, tonnage in tonnes, department. Sorted by year descending. Source: SINOE / ADEME via data.regionreunion.com. Use for waste-policy monitoring, recycling rate analysis.',
        {
          year: z.number().int().optional().describe('Year filter (4 digits, e.g. 2022)'),
          waste_type: z.string().optional().describe('Waste-type label prefix. Examples: "Ordures ménagères résiduelles", "Collecte sélective", "Déchets verts", "Encombrants", "Déchèteries"'),
          limit: z.number().int().min(1).max(200).default(50).describe('Max rows to return (1-200, default 50)'),
        },
        async ({ year, waste_type, limit }) => {
          try {
            const data = await client.getRecords<RecordObject>(DATASET_WASTE_TONNAGE, {
              where: buildWhere([
                year !== undefined ? `annee = ${year}` : undefined,
                waste_type ? `l_typ_reg_dechet LIKE ${quote(`${waste_type}%`)}` : undefined,
              ]),
              order_by: 'annee DESC',
              limit,
            });
            return jsonResult({
              total_rows: data.total_count,
              tonnage: data.results.map((row) => ({
                year: pickNumber(row, ['annee']),
                waste_type_code: pickString(row, ['c_typ_reg_dechet']),
                waste_type: pickString(row, ['l_typ_reg_dechet']),
                tonnage_t: pickNumber(row, ['tonnage_dma_t']),
                department: pickString(row, ['n_dept']),
              })),
            });
          } catch (error) {
            return errorResult(error instanceof Error ? error.message : 'Failed to fetch waste tonnage');
          }
        }
      );
    
      server.tool(
        'reunion_search_rge_companies',
        'Search companies certified RGE (Reconnu Garant de l\'Environnement) in La Réunion. RGE certification is required for clients to qualify for state aids on energy-renovation work (MaPrimeRénov\', éco-PTZ, CEE). Returns SIRET, company name, address, postal code, commune, phone, email, website, certification name, qualification, domain (insulation/heating/PV/...), meta-domain, certifying organization, lat/lon. Source: ADEME via data.regionreunion.com.',
        {
          query: z.string().optional().describe('Free-text search across company name, address, certification'),
          commune: z.string().optional().describe('Commune name prefix match'),
          domain: z.string().optional().describe('Specific domain prefix match. Examples: "Isolation", "Chauffage", "Photovoltaïque", "Eau chaude sanitaire", "Pompe à chaleur"'),
          limit: z.number().int().min(1).max(100).default(25).describe('Max companies to return (1-100, default 25)'),
        },
        async ({ query, commune, domain, limit }) => {
          try {
            const data = await client.getRecords<RecordObject>(DATASET_RGE_COMPANIES, {
              where: buildWhere([
                query ? `search(${quote(query)})` : undefined,
                commune ? `commune LIKE ${quote(`${commune}%`)}` : undefined,
                domain ? `domaine LIKE ${quote(`${domain}%`)}` : undefined,
              ]),
              limit,
            });
            return jsonResult({
              total_companies: data.total_count,
              companies: data.results.map((row) => ({
                siret: pickString(row, ['siret']),
                name: pickString(row, ['nom_entreprise']),
                address: pickString(row, ['adresse']),
                postal_code: pickString(row, ['code_postal']),
                commune: pickString(row, ['commune']),
                phone: pickString(row, ['telephone']),
                email: pickString(row, ['email']),
                website: pickString(row, ['site_internet']),
                certification: pickString(row, ['nom_certificat']),
                qualification: pickString(row, ['nom_qualification']),
                domain: pickString(row, ['domaine']),
                meta_domain: pickString(row, ['meta_domaine']),
                organization: pickString(row, ['organisme']),
                lat: pickNumber(row, ['latitude']),
                lon: pickNumber(row, ['longitude']),
              })),
            });
          } catch (error) {
            return errorResult(error instanceof Error ? error.message : 'Failed to search RGE companies');
          }
        }
      );
    
      server.tool(
        'reunion_list_znieff',
        'List Zones Naturelles d\'Intérêt Écologique, Faunistique et Floristique (ZNIEFF) in La Réunion — official inventory of areas of high ecological value, used for biodiversity protection and as a reference in land-use decisions. Réunion has type-1 (small precise zones with rare species) and type-2 (large functional ecosystems). Returns MNHN ID, organization ID, zone name, generation. Source: MNHN / DEAL via data.regionreunion.com.',
        {
          query: z.string().optional().describe('Free-text search on zone name (e.g. "Piton", "Mafate", "Volcan")'),
          limit: z.number().int().min(1).max(100).default(50).describe('Max zones to return (1-100, default 50)'),
        },
        async ({ query, limit }) => {
          try {
            const data = await client.getRecords<RecordObject>(DATASET_ZNIEFF, {
              where: buildWhere([query ? `search(${quote(query)})` : undefined]),
              limit,
            });
            return jsonResult({
              total_zones: data.total_count,
              zones: data.results.map((row) => ({
                mnhn_id: pickString(row, ['id_mnhn']),
                org_id: pickString(row, ['id_org']),
                name: pickString(row, ['nom']),
                generation: pickString(row, ['generation']),
              })),
            });
          } catch (error) {
            return errorResult(error instanceof Error ? error.message : 'Failed to list ZNIEFF zones');
          }
        }
      );
    
      server.tool(
        'reunion_list_national_park_perimeters',
        'List the official perimeters of the Parc National de La Réunion (created in 2007, UNESCO World Heritage since 2010): the core protected area (cœur de parc, ~42% of the island) and the adherence area (aire d\'adhésion). Returns perimeter type, type code, surface (raw and in hectares), founding decree reference. Useful for environmental impact assessment, hiking-permit logic, conservation analysis.',
        {},
        async () => {
          try {
            const data = await client.getRecords<RecordObject>(DATASET_PNRUN, { limit: 20 });
            return jsonResult({
              total_perimeters: data.total_count,
              perimeters: data.results.map((row) => ({
                type: pickString(row, ['type']),
                type_code: pickString(row, ['code_type']),
                surface: pickNumber(row, ['surface']),
                surface_ha: pickNumber(row, ['surf_ha']),
                decree: pickString(row, ['decret']),
              })),
            });
          } catch (error) {
            return errorResult(error instanceof Error ? error.message : 'Failed to list park perimeters');
          }
        }
      );
    
      server.tool(
        'reunion_get_petroleum_consumption',
        'Annual local consumption of petroleum products in La Réunion, in cubic meters (m³), broken down by product: gasoline (essence), diesel (gazole), heating oil (fioul), LPG (gaz de pétrole liquéfié), jet fuel (carburéacteur). Useful for energy-transition monitoring, GHG emission estimates, transport-policy analysis. Sorted by year descending. Source: SDES (Service des données et études statistiques) via data.regionreunion.com.',
        {
          year: z.number().int().optional().describe('Year filter (4 digits, e.g. 2022)'),
          limit: z.number().int().min(1).max(50).default(20).describe('Max yearly rows to return (1-50, default 20)'),
        },
        async ({ year, limit }) => {
          try {
            const data = await client.getRecords<RecordObject>(DATASET_PETROLEUM, {
              where: buildWhere([year !== undefined ? `annee = ${year}` : undefined]),
              order_by: 'annee DESC',
              limit,
            });
            return jsonResult({
              total_rows: data.total_count,
              consumption: data.results.map((row) => ({
                year: pickNumber(row, ['annee']),
                department: pickString(row, ['departement_libelle']),
                gasoline_m3: pickNumber(row, ['essence_m3']),
                diesel_m3: pickNumber(row, ['gazole_m3']),
                heating_oil_m3: pickNumber(row, ['fioul_m3']),
                lpg_m3: pickNumber(row, ['gpl_m3']),
                jet_fuel_m3: pickNumber(row, ['carbureacteur_m3']),
              })),
            });
          } catch (error) {
            return errorResult(error instanceof Error ? error.message : 'Failed to fetch petroleum consumption');
          }
        }
      );
    
      server.tool(
        'reunion_list_water_management_points',
        'List points of activity / interest related to water management in La Réunion: water intakes (captages), treatment plants (stations d\'épuration / potabilisation), reservoirs, pumping stations, etc. Returns ID, origin/source, nature, toponym, importance level. Useful for water-resource analysis, infrastructure mapping, environmental studies.',
        {
          nature: z.string().optional().describe('Nature prefix match. Examples: "Captage", "Station de traitement", "Forage", "Réservoir", "Pompage"'),
          origine: z.string().optional().describe('Origin / source prefix match (organization that produced the data)'),
          limit: z.number().int().min(1).max(200).default(50).describe('Max points to return (1-200, default 50)'),
        },
        async ({ nature, origine, limit }) => {
          try {
            const data = await client.getRecords<RecordObject>(DATASET_WATER_POIS, {
              where: buildWhere([
                nature ? `nature LIKE ${quote(`${nature}%`)}` : undefined,
                origine ? `origine LIKE ${quote(`${origine}%`)}` : undefined,
              ]),
              limit,
            });
            return jsonResult({
              total_points: data.total_count,
              points: data.results.map((row) => ({
                id: pickString(row, ['id']),
                origin: pickString(row, ['origine']),
                nature: pickString(row, ['nature']),
                toponym: pickString(row, ['toponyme']),
                importance: pickString(row, ['importance']),
              })),
            });
          } catch (error) {
            return errorResult(error instanceof Error ? error.message : 'Failed to list water points');
          }
        }
      );
    }
  • Constant DATASET_WATER_POIS = 'les-points-d-activite-ou-d-interet-la-gestion-des-eaux' which identifies the API dataset used by this tool.
    const DATASET_WATER_POIS = 'les-points-d-activite-ou-d-interet-la-gestion-des-eaux';
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It does not mention behavioral traits such as read-only, destructive hint, rate limits, authentication requirements, or response format. The description only lists the tool's purpose and parameters.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences: the first lists the types of water management points, and the second states what is returned and typical use cases. No unnecessary information; concise and front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema and no annotations, the description adequately covers the tool's capabilities. It mentions returned fields and use cases. However, it could mention the limit parameter or pagination behavior, though the schema covers it. Overall, it is complete enough for a simple list tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds value beyond the input schema by providing concrete examples for the 'nature' parameter (e.g., Captage, Station de traitement) and explaining the 'origine' parameter (organization that produced the data). However, the schema already describes all parameters completely.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that the tool lists points of activity related to water management in La Réunion, specifying the types (water intakes, treatment plants, reservoirs, pumping stations) and returned fields (ID, origin, nature, toponym, importance level). It is specific and distinct from sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides context for usage (water-resource analysis, infrastructure mapping, environmental studies), but does not explicitly state when to use this tool versus alternatives or when not to use it. Siblings are diverse, so it's clear enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Hug0x0/mcp-reunion'

If you have feedback or need assistance with the MCP directory API, please join our Discord server